中文av日韩专区,国产高清免费在线播放,少妇无码精油按摩专区,久久无码视频库-h国产在线观看,欧美一区二区三区久久精品茉莉花,国产三级大片,国

首頁

Android5.0以后,materialDesign風(fēng)格的加陰影和裁剪效果

seo達(dá)人

如果您想訂閱本博客內(nèi)容,每天自動發(fā)到您的郵箱中, 請點這里

5.0以后,materialDesign風(fēng)格,出現(xiàn)了立體這種概念,高光,陰影,也就是Z軸,凸顯層次;同時,裁剪view也變得方便簡單了很多。
1,先說說陰影的實現(xiàn)。
方案1:在xml中設(shè)置 
xml中設(shè)置有兩個方式,android:elevation="2dp" 
android:translationZ="2dp"這兩句代碼是可以同時并存的,而且是疊加的效果;當(dāng)然只使用其中一個屬性進(jìn)行z軸的陰影設(shè)置也是OK的。

方案2:在代碼中設(shè)置 
(下面說這個實現(xiàn)方式,其實就是輪廓的實現(xiàn))

設(shè)置陰影,有一個需要注意的地方:
①:view的大小要比它的父布局小,才會有陰影效果,如果相同大小,是看不到陰影效果的; 
②:給圖片設(shè)置陰影的時候,如果這種圖片的background屬性是shape,那直接通過xml設(shè)置陰影是OK的,但是,如果是一張png或者其他格式的圖片,直接通過xml設(shè)置android:elevation="2dp" 
android:translationZ="2dp"陰影是看不到效果的,得通過其他代碼設(shè)置才行。。。**

2,view的輪廓,輪廓其實也是陰影
默認(rèn)情況下,所有的view都是矩形的,雖然可以給view設(shè)置背景圓形的圖片,即可以在界面顯示出圓形的內(nèi)容,但是view的大小實際上依然是矩形,并且設(shè)置的圖片實際上也是矩形的,只是圓形以外的區(qū)域是透明色。 
如果根據(jù)view大小來生成對應(yīng)的陰影,就會出現(xiàn)很奇怪的效果,(一個看起來圓形的view展示出的確實一個矩形的陰影)我了解決這個問題,view增加了一個新的描述來指明內(nèi)容顯示的形狀,這就是 輪廓

輪廓的實現(xiàn)
①通過shape設(shè)置的背景,view會自動根據(jù)shape的形狀進(jìn)行輪廓判定,
②通過color設(shè)置的背景,view默認(rèn)其輪廓和view的大小一樣。
③但是通過圖片進(jìn)行背景設(shè)置,view則無法獲知輪廓的形狀,這個時候就需要手動進(jìn)行指定了。
1
2
3
一:在xml中可以通過android:outlineProvider來指定輪廓的判定方式: 
1,none即使設(shè)置了Z屬性,也不會顯示陰影 
2,background會按照背景來設(shè)置陰影形狀 
3,bounds會按照view的大小來描繪陰影

**對于①和②這種情況,也是可以通過設(shè)置`android:outlineProvider`
來改變陰影的形狀以及輪廓外觀的。**

對于③這種背景是一張png或者其他格式的圖片的情況,
`android:outlineProvider=“background”`
是沒有效果的,屬性設(shè)置成`android:outlineProvider=bounds`
雖然也是有效果的,但是陰影輪廓是一個方形的輪廓,
并不是我們想要的效果了。

不設(shè)置`android:outlineProvider`屬性就更沒有效果了。
1
2
3
4
5
6
7
8
9
10
對于這種使用了png圖片作為背景的view加陰影輪廓的時候情況解決辦法也非常簡單,解決辦法就是:
就通過Java代碼設(shè)置,也就是說,一個圓形的png圖(我們知道,看起來是圓形的,
但是它其實還是方形的圖片,只是圓形之外的區(qū)域是透明不可見的),
 通過Java代碼設(shè)置輪廓,就會顯示出圓形的陰影輪廓了。
1
2
3
具體實現(xiàn),繼續(xù)看: 
二:在代碼中,課通過setOutlineProvider來指定一個view的輪廓。 
對于③這種情況在代碼中設(shè)置輪廓才會有效果。

TextView textView= findViewById(R.id.tv);
ViewOutlineProvider viewOutlineProvider=new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
         //x,y軸表示位置,后兩個參數(shù)表示長,寬 
               outline.setOval(0,0,textView.getWidth(),textView.getHeight());
            }
        };
textView.setOutlineProvider(viewOutlineProvider);
1
2
3
4
5
6
7
8
9
強調(diào):
如果采用圓形圖片作為背景,即使在xml布局中指定android:outlineProvider=“background”,也不會顯示陰影,設(shè)置為android:outlineProvider=bounds,雖然也有效果,但是效果很差,所以一般都是通過代碼來指定輪廓顯示。

1,一個shape圓形作為背景,設(shè)置陰影,設(shè)置android:outlineProvider的4種屬性的效果:


2,一個圓形png作為背景,設(shè)置陰影,設(shè)置android:outlineProvider的4種屬性的效果:


3,一個png作為背景,設(shè)置陰影,通過代碼設(shè)置的效果:


3,view的裁剪
裁剪,默認(rèn)的ImageView是矩形的,很多時候,需要的是圓角的ImageView或者圓形的ImageView,這就需要裁剪view了。

實現(xiàn),裁剪圓形:

final TextView textView= findViewById(R.id.tv);

ViewOutlineProvider viewOutlineProvider=new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                //設(shè)置圓形oval
                outline.setOval(0,0,textView.getWidth(),textView.getHeight());
            }
        };
//設(shè)置裁剪
textView.setClipToOutline(true);
1
2
3
4
5
6
7
8
9
10
11
實現(xiàn),裁剪圓角矩形:

final TextView textView= findViewById(R.id.tv);

ViewOutlineProvider viewOutlineProvider=new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                //設(shè)置圓角矩形
               outline.setRoundRect(0,0,view.getWidth(),view.getHeight(),25);
            }
        };
textView.setOutlineProvider(viewOutlineProvider);
//設(shè)置裁剪
藍(lán)藍(lán)設(shè)計www.sanmachine.cn )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗 、交互設(shè)計、 網(wǎng)站建設(shè) 、平面設(shè)計服務(wù)。

TabLayout 全面總結(jié)

seo達(dá)人

如果您想訂閱本博客內(nèi)容,每天自動發(fā)到您的郵箱中, 請點這里

一、簡介

TabLayout提供了一個水平布局用于展示tabs,繼承自HorizontalScrollView。一般與Viewpager結(jié)合使用實現(xiàn)頁面和標(biāo)簽聯(lián)動的效果,是時下APP中非常常用的一個控件



二、基本用法

  1. 添加design依賴

    compile 'com.android.support:design:25.3.1'

    1
  2. xml引用
  3. xml中添加tab

    <android.support.design.widget.TabLayout

        android:id="@+id/tab_layout"

        android:layout_width="match_parent"

        android:layout_height="wrap_content">

        <android.support.design.widget.TabItem

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Tab1"/>

        <android.support.design.widget.TabItem

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Tab2"/>

        <android.support.design.widget.TabItem

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Tab3"/>

        <android.support.design.widget.TabItem

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Tab4"/>

    </android.support.design.widget.TabLayout>

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21
  4. 代碼中添加tab

    <android.support.design.widget.TabLayout

        android:id="@+id/tab_layout"

        android:layout_width="match_parent"

        android:layout_height="wrap_content">

    </android.support.design.widget.TabLayout>

    1

    2

    3

    4

    5

    // tablayout,Tab是TabLayout的內(nèi)部類,且Tab的構(gòu)造方法是包訪問權(quán)限

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);

    tabLayout.addTab(tabLayout.newTab().setText("Tab1"));

    tabLayout.addTab(tabLayout.newTab().setText("Tab2"));

    tabLayout.addTab(tabLayout.newTab().setText("Tab3"));

    tabLayout.addTab(tabLayout.newTab().setText("Tab4"));

    1

    2

    3

    4

    5

    6





    三、屬性詳解

    <declare-styleable name="TabLayout">

        <!--指示器顏色-->

        <attr name="tabIndicatorColor" format="color"/>

        <!--指示器高度-->

        <attr name="tabIndicatorHeight" format="dimension"/>

        <!--tabs距TabLayout開始位置的偏移量,但app:tabMode="scrollable"才生效-->

        <attr name="tabContentStart" format="dimension"/>

        <!--僅是Tab背景,設(shè)置TabLayout背景用android:background-->

        <attr name="tabBackground" format="reference"/>

        <!--默認(rèn)fixed,所有Tab只能在屏幕內(nèi)顯示,超出會被擠壓;scrollable,tab數(shù)量多會超出屏幕,可滑動-->

        <attr name="tabMode">

            <enum name="scrollable" value="0"/>

            <enum name="fixed" value="1"/>

        </attr>

        <!--默認(rèn)fill,tab填滿TabLayout,但tabMode=“fixed”才生效;center,tabs位于TabLayout的中間-->

        <attr name="tabGravity">

            <enum name="fill" value="0"/>

            <enum name="center" value="1"/>

        </attr>

        <!--Tab的最小寬度-->

        <attr name="tabMinWidth" format="dimension"/>

        <!--Tab的最大寬度-->

        <attr name="tabMaxWidth" format="dimension"/>

        <!--Tab文本設(shè)置樣式-->

        <attr name="tabTextAppearance" format="reference"/>

        <!--Tab未選中字體顏色-->

        <attr name="tabTextColor" format="color"/>

        <!--Tab選中字體顏色-->

        <attr name="tabSelectedTextColor" format="color"/>

        <!--Tab內(nèi)填充相關(guān)-->

        <attr name="tabPaddingStart" format="dimension"/>

        <attr name="tabPaddingTop" format="dimension"/>

        <attr name="tabPaddingEnd" format="dimension"/>

        <attr name="tabPaddingBottom" format="dimension"/>

        <attr name="tabPadding" format="dimension"/>

    </declare-styleable>

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    使用示例



     <android.support.design.widget.TabLayout

        android:id="@+id/tab_layout"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        app:tabIndicatorColor="@color/colorPrimaryDark"

        app:tabIndicatorHeight="2dp"

        app:tabContentStart="50dp"

        app:tabBackground="@color/colorAccent"

        app:tabMode="scrollable"

        app:tabGravity="fill"

        app:tabTextAppearance="@style/MyTabTextAppearance"

        app:tabTextColor="@android:color/black"

        app:tabSelectedTextColor="@android:color/white"/>

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    <style name="MyTabTextAppearance" parent="TextAppearance.Design.Tab">

        <item name="textAllCaps">false</item>

        <item name="android:textSize">18sp</item>

    </style>

    1

    2

    3

    4





    四、圖文混排,Tab中添加圖片
  5. 通過SpannableString設(shè)置圖片

    @NonNull

    private SpannableString setImageSpan(String string,int drawableId) {

        SpannableString ss = new SpannableString("  "+string);

        Drawable drawable = ContextCompat.getDrawable(this, drawableId);

        drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());

        ImageSpan imageSpan = new ImageSpan(drawable);

        ss.setSpan(imageSpan,0,1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

        return ss;

    }

    1

    2

    3

    4

    5

    6

    7

    8

    9

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);

    tabLayout.addTab(tabLayout.newTab().setText(setImageSpan("Tab1",R.drawable.ic_home)));

    tabLayout.addTab(tabLayout.newTab().setText(setImageSpan("Tab2",R.drawable.ic_info)));

    ……

    1

    2

    3

    4





    我們會發(fā)現(xiàn)個問題,通過ImageSpan設(shè)置的圖片和文字沒有對齊,先百度到一個可用方法解決:重寫ImageSpan的draw()方法



    package com.strivestay.tablayoutdemo;



    import android.graphics.Bitmap;

    import android.graphics.Canvas;

    import android.graphics.Paint;

    import android.graphics.drawable.Drawable;

    import android.support.annotation.NonNull;

    import android.text.style.ImageSpan;



    public class CenterImageSpan extends ImageSpan {

        public CenterImageSpan(Drawable drawable) {

            super(drawable);



        }



        public CenterImageSpan(Bitmap b) {

            super(b);

        }



        @Override

        public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom,

                         @NonNull Paint paint) {



            Drawable b = getDrawable();

            Paint.FontMetricsInt fm = paint.getFontMetricsInt();

            int transY = (y + fm.descent + y + fm.ascent) / 2 - b.getBounds().bottom / 2;//計算y方向的位移

            canvas.save();

            canvas.translate(x, transY);//繪制圖片位移一段距離

            b.draw(canvas);

            canvas.restore();

        }

    }

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    將上面的ImageSpan替換為現(xiàn)在的CenterImageSpan,即可實現(xiàn)圖文混排時對齊






  6. 通過Tab.setCustomView()設(shè)置圖片
  7. 自定義view布局

    <?xml version="1.0" encoding="utf-8"?>

    <LinearLayout

        xmlns:android="http://schemas.android.com/apk/res/android"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:orientation="vertical"

        android:gravity="center">

        <ImageView

            android:id="@+id/iv"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:src="@drawable/ic_home"/>

        <TextView

            android:id="@+id/tv"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_margin="2dp"

            android:textSize="16sp"

            android:text="首頁"/>

    </LinearLayout>

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20
  8. 代碼設(shè)置

     TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);

    tabLayout.addTab(tabLayout.newTab().setCustomView(setCustomView(R.drawable.ic_home,"首頁")));

    tabLayout.addTab(tabLayout.newTab().setCustomView(setCustomView(R.drawable.ic_info,"資訊")));

    tabLayout.addTab(tabLayout.newTab().setCustomView(setCustomView(R.drawable.ic_live,"直播")));

    tabLayout.addTab(tabLayout.newTab().setCustomView(setCustomView(R.drawable.ic_me,"我")));

    1

    2

    3

    4

    5

     private View setCustomView(int drawableId,String tabText) {

        View view = View.inflate(this, R.layout.item_tab, null);

        ImageView iv = (ImageView) view.findViewById(R.id.iv);

        TextView tv = (TextView) view.findViewById(R.id.tv);

        iv.setImageResource(drawableId);

        tv.setText(tabText);

        return view;

    }

    1

    2

    3

    4

    5

    6

    7

    8





    五、TabLayout與Viewpager聯(lián)動
  9. xml設(shè)置TabLayout和Viewpager

    第一種:TabLayout放置在Viewpager的上方,放在AppbarLayout中會有陰影效果



    <?xml version="1.0" encoding="utf-8"?>

    <android.support.design.widget.CoordinatorLayout

        xmlns:android="http://schemas.android.com/apk/res/android"

        xmlns:app="http://schemas.android.com/apk/res-auto"

        xmlns:tools="http://schemas.android.com/tools"

        android:id="@+id/main_content"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:fitsSystemWindows="true"

        tools:context="com.strivestay.tablayoutdemo.MainActivity">



        <android.support.design.widget.AppBarLayout

            android:id="@+id/appbar"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:paddingTop="@dimen/appbar_padding_top"

            android:theme="@style/AppTheme.AppBarOverlay">



            <android.support.v7.widget.Toolbar

                android:id="@+id/toolbar"

                android:layout_width="match_parent"

                android:layout_height="?attr/actionBarSize"

                android:background="?attr/colorPrimary"

                app:layout_scrollFlags="scroll|enterAlways"

                app:popupTheme="@style/AppTheme.PopupOverlay">



            </android.support.v7.widget.Toolbar>



            <android.support.design.widget.TabLayout

                android:id="@+id/tab_layout"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                app:tabIndicatorColor="@color/colorAccent"

                app:tabIndicatorHeight="2dp"

                app:tabBackground="@android:color/white"

                app:tabTextAppearance="@style/MyTabTextAppearance"

                app:tabTextColor="@android:color/black"

                app:tabSelectedTextColor="@android:color/holo_blue_light">

            </android.support.design.widget.TabLayout>



        </android.support.design.widget.AppBarLayout>



        <android.support.v4.view.ViewPager

            android:id="@+id/container"

            android:layout_width="match_parent"

            android:layout_height="match_parent"

            app:layout_behavior="@string/appbar_scrolling_view_behavior"/>



        <android.support.design.widget.FloatingActionButton

            android:id="@+id/fab"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_gravity="end|bottom"

            android:layout_margin="@dimen/fab_margin"

            app:srcCompat="@android:drawable/ic_dialog_email"/>



    </android.support.design.widget.CoordinatorLayout>

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58





    第二種:TabLayout直接放在Viewpager,無陰影



    <android.support.v4.view.ViewPager

        android:id="@+id/container"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <android.support.design.widget.TabLayout

            android:id="@+id/tab_layout"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            app:tabIndicatorColor="@color/colorAccent"

            app:tabIndicatorHeight="2dp"

            app:tabBackground="@android:color/white"

            app:tabTextAppearance="@style/MyTabTextAppearance"

            app:tabTextColor="@android:color/black"

            app:tabSelectedTextColor="@android:color/holo_blue_light">

        </android.support.design.widget.TabLayout>

    </android.support.v4.view.ViewPager>

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17




  10. 為Viewpager創(chuàng)建適配器

    /

      fragment

     
    /

    public static class PlaceholderFragment extends Fragment {

        private static final String ARG_SECTION = "section";



        public PlaceholderFragment() {

        }



        public static PlaceholderFragment newInstance(String section) {

            PlaceholderFragment fragment = new PlaceholderFragment();

            Bundle args = new Bundle();

            args.putString(ARG_SECTION, section);

            fragment.setArguments(args);

            return fragment;

        }



        @Override

        public View onCreateView(LayoutInflater inflater, ViewGroup container,

                                 Bundle savedInstanceState) {

            View rootView = inflater.inflate(R.layout.fragment_main, container, false);

            TextView textView = (TextView) rootView.findViewById(R.id.section_label);

            textView.setText(getArguments().getString(ARG_SECTION));

            return rootView;

        }

    }



    /


      pagerAdapter

     
    /

    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        String[] tabs = {"首頁","資訊","直播","我"};



        public SectionsPagerAdapter(FragmentManager fm) {

            super(fm);

        }



        @Override

        public Fragment getItem(int position) {

            return PlaceholderFragment.newInstance(tabs[position]);

        }



        @Override

        public int getCount() {

            return tabs.length;

        }



        @Override

        public CharSequence getPageTitle(int position) {

            return tabs[position];

        }

    }

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    主要是重寫getPageTitle()方法


  11. 代碼設(shè)置 TabLayout和Viewpager綁定

     // tablayout

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);



    // vp

    mViewPager = (ViewPager) findViewById(R.id.container);

    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

    mViewPager.setAdapter(mSectionsPagerAdapter);



    // 綁定,要在viewpager設(shè)置完數(shù)據(jù)后,調(diào)用此方法,否則不顯示 tabs文本

    tabLayout.setupWithViewPager(mViewPager);

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    調(diào)用setupWithViewPager()方法,則使用TabLayout.addtab()方法無效,TabLayout會清除之前添加的所有tabs,并將根據(jù)Viewpager的頁數(shù)添加Tab,Tab標(biāo)題為對應(yīng)頁通過getPageTitle()返回的文本






  12. 圖文混排
  13. 同上,使用SpannableString

    修改Adapter如下:



    /*

     
    pagerAdapter

     */

    public class SectionsPagerAdapter extends FragmentPagerAdapter {



        String[] tabs = {"首頁","資訊","直播","我"};

        int[] imgs = {R.drawable.ic_home,R.drawable.ic_info,R.drawable.ic_live,R.drawable.ic_me};



        public SectionsPagerAdapter(FragmentManager fm) {

            super(fm);

        }



        @Override

        public Fragment getItem(int position) {

            return PlaceholderFragment.newInstance(tabs[position]);

        }



        @Override

        public int getCount() {

            return tabs.length;

        }



        @Override

        public CharSequence getPageTitle(int position) {

    //            return tabs[position];

            return setImageSpan(tabs[position],imgs[position]);

        }

    }

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    setImageSpan()方法同上






  14. 同上,使用Tab.setCustomView()

    修改pagerAdapter如下:



    /

      pagerAdapter

     
    /

    public class SectionsPagerAdapter extends FragmentPagerAdapter {



        String[] tabs = {"首頁","資訊","直播","我"};

        int[] imgs = {R.drawable.ic_home,R.drawable.ic_info,R.drawable.ic_live,R.drawable.ic_me};



        public SectionsPagerAdapter(FragmentManager fm) {

            super(fm);

        }



        @Override

        public Fragment getItem(int position) {

            return PlaceholderFragment.newInstance(tabs[position]);

        }



        @Override

        public int getCount() {

            return tabs.length;

        }



        @Override

        public CharSequence getPageTitle(int position) {

    //            return tabs[position];

    //            return setImageSpan(tabs[position],imgs[position]);

            return null;

        }



        /


          設(shè)置自定義view

         
    @param position

          @return

         
    /

        public View setCustomView(int position) {

            View view = View.inflate(getApplicationContext(), R.layout.item_tab, null);

            ImageView iv = (ImageView) view.findViewById(R.id.iv);

            TextView tv = (TextView) view.findViewById(R.id.tv);

            iv.setImageResource(imgs[position]);

            tv.setText(tabs[position]);

            return view;

        }

    }

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    代碼修改如下:



    …………

    // 綁定,要在viewpager設(shè)置完數(shù)據(jù)后,調(diào)用此方法,否則不顯示 tabs文本

    tabLayout.setupWithViewPager(mViewPager);



    // 為綁定viewpager后的TabLayout的tabs設(shè)置自定義view

    for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {

        tabLayout.getTabAt(i).setCustomView(mSectionsPagerAdapter.setCustomView(i));

    }

    1

    2

    3

    4

    5

    6

    7

    8

    發(fā)現(xiàn)問題:我使用的仍然是上面的item_tab,但是只顯示圖片,不顯示文字如下







    翻了翻源碼,也沒發(fā)現(xiàn)有對Tab的標(biāo)題有特別的設(shè)置;后來,就感覺是不是顏色問題,給item_tab中的textview加上屬性android:textColor="@android:color/black",就顯示出來了







    六、FlycoTabLayout

    這是一個不錯的TabLayout開源項目,效果挺好,可以了解一下。





    藍(lán)藍(lán)設(shè)計www.sanmachine.cn )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗 、交互設(shè)計、 網(wǎng)站建設(shè) 、平面設(shè)計服務(wù)

一口吃下 iPhone設(shè)計規(guī)范

濤濤

如果您想訂閱本博客內(nèi)容,每天自動發(fā)到您的郵箱中, 請點這里

如果您不熟悉iPhone設(shè)計規(guī)范,請一口吃下本篇文章。伴隨筆記吃下效果更佳:)

Image title

 

iPhone的歷史


每次蘋果發(fā)布會UI設(shè)計師可能是最睡不著覺的人啦。每次發(fā)布會蘋果推出全新iPhone時,我們在iPhone平臺上的APP應(yīng)用程序必須跟隨iPhone的尺寸、規(guī)范等特性調(diào)整設(shè)計稿。也就是說,幾乎每次蘋果發(fā)布會都是UI設(shè)計師加班的通知書!這不,2018年9月13日凌晨,蘋果在Apple Park總部里的喬布斯劇院舉行了2018蘋果秋季新品發(fā)布會。這次蘋果發(fā)布了全新的iPhone Xs、iPhone Xs Max,iPhone Xr三款手機。噢,不要忘記我們也不能怠慢還在服役的iPhone X、iPhone Plus、iPhone6/7/8、iPhone SE等蘋果手機。作為一個移動端UI設(shè)計師,您必須對蘋果所有生產(chǎn)過和現(xiàn)役的iPhone有所了解。

 

起源

談到iPhone我們必須談?wù)勈返俜颉滩妓梗⊿teve Jobs)。盡管喬布斯去世多年,但是他的理念仍然是現(xiàn)代智能手機設(shè)計的原則。喬布斯不僅重新定義了智能手機,也定義了移動端應(yīng)用程序。這位被領(lǐng)養(yǎng)的猶太男孩在很早就對個人電腦產(chǎn)生了興趣。在游歷了印度和日本之后,他進(jìn)入了大學(xué)校園。在校園里除了無線電和嬉皮士文化,他認(rèn)為大學(xué)課程多半是無聊的。但他曾跑去特意選修了一門課程:字體設(shè)計。他所在大學(xué)的字體設(shè)計課是全美最著名的,在那個課堂上喬布斯學(xué)習(xí)到了網(wǎng)格設(shè)計、襯線體與無襯線體、字體的氣質(zhì)等設(shè)計知識。當(dāng)然在前面講過的具有搖滾精神的字體Helvetica也深深吸引了喬布斯。后來喬布斯選擇大學(xué)肄業(yè)并在自家車庫創(chuàng)立了蘋果公司,自此“車庫”也成了創(chuàng)業(yè)者最喜愛的地標(biāo)。蘋果公司的第一代個人電腦內(nèi)置了非常出色的用戶圖形界面系統(tǒng)(即GUI),并且內(nèi)置了Helvetica等漂亮的字體。但是這并不是喬布斯事業(yè)的終點,在經(jīng)歷了蘋果公司的權(quán)利斗爭后,成熟的喬布斯再次登上發(fā)布會的舞臺,推出了真正能改變世界的產(chǎn)品 - iPhone。一般產(chǎn)品名都會用名字加上產(chǎn)品的類型命名,比如百事可樂、英雄鋼筆等。而iPhone似乎本身就是一個類別。在那次發(fā)布會上,喬布斯指責(zé)當(dāng)時的功能手機太“愚蠢”:當(dāng)時的功能手機性能很差,并且屏幕很小,實體鍵盤占用了很大的空間。之后,他拿出了一部像外星科技的產(chǎn)品:iPhone。自此,蘋果重新發(fā)明了手機。喬布斯如此強調(diào)用戶界面和交互設(shè)計的重要性,這種理念改變了當(dāng)時和現(xiàn)在的設(shè)計思維。喬布斯身后,移動端的格局在改變,接任喬布斯指揮棒的蒂姆·庫克和首席設(shè)計官喬納森·伊夫(Sir Jonathan Paul Ive)也陸續(xù)更新著蘋果手機的產(chǎn)品線,延續(xù)著這些偉大的產(chǎn)品。

 

 Image title

年輕的喬布斯

 

初代iPhone

相關(guān)產(chǎn)品:iPhone(一代)、iPhone3G(二代)、iPhone3GS(三代)。

iPhone初代產(chǎn)品在2007年1月9日由史蒂夫·喬布斯在蘋果發(fā)布會上正式發(fā)布。初代的iPhone產(chǎn)品的共同特點是:玻璃屏、屏幕清晰度普通、3.5英寸屏(注意:我們所說的手機尺寸都是測量屏幕的對角線得出的)。iPhone沒有實體鍵而整體是屏幕的設(shè)計,在當(dāng)時仿佛是外星科技降臨一般令人驚艷。為了讓大眾習(xí)慣直接在手機上點圖標(biāo)(在此之前人機互動都是間接輸入的:比如實體鍵盤、鼠標(biāo)、觸控筆等),喬布斯發(fā)布了革命性的操作系統(tǒng)iOS,手機的所有圖標(biāo)都是圓角:這樣可以避免用戶認(rèn)為會刺到手指。所有圖標(biāo)和界面全部是擬物設(shè)計,這樣可以更好地讓用戶理解哪些是可以點擊操作的。按鈕在手機上呈現(xiàn)的大小都是7mm左右,這是因為人類手指點擊區(qū)域大概是7mm - 9mm。系統(tǒng)充分地應(yīng)用了多點觸控的功能,你不僅僅可以點手機里的按鈕,還可以進(jìn)行長按、滑動、捏等手勢操作。這些用戶體驗和人性化的設(shè)計在當(dāng)時具有劃時代的意義。隨后,第二代產(chǎn)品iPhone 3G、第三代產(chǎn)品iPhone3GS先后由喬布斯發(fā)布。這種能聽歌、能打電話、能上網(wǎng)的手機真是太炸了!而且你可以在應(yīng)用商店Appstore中下載第三方的應(yīng)用程序,海量的第三方程序可謂是大千世界了。這塊3.5英寸屏的手機截圖出來后的實際分辨率是480x320px,所以如果你在當(dāng)時做UI設(shè)計的話,那么做APP界面建圖的尺寸就應(yīng)該是480x320px。

 

Image title

 蘋果初代產(chǎn)品 (2007)

 

iPhone 4

相關(guān)產(chǎn)品:iPhone 4(四代)、iPhone 4s(五代)。

iPhone 4于2010年6月8日發(fā)布。iPhone 4延續(xù)了iPhone一代的多點觸摸(Multi-touch)屏界面,并首次加入視網(wǎng)膜屏幕、前置攝像頭、陀螺儀、后置閃光燈,相機像素提高至500萬。對我們設(shè)計師最重要的就是加上了視網(wǎng)膜屏Retina。Retina是蘋果提出的標(biāo)準(zhǔn),它的含義就是在應(yīng)用場景的視距內(nèi)讓人無法看清單個像素。我們都知道如果你貼的夠近,一般的屏幕上都會出現(xiàn)一格一格的像素矩陣。屏幕是由這些矩陣組成的。這種屏幕的問題就是稍微近一些我們就能看到那些網(wǎng)格和矩陣。如果我們希望用戶得到最好的體驗,自然是讓用戶看不到格子,那怎么辦?答案就是:加大屏幕的密度。如果屏幕的密度到達(dá)一個指定的水平(當(dāng)然也要取決于用戶的視距,即用戶與屏幕通常離多遠(yuǎn)),那么用戶的眼睛就無法分辨出細(xì)小的像素顆粒了。這種屏幕就被稱為Retina屏,也叫視網(wǎng)膜屏。這是用戶體驗的巨大進(jìn)步,但是也是UI設(shè)計師的噩夢。原先的設(shè)計稿統(tǒng)統(tǒng)需要放大才可以在iPhone4里顯示得完美:比如原來我們一個界面的尺寸是480x320px,現(xiàn)在因為屏幕密度增加了一倍,我們就需要設(shè)計640x960px才夠用。在電腦上看這個尺寸要比手機大兩倍!(當(dāng)然啦,那時的電腦屏幕通常不是Retina屏)。而且3GS并沒有完全被淘汰,那么如何讓一個APP適配兩個不同尺寸的手機呢?于是每個APP內(nèi)預(yù)裝了兩套切圖,一套480x320px尺寸,也就是一倍圖(@1x);一套960x640px尺寸,也就是二倍圖(@2x)。這兩套圖像資源的命名完全一樣,只是二倍圖結(jié)尾需要加上@2x標(biāo)記它是高清尺寸,比如home_icon@2x.png。

Image title

 

 iPhone 4代產(chǎn)品 (2010)

 

邏輯像素和物理像素

邏輯像素(logic point):邏輯像素的單位是PT,它是按照內(nèi)容的尺寸計算的單位。比如iPhone 4的邏輯像素是480x320pt。但是由于每個邏輯的點因為視網(wǎng)膜屏密度增加了一倍,即1pt=2px,那么其實iPhone 4的物理像素是960x640px。iOS開發(fā)工程師和使用Sketch和AdobeXD軟件設(shè)計界面的設(shè)計師使用的單位都是PT。

 

物理像素的單位就是我們常說的pixel,簡寫成PX。它是我們在Photoshop和切圖中使用的單位,屏幕設(shè)計中最小的單位就是1px不可再分割。使用Photoshop設(shè)計移動端界面和網(wǎng)站的設(shè)計師使用的單位是PX。在以下的文章中,如果您使用Photoshop設(shè)計界面,那么只需要記住所有px單位的數(shù)值和支持Photoshop的工具,如果使用Sketch或Adobe XD設(shè)計界面,那么只需要記住所有pt單位的數(shù)值和對應(yīng)的工具即可。

 

 Image title

邏輯像素和實際像素計算方式不同

 

PPI

PPI(pixels per inch)指的是屏幕分辨率的單位,表示的是每英寸顯示的像素密度。屏幕的PPI值越高,那么這個屏幕每英寸能容納的像素顆粒也就越多,那這個產(chǎn)品的畫面的細(xì)節(jié)度也就越豐富。PPI值大于300一般我們就無法用肉眼察覺出屏幕上的“馬賽克”格子了。但是如果屏幕很大,那么需要呈現(xiàn)視網(wǎng)膜屏的PPI值也需要更大,所以iPhone Plus系列的PPI值比iPhone6/7/8要大。PPI在我們設(shè)計的工作中其實關(guān)系不大,但理解它對于幫助我們理解為什么iPhone4比iPhone3GS實際像素大一倍有幫助。

 Image title

PPI的計算公式

 

iPhone 5

相關(guān)產(chǎn)品:iPhone 5(六代)、iPhone 5s和iPhone 5c(七代)

iPhone 5于2012年9月13日正式發(fā)布。iPhone5在設(shè)計上帶來了很多爭議,因為iPhone5沒有采用喬布斯認(rèn)為人類最合適的手機尺寸3.5英寸屏,而是用了4英寸的屏幕。寬度沒變而高度加長了。這樣做的原因是市場上越大的手機越受歡迎。當(dāng)時設(shè)計師也幾近崩潰,因為又要搞適配了。原來960x640px的尺寸變?yōu)榱?136x640px,但是這個變化其實不大,就是高了點兒。于是@2x高清圖的設(shè)計稿就變成了640x1136px。因為iPhone4的手機看著也就是長了點兒,滑動不就完了嘛。除了閃屏這樣的界面需要單獨做iPhone4、iPhone5、3GS尺寸之外,其他界面仍然維持兩套設(shè)計稿即可。

 

Image title

iPhone 5 (2012)

 

iPhone 6/7/8 和iPhone Plus

相關(guān)產(chǎn)品:iPhone6和iPhone6 Plus(八代)、iPhone 6s和iPhone 6s Plus(九代)、iPhone7和iPhone7 Plus(十代)、iPhone8和iPhone8 Plus(十一代)。

這個產(chǎn)品迭代周期值得大家留意,從iPhone6到iPhone8這段時間蘋果新手機的物理像素都是750x1334px。而所有Plus手機的物理像素都是1242x2208px。如果按照邏輯像素來計算,那么iPhone6/7/8的邏輯像素就是375 x 667 pt(就是750x1334除以2);而iPhone Plus的邏輯像素就是414 x 736 pt(就是1242x2208除以3,因為這個屏幕太大了視距不同所以屏幕密度更高)。歷史到這個時候,原來的手機全部被淘汰了。也就是說iPhone6/7/8成為了我們的設(shè)計標(biāo)準(zhǔn),它的切圖就是@2x,iPhone Plus(1242x2208)使用@3x。從此沒有@1x倍圖了,只存在一個假想的概念。

 Image title

iPhone 6/7/8  (自2014)

 

Image title

 

iPhone Plus (自2014)

 

 

iPhone X

相關(guān)產(chǎn)品:iPhone X(十一代)。

這四款手機全部是蘋果的全面屏手機。全面屏并不是新概念了,因為從iPhone初代產(chǎn)品開始,手機業(yè)內(nèi)就在構(gòu)思如何把手機做成全部都是屏幕區(qū)域的技術(shù)了。但是這個技術(shù)有很多難題,比如前置攝像頭和聽筒怎么處理。那么蘋果采用的方案是“齊劉?!?,把四周處理成圓角的方式。IPhone X和后續(xù)三款全面屏我們設(shè)計師需要注意的就是齊劉海。因為需要規(guī)避攝像頭和麥克風(fēng)聽筒,所以導(dǎo)航欄比其他iPhone系列產(chǎn)品要高;而底部Tab欄因為最下方有圓角同樣比其他iPhone系列要高。而且這兩個邊界是不應(yīng)該放置任何操作功能的。也就是說只有看的份兒。

iPhone X的物理像素是1125 x 2436 px,而邏輯像素是375 x 812 pt。也就是說如果你使用Sketch或者Adobe XD等工具設(shè)計界面的話,iPhone X的寬度和iPhone 6/7/8是相同的;只是高了一些。那么如果需要出一套iPhone X效果圖只需要把頭和尾巴替換成新版即可。而如果你用Photoshop設(shè)計界面的話,寬度變化還是比較大的。需要做放大處理然后單獨調(diào)整那些亂了的尺寸。

 Image title

iPhone X(2017)

 

iPhone XS Max

相關(guān)產(chǎn)品:iPhone XS、iPhone XS Max、iPhone XR(十二代)。

這三款產(chǎn)品的像素分辨率聽上去會比較眼暈:

iPhone XS Max:1242 x 2688 px

iPhone XS:1125 x 2436 px

iPhone XR:828 x 1792 px

但是如果我們用點的單位看就會得到:

iPhone XS Max:414 x 896 pt (iPhone Plus分辨率寬度)

iPhone XS:375x812 pt (iPhone 6/7/8分辨率寬度)

iPhone XR:414 x 896 pt (iPhone Plus分辨率寬度)

 

所以其實今年發(fā)布的iPhone都是比較友好的,如果使用矢量界面工具那么只需要調(diào)整設(shè)計稿頭和尾巴即可,如果使用Photoshop的設(shè)計師需要放大縮小設(shè)計稿然后調(diào)整頭和尾巴可以得到新版設(shè)計稿。而切圖其實和之前沒有變化,不管用什么工具設(shè)計還是得出兩套切圖:@2x(750x1334px)、@3x(1242x2208px)即可。

 Image title

iPhone XS Max (2018)

 

 

以iPhone6/7/8為基準(zhǔn)設(shè)計

在開始比賽之前,由于iPhone 6、iPhone 6S、iPhone7、iPhone7S、iPhone8屏幕和分辨率都是一致的750X1334px,所以我們可以稱它們?yōu)閕Phone6/7/8。而iPhone 6 Plus、iPhone7 Plus、iPhone8 Plus、屏幕和分辨率都是一致的1242x2208,所以我們可以稱它們?yōu)閕Phone Plus。而iPhone XS、iPhone X屏幕和分辨率都是一致的1125x2436,所以我們可以稱它們?yōu)閕PhoneX。那這場比賽的贏家毫無疑問是價格美麗的iPhone6/7/8獲勝啦。那么我們做界面設(shè)計時需要按照iPhone6/7/8為基準(zhǔn)設(shè)計。如果使用Photoshop就建750x1334px尺寸的畫布,如果是使用Sketch或Adobe XD等工具就建立375x667pt。當(dāng)然如果要設(shè)計首頁之類的界面,它的界面很長你可以設(shè)計一個長的設(shè)計稿,比如750x8000px。

 Image title

手機型號與像素對應(yīng)圖

 

Image title

 

HIG設(shè)計指南


上文說我們建立界面可以根據(jù)750x1334px或375x667pt來建立畫布,但是具體狀態(tài)欄的高度、導(dǎo)航欄的高度、tab欄的高度是多少?那些UIKit組件里的東西去哪里找呢?蘋果已經(jīng)為我們準(zhǔn)備好了多個格式的規(guī)范了:

資源下載地址:https://developer.apple.com/design/resources/

 

設(shè)計方式

在iPhone6/7/8存量仍然很大的情況下,我們做設(shè)計稿仍然需要以iPhone6/7/8為尺寸來建圖。從蘋果官網(wǎng)下載好UIKit,上面有我們需要的一切元素。這些元素有PSD、Sketch以及XD版本,不管用什么設(shè)計軟件均可找到對應(yīng)版本。打開之后你會發(fā)現(xiàn)蘋果已經(jīng)將我們所需要的規(guī)范元素準(zhǔn)備好了。如果你需要一些彈窗或者控件,那么就在UI Elements里找。如果需要界面的尺寸模板,就在Design Templates找。所有文件都有兩份,結(jié)尾帶有-iPhoneX的是為iPhone X系列設(shè)計的模板。沒有標(biāo)識的是為iPhone6/7/8設(shè)計的模板。

 Image title

UI Elements 文件夾中的源文件

 

Image title Design Templates中的源文件

 

狀態(tài)欄和導(dǎo)航欄

狀態(tài)欄(Status Bars)就是iPhone最上方用來顯示時間、運營商信息、電池電量的那個很窄的區(qū)域。導(dǎo)航欄(Navigation Bars)就是狀態(tài)欄之下的區(qū)域,一般來說導(dǎo)航欄中間是頁面標(biāo)題,左右是放置功能圖標(biāo)的區(qū)域。

在iPhone6/7/8設(shè)計中,狀態(tài)欄的高度為20pt(40px)。導(dǎo)航欄的高度是44pt(88px)。這兩個區(qū)域在iOS7代之后就進(jìn)行了一體化設(shè)計。所以它們加起來的高度是64pt(128px)。

在iPhoneX設(shè)計中,狀態(tài)欄的高度為40pt(132px)。導(dǎo)航欄的高度也是44pt(132px)。這兩個區(qū)域同樣要進(jìn)行一體化設(shè)計。所以它們加起來的高度是84pt(264px)。這里注意一下,因為iPhone X的PPI值為458,所以并不是如iPhone6/7/8一樣1pt=2px換算。

 

 Image title

iPhone6/7/8和iPhone X導(dǎo)航區(qū)域的差別

 

Image title

 部分優(yōu)秀APP的導(dǎo)航區(qū)域設(shè)計

 

大標(biāo)題導(dǎo)航欄

在的蘋果設(shè)計中導(dǎo)航出現(xiàn)了一種新形式:大標(biāo)題。出現(xiàn)這種形式就是為了減少視覺噪音,讓內(nèi)容更加突出。很明顯大標(biāo)題的設(shè)計很像報紙的版式設(shè)計,在第一眼我們就會明白頁面的主題。大標(biāo)題導(dǎo)航欄的高度一般為116pt(232px):這包括了20pt(40px)狀態(tài)欄的高度,同時也能放得下34pt(68px)的大標(biāo)題和輔助信息(如返回等圖標(biāo))。但是注意一下,大標(biāo)題并不應(yīng)該像傳統(tǒng)導(dǎo)航一樣常駐在頁面之上,因為它太占空間了。所以在滑動頁面時大標(biāo)題會變成正常導(dǎo)航欄的64pt(128px)的高度。當(dāng)然如果設(shè)計稿為iPhone X那么數(shù)值需要另外換算。

 

 Image title

大標(biāo)題的尺寸

導(dǎo)航欄圖標(biāo)

圖標(biāo)作為文字的補充,在移動端中應(yīng)用非常廣泛。在導(dǎo)航欄區(qū)域上的功能諸如搜索、添加、更多、返回等均需要用圖標(biāo)來表達(dá)。說明:@2x和@3x在邏輯像素單位是一樣的,如果您使用如Sketch、Adobe XD等矢量工具設(shè)計,可以參照邏輯像素數(shù)值設(shè)計即可。但是如果您用Photoshop工具以iPhone6/7/8尺寸進(jìn)行設(shè)計,就需按照@2x下的px單位數(shù)值設(shè)計。

 Image title

導(dǎo)航欄圖標(biāo)尺寸規(guī)范

 

標(biāo)簽欄 (Tab Bars)

Tab就是點擊的意思,Tab欄(也叫標(biāo)簽欄)指的是APP底部的區(qū)域,如微信底部常駐有聊天、通訊錄、發(fā)現(xiàn)、我的四個圖標(biāo)。iOS規(guī)范中Tab欄一般有五個、四個、三個圖標(biāo)的形式。也就是把寬度平分為五、四、三份。iPhone6/7/8設(shè)計中,標(biāo)簽欄的高度為49pt(98px)。Tab欄的操作是最常用的,因為手指最方便點擊而且這個欄是常駐在頁面之上的。所以Tab欄的圖標(biāo)至關(guān)重要,因為很多用戶可能因為看不懂圖標(biāo)而找不到重要功能的入口,通常我們會在Tab欄圖標(biāo)之下加上11pt(22px)的注釋文字,這個注釋文字一般來說都是非常淺的淺灰色。

 

Image title

標(biāo)簽欄的尺寸

標(biāo)簽欄圖標(biāo)

我們在標(biāo)簽欄上的圖標(biāo)一般來說30pt(60px)大小左右,蘋果給出了四種不同形狀標(biāo)簽欄圖標(biāo)的尺寸參考供大家設(shè)計時考慮。其意義是讓不同外形的圖標(biāo)看上去是差不多大的,保證圖標(biāo)的平衡。標(biāo)簽欄圖標(biāo)的選中態(tài)應(yīng)該是一個彩色,來區(qū)別于非選中狀態(tài)。

 Image title

真實設(shè)計中的標(biāo)簽欄

 

Image title

 

標(biāo)簽欄圖標(biāo)設(shè)計規(guī)范

Image title

 

標(biāo)簽欄圖標(biāo)應(yīng)該盡量使用清晰地填充風(fēng)格

 

 

工具欄 (ToolBars)

我們在蘋果自帶瀏覽器底部就能看到工具欄。工具欄提供了和當(dāng)前任務(wù)相關(guān)的操作和按鈕,在滑動時可以收起。工具欄同Tab欄一樣都是位于底部,但是高度略窄,它的高度是44pt(88px)。

 

閃屏資源

由于閃屏是一張完整的靜態(tài)滿屏圖片,而不是諸如其他頁面一樣是由切圖和文本拼成的,所以閃屏的適配更簡單粗暴:我們需要提供不同尺寸的閃屏效果。閃屏資源就是滿尺寸的一張png,上端不需要狀態(tài)欄里的信息,程序會在開發(fā)完畢時自動在閃屏中補上狀態(tài)欄里的信息。我們需要提供的閃屏尺寸有:

 Image title

我們需要提供的閃屏尺寸 一共6張

 

安全距離

作為iPhone全面屏系列手機,齊劉海無疑是一個特征。但是全面屏給我們帶來了使用上的問題:上下左右是圓角、頂部齊劉海使屏幕凹下一塊。所以在帶有圓角和齊劉海的紅色標(biāo)注區(qū)域不應(yīng)該放置任何功能,僅可在上端放置狀態(tài)欄,底部圓角區(qū)域留白。我們界面豎屏使用時左右臨近手機邊緣的區(qū)域不建議放任何操作,應(yīng)留出一定的邊距(Margin)。這個邊距是多少呢?沒有明確嚴(yán)格的規(guī)定,但是一般的APP會留出16pt-24pt不等的邊距防止用戶在屏幕邊緣不好點擊。不過內(nèi)容展現(xiàn)卻可以呈現(xiàn)在邊距里。如果我們橫屏使用手機時,左右同樣不好點對吧?橫屏同時還有令人鬧心的“齊劉海”,所以同樣左右需留出一定的邊距來。所以我們就得到一個安全距離的矩形,內(nèi)容可以完整地呈現(xiàn)在這個安全距離內(nèi)。

 

 Image title

iPhone X系列由于全面屏上下出現(xiàn)不可操作區(qū)域

 

色彩

其實在iPhone上顯示的色域要比我們作圖時的RGB色域要廣。所以在iPhone上設(shè)計怎樣的顏色都可以。只要符合產(chǎn)品氣質(zhì)并且在色彩心理學(xué)理論上思考,用什么顏色是設(shè)計師的自由。官方建議的系統(tǒng)色彩如下:

 Image title

iPhone的系統(tǒng)色

 

字體

iOS中英文使用的是San Francisco (SF)字體。(下載地址:https://developer.apple.com/fonts

),中文使用的是蘋方黑體。安裝好以后你會發(fā)現(xiàn)中文蘋方的字族有不少可供選擇的粗細(xì),那么我們設(shè)計界面時需要根據(jù)信息的邏輯權(quán)重分配粗細(xì):標(biāo)題應(yīng)該較粗,而說明字體應(yīng)該較細(xì)并且可以設(shè)計成灰色。其實字體的設(shè)計最重要的考量就是信息層級。蘋果認(rèn)為APP的字體信息層級有:大標(biāo)題(Large Title)、標(biāo)題一(Title 1)、標(biāo)題二(Title 2)、標(biāo)題三(Title 3)、頭條(Headline)、正文(Body)、標(biāo)注(Callout)、副標(biāo)題(Subhead)、注解(Footnote)、注釋一(Caption 1)、注釋二(Caption 2)這幾種。

 Image title

HIG對APP的字體建議(基于@2x)

 

注意一下,以上HIG的建議全部是針對英文SF字體而言的,中文字體需要我們靈活運用,以最終呈現(xiàn)效果為基準(zhǔn)調(diào)整。在設(shè)計具體界面時我們一定要以用戶的使用情景來考慮,把設(shè)計稿導(dǎo)入手機去思考行高與字體大小是否是可讀的。10pt(20px)是手機上顯示的最小字體,最大的應(yīng)該是目前的大標(biāo)題字體了,達(dá)到了34pt(68px)。

 

啟動圖標(biāo)

在設(shè)計模板還沒有如今這么發(fā)達(dá)時,設(shè)計師需要設(shè)計啟動圖標(biāo)(1024x1024px)之后按照程序員的要求切出幾十個不同尺寸的圖標(biāo)。比如,在手機中@3x情況下桌面圖標(biāo)尺寸為180x180px,在@2x情況下為120x120px;在應(yīng)用商店圖標(biāo)需要使用的尺寸是1024x1024px;這個工作太煩人了,好在現(xiàn)在我們只需要專注在啟動圖標(biāo)設(shè)計本身上了。在蘋果給我們的這套資源中,有Template-AppIcons-iOS這個文件。打開這個文件,用我們自己設(shè)計的啟動圖標(biāo)替換掉智能對象里的內(nèi)容,你會發(fā)現(xiàn)所有尺寸的圖標(biāo)都變成了我們的圖標(biāo)。然后我們把背景隱藏,切出這些圖標(biāo)即可。圖標(biāo)設(shè)計建議使用AI等矢量軟件,然后使用規(guī)范切出圖像資源。

 

 Image title

Template-AppIcons-iOS

 

控件

控件包括:輸入框、按鈕、滑桿、頁卡、開關(guān)等,在設(shè)計模板中已經(jīng)全部列出。這里格外說明一下,為了讓設(shè)計更符合整體產(chǎn)品品牌調(diào)性,這些控件都可以做成自定義的設(shè)計樣式。但是會增加工作量和切圖資源,所以一般我們在諸如設(shè)置界面這些無需太體現(xiàn)設(shè)計感的頁面中都使用系統(tǒng)默認(rèn)控件,而在一些品牌感需要強調(diào)的頁面或產(chǎn)品(諸如白噪音產(chǎn)品、游戲等)則會使用自定義的樣式。如果我們想自己設(shè)計控件,那么注意兩件事:第一,點擊區(qū)域基本符合44pt(88px)原則,也就是在手機上大小大概是7mm-9mm,適合手指點擊。第二,要設(shè)計操作的不同狀態(tài),不要只設(shè)計一種狀態(tài)。

 Image title

默認(rèn)控件

 

Image title

 

自定控件和默認(rèn)控件

 

控件中無處不在的44pt(88px)

之前我們介紹過,人手指點擊區(qū)域為7mm - 9mm,在@2x中就是44pt(88px)。蘋果的導(dǎo)航條、列表、工具欄都充滿了44pt(88px)這個神秘數(shù)字。我們在設(shè)計時一定也要考慮到手指的點擊區(qū)域。

 Image title

無處不見的44pt(88px)

 

鍵盤

在設(shè)計模板中您也可以找到鍵盤的設(shè)計。這里需要提醒的是,很多朋友做界面設(shè)計時不考慮輸入時鍵盤會遮擋到的空間,如果考慮到鍵盤彈起遮擋住的內(nèi)容,那么我們的一些界面中的輸入框和信息可能都需要上移了。當(dāng)然也不是說可能被鍵盤遮擋的地方不可以防止任何內(nèi)容,也有一種方式就是當(dāng)輸入一個表單時,頁面會垂直定位到當(dāng)前輸入的位置。

 Image title

鍵盤高度

 

iTunes 上傳截圖

在程序上傳APPSTORE時我們需要提供多張APP截圖,供用戶了解APP的功能。很多設(shè)計師朋友不太清楚這個尺寸,這里我們需要提供1242 x 2688px和1125 x 2436px兩套截圖。有時我們也會在這個尺寸上做一些設(shè)計,讓用戶在APPSTORE打開APP介紹時獲得最好的體驗。

 Image title

ITunes上傳用截圖

 Image title


工作流程


前期調(diào)研階段

在我們設(shè)計界面之前,我們必須做用戶研究來了解產(chǎn)品的調(diào)性,比如用戶研究手段中的用戶畫像、用戶調(diào)研、用戶使用場景分析、設(shè)計競品分析等方法。不管工作再忙也建議大家做這些工作,他們對我們深入了解產(chǎn)品大有裨益。

 

原型圖階段

APP產(chǎn)品設(shè)計首先需要構(gòu)建出原型圖,之后再開始視覺設(shè)計。這個工作有些公司是由產(chǎn)品經(jīng)理負(fù)責(zé)的,也有交互設(shè)計師負(fù)責(zé)的,還有的公司因為人手較少,也會出現(xiàn)由UI設(shè)計師來負(fù)責(zé)的情況。就算有產(chǎn)品經(jīng)理或其他職能人員來完成原型圖,那設(shè)計師也需要和產(chǎn)品經(jīng)理等人員溝通需求和探討原型圖,并不是產(chǎn)品經(jīng)理向設(shè)計師下發(fā)需求。設(shè)計師要站在視覺和交互的角度提出自己建設(shè)性的意見,而不是簡單等原型圖完成后照著上色而已。關(guān)于原型圖的工具,我們不僅僅可以用Axure RP設(shè)計原型圖,也可以使用像墨刀、Adobe XD等新工具來完成原型圖。

 

 Image title

構(gòu)建APP原型圖(工具:Adobe XD )

 

視覺稿階段

視覺稿階段要根據(jù)原型圖確定的內(nèi)容和大體版式完成APP的界面設(shè)計。但是這里請大家注意一下:目前業(yè)界主要是以Sketch、Adobe XD、Photoshop這三個軟件來完成APP的界面設(shè)計的。Sketch和Adobe XD都是以邏輯像素的單位(PT)來設(shè)計,然后導(dǎo)出圖像的時候再進(jìn)行放大兩倍三倍來切圖。這樣做的好處是不用在設(shè)計的時候小心翼翼地使用偶數(shù)了。而Photoshop由于主要是處理圖像而非矢量圖形的軟件,所以在設(shè)計移動端界面時如果做成一倍的話切圖會變得很虛,所以要基于2倍圖來進(jìn)行界面設(shè)計。比如如果我們以iPhone6/7/8的界面來進(jìn)行設(shè)計,那么在Sketch和Adobe XD中我們建立的畫布就是375x667pt在Photoshop中則是750x1334px。

 

Image title 

視覺稿設(shè)計階段(工具:Adobe XD)

 

Image title

 

視覺稿設(shè)計階段(工具:Adobe Photoshop)

 

 

iPhone6/7/8尺寸

在iPhone6/7/8尺寸下,狀態(tài)欄高度20pt(40px)、導(dǎo)航欄44pt(88px)、Tab欄49pt(98px)、導(dǎo)航標(biāo)題字號建議17pt(34px)、導(dǎo)航欄圖標(biāo)建議22pt(44px)、Tab欄圖標(biāo)建議30pt(60px)、Tab欄圖標(biāo)注釋文字11pt(22px)、左右安全距離建議12pt(24px)。字號從10pt(20px)到34pt(68px)均可,要視具體情況決定。

 

 Image title

在iPhone6/7/8尺寸下的設(shè)計尺寸

 

實時預(yù)覽你的設(shè)計稿

我們在Sketch、Adobe XD、Photoshop等軟件中設(shè)計界面時有一個問題:電腦上的效果總和手機上呈現(xiàn)的效果不同。這是由于尺寸和觀察方式?jīng)Q定的,所以最好的方式是我們實時地查看設(shè)計稿在手機上的呈現(xiàn)效果。以下APP通過數(shù)據(jù)線或wifi鏈接電腦后,即可及時在手機中看到還沒有保存的設(shè)計稿呈現(xiàn)在手機中的樣子。

 

 Image title

Design Mirror:可實時預(yù)覽Photoshop、XD等設(shè)計稿

 

Image title

 

Adobe XD:可實時預(yù)覽你的XD畫板

 

Image title

 Sketch Mirror:可實時預(yù)覽你的Sketch畫板

 

iPhoneX設(shè)計效果圖

雖然程序員對于iPhoneX等全面屏手機的適配只需要設(shè)計師提供切圖即可,但很多設(shè)計師比較青睞iPhone X和XR和XSM等的設(shè)計效果,也比較愿意把設(shè)計稿改成iPhoneX的設(shè)計圖放到作品集或者在匯報時展示。那么我們應(yīng)該怎么做呢?如果設(shè)計稿需要調(diào)整為iPhone X的顯示效果,可以下載iOS 12設(shè)計源文件,把界面頭和尾替換成iPhoneX專用頭尾——專用頭尾在劉海和圓角處做了留白。Sketch和XD都是用一倍圖設(shè)計所以不涉及修改尺寸,改頭尾即可。而PS比較復(fù)雜一點:需要先等比例變大整個設(shè)計稿,再把寬度改為1125寬度自適應(yīng)即可。PS變大會虛還得一個一個調(diào)一下,然后再改頭尾。

 

Image title

替換導(dǎo)航區(qū)域和Tab欄區(qū)域,即可得到iPhoneX設(shè)計效果

 

視覺規(guī)范

如果我們設(shè)計完了五六個主要界面,那么現(xiàn)在做什么呢?APP設(shè)計一套視覺規(guī)范是非常有必要的,有了視覺規(guī)范我們就可以把控整體的設(shè)計和語言。一般來說,一套APP應(yīng)該有3-5種主題色和輔助色;5-10種不同變化的字體樣式。這些如果沒有落實到一套規(guī)范中,那么很容易跑偏。一套移動端應(yīng)用的視覺規(guī)范應(yīng)該包括:

 

主色/輔色/色彩規(guī)范: 規(guī)定APP所能使用的色彩種類;

文字顏色/大小規(guī)范: 規(guī)定APP主要使用文字的大小、顏色、應(yīng)用場景等;

ICON規(guī)范: 規(guī)定APP的icon設(shè)計規(guī)范;

應(yīng)用圖標(biāo)規(guī)范: 規(guī)定APP的應(yīng)用圖標(biāo)使用規(guī)范;

按鈕和交互態(tài)規(guī)范: 規(guī)定APP內(nèi)所有按鈕和交互態(tài)的樣式;

間距規(guī)范: 規(guī)定APP內(nèi)所有間距的尺寸。

 

 

Image title

設(shè)計規(guī)范的重要性

 

 

Image title

設(shè)計規(guī)范中的色彩規(guī)范

 

設(shè)計規(guī)范的類型可以是png或者多個頁面組成的pdf文件。其他設(shè)計師打開我們制定的設(shè)計規(guī)范,可以清晰地找到當(dāng)前項目適合使用的元素和字體大小、間距等。這樣盡管是多人協(xié)同工作也可以保證項目設(shè)計風(fēng)格的一致性。

 

切圖

有了大小各異的iPhone尺寸,如果程序只有一套切圖,那么一定會造成有的手機顯示很差。所以我們要在程序里放置多套切圖,然后讓程序判斷“主人”的手機是什么型號,顯示不同的切圖。這樣才能夠完美地呈現(xiàn)給用戶最好的體驗。切圖的方法有很多種。Sketch和Adobe XD可以直接導(dǎo)出。Phtoshop不具備這個功能,但是我們可以使用cutterman、藍(lán)湖等插件導(dǎo)出切圖。不管是自帶功能還是插件,導(dǎo)出切圖都可以導(dǎo)出@2x和@3x圖,而設(shè)計稿只需要iPhone6/7/8一套即可。

 

 

Image title

某項目中的切圖文件

 

Adobe XD切圖功能

在Adobe XD中將需要切出的元素在圖層面板(Ctrl + Y)點擊添加批量導(dǎo)出標(biāo)記記錄;然后點擊 菜單 > 導(dǎo)出 > 所選畫板 > 用于iOS > 導(dǎo)出所有畫板 即可。

 

Image title

Adobe XD自帶切圖功能

 

使用Cutterman協(xié)助Photoshop切圖

在Cutterman官網(wǎng)下載PS插件后,點擊窗口 > 擴展功能 > Cutterman 調(diào)出面板;然后選擇iOS 并高亮選中@3X和@2X;在圖層面板里選中需要切圖的元素,點擊“導(dǎo)出選中圖層”即可。

 

 

Image title

Photoshop中的Cutterman 插件

 

使用藍(lán)湖切圖

在藍(lán)湖平臺可以下載Sketch、Adobe XD或Photoshop對應(yīng)的插件。然后在不同設(shè)計軟件插件中將設(shè)計稿上傳到藍(lán)湖(PS需要用插件標(biāo)記需要切出的元素),然后在藍(lán)湖網(wǎng)頁版點擊切圖按鈕,選擇視網(wǎng)膜@2x和高清視網(wǎng)膜@3x,再點擊“下載該頁全部切圖”即可。

 

 

Image title

在藍(lán)湖平臺導(dǎo)出切圖

 

切圖命名規(guī)范

切圖最后需要命名成規(guī)范的格式,這樣方便程序員查找。切圖命名的格式建議全英文,如果大家英文不好需要想辦法提升一點簡單的詞匯量。借由上述工具切圖后,需要整理切圖命名,或在切圖之前對圖層命名亦可。以下是切圖元素的中英文對照:

 Image title

切圖命名對照表

 

然后我們要按照 功能_類型_名稱_狀態(tài)@倍數(shù) 來命名每個切圖,比如我們導(dǎo)航條上有一個搜索圖標(biāo),那么它的名稱就是:

 

navi_icon_search_default@2x.png

(導(dǎo)航_圖標(biāo)_搜索_正常@2x.png)

 

iOS開發(fā)語言

作為iOS開發(fā)工程師,最重要的三個工具是:Obiective-C、Swift、UIKit框架。Obiective-C是目前最有效率的語言;而Swift開發(fā)非常。一般iOS工程師會在這兩個語言中選擇一種作為開發(fā)工具。UIKit是蘋果系統(tǒng)自帶的一套框架,這個框架里有設(shè)置按鈕、滑竿、狀態(tài)欄、電池電量、鍵盤等接口可供調(diào)用。所以我們看到很多第三方APP的界面中,有許多控件和蘋果自帶程序是一致的,這就是UIKit的功勞。

 

 

Image title

開發(fā)視角 By @alvaroreyes

 

了解開發(fā)工程師的語言和工具對我們做設(shè)計也格外有幫助,我們會知道哪些效果能做,哪些效果不能做,哪些效果能做不好做等等。我找了大家關(guān)注的九個問題請教了iOS資深開發(fā)工程師程威:

 

 

Image title

Image title

和iOS工程師溝通

 

溝通完是不是學(xué)到了不少?我們明白了iOS工程師工作的機制后再設(shè)計界面時就可以做到心中有數(shù)了。在平時工作中我們也應(yīng)該多和開發(fā)小哥哥聊聊,學(xué)習(xí)一下他們實現(xiàn)的方式,以便我們的設(shè)計能夠更好地落地。

 

標(biāo)注

切圖后程序員得到了什么?一大堆碎片。把這些碎片重新用OC或者Swift構(gòu)建回我們設(shè)計的界面并沒有想的那么簡單。所以開發(fā)工程師可能會總是在思考構(gòu)架層面的問題,而忽視了視覺還原。并且由于iOS的開發(fā)人員不會使用設(shè)計軟件,所以很容易出現(xiàn)比如14pt或者28px的文字,實現(xiàn)后是16pt或者32px。那就亂了套了不是,那怎么辦呢?我們可以通過一些標(biāo)注軟件把圖標(biāo)之間的位置、字體的高度、字體的大小和色彩進(jìn)行標(biāo)注,讓程序員輕松省力地還原我們的設(shè)計稿。

 

藍(lán)湖平臺自動標(biāo)注功能

將Sketch和Adobe XD、Photoshop的設(shè)計稿上傳至藍(lán)湖后,在藍(lán)湖平臺每個頁面左側(cè)有一個類似分享的圖標(biāo),點擊會獲取一個網(wǎng)址,這個網(wǎng)址就是系統(tǒng)生成的自動標(biāo)注。它會自動識別設(shè)計稿中字體大小和間距等,甚至有代碼參考。

 

Image title

藍(lán)湖自動標(biāo)注工具

 

使用Px像素大廚標(biāo)注

像素大廚同樣提供了自動標(biāo)注、手動標(biāo)注兩種標(biāo)注方法。自動標(biāo)注需要上傳設(shè)計稿,手動標(biāo)注需要設(shè)計師使用“尺子”來測量距離、“吸管”來吸取色號。在界面上部有單位選擇,如果我們給iOS開發(fā)做標(biāo)注,那么單位最好選擇PT,與開發(fā)環(huán)境一致。

 

Image title

像素大廚標(biāo)注工具

 

“標(biāo)你妹啊”進(jìn)行自動標(biāo)注

國產(chǎn)標(biāo)注在線神器。只需要登錄網(wǎng)站后,上傳設(shè)計稿可直接生成標(biāo)注網(wǎng)址,發(fā)給程序員就可以啦。同樣提供代碼參考和自動標(biāo)注間距尺寸等功能。

 

 

Image title

在線標(biāo)注工具 - 標(biāo)你妹啊

 

Markman 手動標(biāo)注

Markman同樣是國產(chǎn)標(biāo)注神器。而且是我使用的第一個標(biāo)注工具,選用底部工具可以進(jìn)行手動標(biāo)注,標(biāo)注后導(dǎo)出png標(biāo)注圖即可。

 

 

Image title

Markman標(biāo)注工具

 

動效

據(jù)資深iOS開發(fā)程威介紹,目前的iOS主流的動效實現(xiàn)方式有以下四種:第一種,設(shè)計師給到開發(fā)動效視頻或gif,開發(fā)人員照著效果編寫代碼調(diào)用靜態(tài)切圖重新做一遍,這樣的還原度可能會有問題,需要開發(fā)和設(shè)計師多溝通。第二種,可以使用序列幀的方式實現(xiàn)動畫,原理是給到開發(fā)按順序命名的png,比如1.png、2.png等,然后用代碼將它們快速替換實現(xiàn)動畫。第三種,我們也可以給到程序員avi等視頻文件直接插入視頻。第四種,使用Airbnb開源的Lottie(https://airbnb.design/lottie/)。具體來說是通過after effects來完成動效,然后通過BodyMovin插件導(dǎo)出json文件,里面記錄的就是動畫的細(xì)節(jié),然后在安卓,iOS,React Native上都有一套對應(yīng)的SDK,來解析這個json文件來還原成動畫。這個方式的還原度很高,除了部分AE不支持外堪稱完美。其實還有QuartzCode、CoreAnimator等工具,有興趣的大家可以去嘗試一下。但我認(rèn)為不管使用什么方式,最優(yōu)秀的動效還是要靠設(shè)計師和開發(fā)人員“真誠地交流”。


項目走查

當(dāng)我們最終完成了界面設(shè)計,需要和我們的設(shè)計稿進(jìn)行對照還原。除了用肉眼辨別之外,我們也可以把還原后的程序截圖下來放到PS中對照,尋找問題。那么我們給程序員的反饋就是一個有截圖對照和標(biāo)注的文檔,這個文檔可以成為Buglist。

 

Image title

截圖后可在軟件中對比尋找問題

 

項目走查除了判斷視覺還原程度,也要兼顧動效、點擊狀態(tài)等動態(tài)效果是否符合設(shè)計預(yù)期。如果有問題需要及時和技術(shù)反饋,反饋的方式建議是文檔類型,保證有據(jù)可查。

 

 Image title


總結(jié)


我們一起來小結(jié)一下:當(dāng)我們設(shè)計iOS平臺的APP時,我們可以選擇使用Sketch、Adobe XD、Photoshop等工具。為了切圖和適配方便,設(shè)計時我們以iPhone6/7/8尺寸(750x1334px或375x667pt)為基準(zhǔn)設(shè)計。設(shè)計過程中我們需要通過諸如Adobe XD或Mirror等工具隨時在手機上預(yù)覽設(shè)計效果。之后我們需要把圖像資源輸出成@2x視網(wǎng)膜屏幕和@3x高清視網(wǎng)膜屏幕兩套圖像資源,這時可以使用Cutterman或Sketch和XD自帶的切圖功能切圖。為了保證開發(fā)工程師能夠完美地還原我們的設(shè)計稿,我們需要提供標(biāo)注。通過藍(lán)湖或像素大廚、Markman、標(biāo)你妹啊等工具我們可以把設(shè)計稿完美標(biāo)注給到程序員,這時程序員就清晰地明白每個元素的大小和間距了。最后,我們要對完成的程序進(jìn)行驗收。本篇文章寫于二零一八年,按照慣例,每年蘋果都會舉辦兩場發(fā)布會發(fā)布新產(chǎn)品。如果后面發(fā)布了新的手機,也希望大家能夠理清脈絡(luò),透過現(xiàn)象看到本質(zhì),找出合適的設(shè)計適配方法。



參考資料

蘋果開發(fā)者中心網(wǎng)址:

https://developer.apple.com/

蘋果人機交互規(guī)范:

https://developer.apple.com/design/human-interface-guidelines/

iOS設(shè)計資源下載:

https://developer.apple.com/design/resources/

藍(lán)藍(lán)設(shè)計www.sanmachine.cn )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計  ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗 、交互設(shè)計、 網(wǎng)站建設(shè) 、平面設(shè)計服務(wù)

jQuery中的Ajax操作

seo達(dá)人

如果您想訂閱本博客內(nèi)容,每天自動發(fā)到您的郵箱中, 請點這里

jQuery對Ajax操作進(jìn)行了封裝,常用的方法包括 $.get(),$.post(),$.ajax()。 
分別對其進(jìn)行介紹

$.get()
$.get()方法使用GET方式來進(jìn)行異步請求。
$.get()結(jié)構(gòu)
$.get(url,[. data][. callback][. type])
1
$.get()方法參數(shù)解釋
參數(shù)名稱 類型 說明
url String 請求的HTML頁的url地址
data(可選) Object 發(fā)送至服務(wù)器的key/value數(shù)據(jù)會作為QueryString附加到請求的url中
callback(可選) Function 載入成功時回調(diào)函數(shù)(只有當(dāng)Response的返回狀態(tài)是success才調(diào)用該方法)自動將請求結(jié)果和狀態(tài)傳遞給該方法
type(可選) String 服務(wù)器端返回內(nèi)容的格式,包括xml、html、script、json、text和_default
示例 
json數(shù)據(jù):data.json(后面的$.post()和$.ajax()方法都用這個數(shù)據(jù))
{
    "name":"龍貓",
    "hobby":"睡覺",
    "friend":"加菲貓"
}

jq_get.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>

</head>
<body>
    <input type="button" value="$.get方法" id="jQget">
    <div id="content"></div>
</body>
</html>
<!-- 導(dǎo)入jquery.js文件 -->
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript">
    $(function(){
        $('#jQget').on('click',function(){

            /*

            參數(shù)1:url
                參數(shù)2:發(fā)送的數(shù)據(jù) 支持 直接寫js對象的方式
                參數(shù)3:回調(diào)函數(shù)
                參數(shù)4:從服務(wù)端獲取的 數(shù)據(jù)類型 可以不寫
                注意
                    如果type 為json 
                        并且服務(wù)端返回的就是 json格式字符串
                        jq內(nèi)部 會幫助我們自動轉(zhuǎn)化
                        在回調(diào)函數(shù)中 獲取的 實參 就是轉(zhuǎn)化完成的 js對象 直接使用即可

                參數(shù)的 順序 是更換的
                    但是 如果 把data 放到后面 會出現(xiàn) 無法傳遞數(shù)據(jù)的問題,
                    所以 不要擅自更換 嚴(yán)格按照 jq文檔中的 順序 進(jìn)行使用
            */
            $.get('jq_get.php',{name:"jack",age:18},function(data){
                    console.log(data);

                    $('#content').html('name:'+data.name+'<br>'+'hobby:'+data.hobby+'<br>'+'friend:'+data.friend); 

            },'json');
        });

    });
</script>

jq_get.php (后面的$.post()和$.ajax()方法都用這個頁面的內(nèi)容,只是在html請求時分別對應(yīng)的php頁面)

<?php
    header('content-type:text/html;charset=utf-8');
    echo file_get_contents('datas/data.json');
?>

結(jié)果展示: 


$.post()方法
  它與$.get()方法的結(jié)構(gòu)和使用方式都相同,不過它們之間仍然有以下區(qū)別:

GET請求會將參數(shù)跟在URL后進(jìn)行傳遞,而POST請求則是作為HTTP消息的實體內(nèi)容發(fā)送個Web服務(wù)器,當(dāng)然,在Ajax中,這種區(qū)別對用戶是不可見的。
GET方式對傳輸?shù)臄?shù)據(jù)有大小限制(通常不能大于2KB),而使用POST方式傳遞的數(shù)據(jù)量要比GET方式大得多(理論上不受限制,但是可以在服務(wù)端進(jìn)行限制)。
GET方式請求的數(shù)據(jù)會被瀏覽器緩存起來,因此其他人就可以從瀏覽器的歷史記錄中讀取這些數(shù)據(jù),例如賬號和密碼等。在某種情況下,GET方式會帶來嚴(yán)重的安全性問題,而POST方式相對來說就可以避免這些問題。(但是也是不安全的,所以密碼之類的還是要加密的)
GET方式和POST方式傳遞的數(shù)據(jù)在服務(wù)器的獲取方式也不相同。在PHP中,GET方式數(shù)據(jù)可以用$_GET[]獲取,而POST可以用$_POST[]獲取、兩種方式都可以用$_REQUEST[]來獲取。 
其實這完全是對這篇文章中post()和get()方法不同的總結(jié)啊!(點擊查看) 
$.post()演示
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript">
    $(function(){
        $('#jQpost').on('click',function(){
            // 跟$.get用法及其類似
            /*
                參數(shù)1:url
                參數(shù)2:發(fā)送的數(shù)據(jù) 支持 直接寫js對象的方式
                參數(shù)3:回調(diào)函數(shù)
                參數(shù)4:從服務(wù)端獲取的 數(shù)據(jù)類型 可以不寫,如果寫為json jq內(nèi)部 會幫我們進(jìn)行一個 JSON.parse()的轉(zhuǎn)化 
            */
             $.post('jq_post.php',{name:"kong",age:18},function(data){
                    console.log(data);
             },'json');
        });
    });
</script>

$.ajax()
$.ajax()方法是jQuery最底層的Ajax實現(xiàn)
其結(jié)構(gòu)為
$.ajax(options)
1
該方法只有1個參數(shù),但在這個對象里包含了$.ajax()方法所需要的請求設(shè)置以及回調(diào)函數(shù)等信息,參數(shù)以key/value的形式存在,所有參數(shù)都是可選的,只寫幾個常用的參數(shù),如下:

參數(shù)名稱 類型 說明
url String 請求的HTML頁的url地址
type String 請求方式,默認(rèn)GET。注意其他的HTTP請求方法,例如PUT和DELETE也可以使用,但僅部分瀏覽器支持
data Object或String 發(fā)送到服務(wù)器的數(shù)據(jù),如果已經(jīng)不是字符串,將自動轉(zhuǎn)換為字符串格式。
dataType String 服務(wù)器端返回內(nèi)容的格式,包括xml、html、script、json、jsonp 、jQuery
beforeSend Function 發(fā)送請求前可以修改XMLHttpRequest對象的函數(shù),例如添加自定義HTTP頭。在beforeSend中如果返回false可以取消本次Ajax請求。XMLHttpRequest對象的唯一參數(shù)。
success Function 請求成功后嗲用的回調(diào)函數(shù),有兩個參數(shù)。
(1)由服務(wù)器返回,并根據(jù)dataType參數(shù)進(jìn)行處理后的數(shù)據(jù)。
(2)描述狀態(tài)的字符串。
function(data,textStatus){
        //data可能是xmlDoc、jsonObj、html、text等等。
        this//調(diào)用本次Ajax請求時傳遞的options參數(shù)
  }
error Function 請求失敗時被調(diào)用的函數(shù),該函數(shù)有3個參數(shù),即
XMLHttpRequest對象、錯誤信息、捕獲的錯誤對象(可選)。
Ajax事件函數(shù)如下。
function(XMLHttpRequest,textStatus,errorThrown){//通常情況下textStatus和errorThown只有其中一個包含信息
this;//調(diào)用本次Ajax請求時傳遞的options參數(shù)
}
示例
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript">
    $(function(){
        $('#jqAjax').on('click',function(){
    /*
                常見參數(shù):
                    url:請求的地址
                    success:請求成功的回調(diào)函數(shù)
                    type:不寫是get 可以指定 get,post
                    dataType:數(shù)據(jù)的類型
                    data:發(fā)數(shù)據(jù) 可以寫js對象
                    beforeSend:發(fā)送之前調(diào)用的匿名函數(shù)
                        可以return false 阻止該次請求
                        驗證用戶的數(shù)據(jù) 是否填了
                    error:請求失敗以后 會調(diào)用
            */
            $.ajax({
                url:'jq_ajax.php',
                success:function(data){
                    console.log(data);
                    $('#box').append(data.name+'<br>'+data.hobby);
                },
                type:'post',
                dataType:'json',
                data:{"name":"張信哲","skill":"情歌王子"},
                beforeSend:function(){
                    console.log('發(fā)送之前調(diào)用');
                },
                error:function(){
                    console.log('請求失敗了');
                }
            });
        });

    });
</script>
--------------------- 
作者:diligentkong 
來源:CSDN 
原文:https://blog.csdn.net/diligentkong/article/details/72851443 
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!
藍(lán)藍(lán)設(shè)計www.sanmachine.cn )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗 、交互設(shè)計、 網(wǎng)站建設(shè) 、平面設(shè)計服務(wù)。

這4個最常見的 UI 組件,給你總結(jié)了這份使用指南

濤濤

如果您想訂閱本博客內(nèi)容,每天自動發(fā)到您的郵箱中, 請點這里

我們在看 App 時,有沒有思考過這樣的問題,同樣都是提示彈窗為什么出現(xiàn)那么多不同的樣式,亦或者同樣都是讓界面進(jìn)行切換的導(dǎo)航為什么有的可以通過側(cè)滑切換,有的卻只能點擊切換呢?最近在玩 App 時發(fā)現(xiàn)了幾組這樣的控件,下面就來和大家分享下我對他們的理解和選用。

目錄:

  • 警告框與操作表
  • 標(biāo)簽欄與操作欄
  • Tabs與分段控件
  • Toast與Snackbar

一、警告框與操作表

1. 定義

警告框:是一種操作上的確認(rèn),只有當(dāng)用戶點擊按鈕后才算真的完成,才可以有其他操作,主要作用是警告或提示用戶的。

警告框由三部分組成:標(biāo)題、正文、按鈕。有些簡單的警告或提示只有正文和按鈕即可。

操作表/ActionSheet:操作表通常會從屏幕底部邊緣向上滑出一個面板,可提供2個以上的選擇。呈現(xiàn)給用戶的是簡單、清晰、無須解釋的一組操作,沒有正文的描述內(nèi)容(大部分)。另外重要的功能操作也會用紅色文字展示。

2. 如何選用?

文字內(nèi)容的重要性

文字內(nèi)容的重要性:選擇警示框和操作表時,要考慮的是兩個彈窗文字內(nèi)容對于用戶的重要程度,如果內(nèi)容極為重要則選用警示框,如果文字內(nèi)容不重要甚至不需要描述文字我們就應(yīng)該選擇操作表。

案例:如下圖,淘寶登錄密碼錯誤時,由于警示框更重要的是文字內(nèi)容的體現(xiàn),幫助用戶找到問題所在,所以選用警示框。再看 QQ郵箱的垃圾箱中點擊全部清空時,由于信息本身就在垃圾箱內(nèi),不需要對用戶過多的文字提示,用戶直接操作即可,所以最后選用操作表。

用戶操作流暢性

用戶操作流暢性:當(dāng)我們需要讓用戶停止操作并必須點擊當(dāng)前界面的按鈕時,要選擇警示框,警示框?qū)τ脩舨僮魃系牧鲿承杂兄車?yán)重的影響。如果不需要太過強硬,我們就選用只需在屏幕中任意位置點擊就會消失的操作表。

數(shù)量

數(shù)量:這是最容易區(qū)分使用的方面,當(dāng)彈窗中的按鈕數(shù)量超過2個時我們一定選用操作表,因為警示框的按鈕數(shù)量不可以超過兩個。如果數(shù)量一樣,可以根據(jù)上面兩點擇優(yōu)使用。

案例:如下圖,我們在得到App 中點擊開通「推送通知」時,因為操作按鈕只有一個,所以選擇警示框。而點開微博中的更多按鈕,用的則是操作表,因為操作按鈕有三個。

二、標(biāo)簽欄與工具欄

1. 定義

標(biāo)簽欄:標(biāo)簽欄位于屏幕底部,它是懸浮在當(dāng)前頁面之上的,并且會一直存在,只有當(dāng)用戶點擊跳轉(zhuǎn)到二級菜單后才會消失。用戶可以在不同的子任務(wù)、視圖和模式中進(jìn)行切換,并且切換按鈕間都屬于不同的內(nèi)容。

當(dāng)用戶選中某個標(biāo)簽時,該標(biāo)簽呈現(xiàn)適當(dāng)?shù)母吡翣顟B(tài)。數(shù)量也有限制,不能超過5個,如果存在5個以上的標(biāo)簽可以將最后的標(biāo)簽設(shè)計成「更多」標(biāo)簽。

工具欄:工具欄同樣位于屏幕底部,懸浮在當(dāng)前頁面之上的,并且當(dāng)用戶不需要使用的時候,可以隱藏它。例如向上滑動界面時,工具欄會自動隱藏。工具欄的內(nèi)容主要是對當(dāng)前頁面的相關(guān)操作按鈕。

2. 如何選用?

切換狀態(tài)

切換狀態(tài):當(dāng)我們需要同級別界面切換時,應(yīng)該選擇標(biāo)簽欄,同時標(biāo)簽欄的切換通常為一級導(dǎo)航,工具欄的功能僅針對當(dāng)前界面內(nèi)容的相關(guān)操作。

案例:如下圖,微信讀書底部欄中是關(guān)于同級別的視圖切換,所以選擇標(biāo)簽欄,同時標(biāo)簽欄也常用于產(chǎn)品的一級導(dǎo)航。而 Safari瀏覽器底部的內(nèi)容是針對當(dāng)前界面的操作功能,所以使用了工具欄。

位置狀態(tài)

位置狀態(tài):當(dāng)?shù)撞繉?dǎo)航始終在界面最上方時,上下滑動都不會消失,則選擇標(biāo)簽欄;如果底部導(dǎo)航上滑隨之消失則選擇工具欄(說明:也有少數(shù)的工具欄是怎么滑動都不會消失的)。

案例:如下圖,我們來看看百度的 App,當(dāng)我向上滑動界面時,底部導(dǎo)航的位置是不會消失的,所以使用了標(biāo)簽欄。再看 Safari瀏覽器,因為上滑時底部欄會被隱藏,所以選用了工具欄。

選中狀態(tài)

選中狀態(tài):當(dāng)用戶選中底部某一項時,如果需要高亮顯示且顯示的內(nèi)容是不同子任務(wù)的視圖,則使用標(biāo)簽欄;而當(dāng)選擇后,出現(xiàn)操作表等與當(dāng)前界面相關(guān)的操作時,應(yīng)該選擇工具欄。

案例:如下圖,我們還是來看百度App,當(dāng)我點擊底部的選項時,切換的同時,當(dāng)前選中的「好看視頻」需要變成選中的樣式,來告知用戶當(dāng)前選中的是那個界面,所以使用了標(biāo)簽欄。再看 Safari瀏覽器,點擊底部按鈕后出現(xiàn)操作表且當(dāng)前選中的按鈕也不會變高亮,因為不會在當(dāng)前切換界面,所以選擇了工具欄。

三、Tabs與分段控件/Segment Control

1. 定義

Tabs:Tabs 來自 MD規(guī)范,早在 Android 2.0時代,官方的通訊錄App 就使用頂部 Tab導(dǎo)航,可以滑動切換不同視圖。Tabs 里 Tab 呈現(xiàn)的內(nèi)容可以有很大的差別,而且數(shù)量沒有限制,Tabs 不能作為表單的單選組件。

分段控件:iOS 原生控件之一,每個分段作用是互斥的,在分段控件里,所有的分段選項框在長度上要保持一致,同 iOS規(guī)范中對于分段控件的分段選項不得超過5個,每個分段選項可以是純文字或者圖片。

2. 如何運用?

來源不同

來源不同:分段控件來自 iOS規(guī)范,而 Tabs 來源于 MD規(guī)范。

案例:如圖我們來看 iPhone 的日歷界面點擊收件箱,因為是 iOS系統(tǒng)配置的應(yīng)用,所以界面中切換樣式用的是分段控件,而反觀安卓系統(tǒng)則用的是 Tabs切換。

內(nèi)容不同

內(nèi)容不同:分段控件主要起到分割和篩選同類數(shù)據(jù),而 Tabs 則沒有這樣的限制,Tabs 里的每一項所呈現(xiàn)的內(nèi)容可以有很大的差別。另外分段控件更多的是以單選功能出現(xiàn)在表單的使用中,而 Tab 則不能作為表單的單選組件。

案例:如下圖鯊魚記賬中的圖表頁,支持、收入為整個界面展示項目,為了讓用戶查看起來更加方便,把數(shù)據(jù)分割為周、月、年的不同的數(shù)據(jù)展示,因為是同類數(shù)據(jù)切換,所以選擇了分段控件。反觀36氪首頁的 Tabs欄,由于每個內(nèi)容的差別都很大,所以使用了 Tab欄展示。

操作方式不同

操作方式不同:分段控件需要點擊操作,而 Tabs 除了點擊外還可以通過左右滑動切換不同視圖。

案例:如下圖,網(wǎng)易錢包App 界面中的切換控件,因為在表單中且是極為近似的數(shù)據(jù)圖,不易讓用戶側(cè)滑屏幕切換,需要讓用戶更精準(zhǔn)的點擊選擇。所以使用了智能點擊的分段控件,而優(yōu)酷視頻的切換頁變化都比較明顯,很容易區(qū)分,所以選擇了可以側(cè)滑屏幕切換的 Tabs。

數(shù)量

數(shù)量:分段控件數(shù)量不能超過5個,而 Tabs 沒有數(shù)量限制。

案例:如下圖網(wǎng)易云音樂中的消息界面,界面中因為分類的數(shù)量未超過五個(不是所有未超過5個的就要用分段控件,同時也要根據(jù)以上說的其他三種情況判斷,這里只針對數(shù)量闡述而已),所以可以使用分段控件,而網(wǎng)易云音樂視頻界面中因為分類數(shù)量過多且內(nèi)容上有區(qū)別所以選擇了 Tabs。

四、Toast與Snackbar

1. 定義

Toast:Toast 通常出現(xiàn)在頂部和中部,浮于頁面上方,無法對其操作,出現(xiàn)一段時間后便會消失,并且在此期間不影響其他正常操作。

Snackbar:Snackbar 出自于安卓系統(tǒng),是安卓系統(tǒng)的特色彈窗之一。它是由一段信息和一個按鈕組成,他們會在超時或者用戶在屏幕其他地方觸碰后自動消失。Snackbar 可以在屏幕上滑動關(guān)閉。Snackbar 不會妨礙用戶對產(chǎn)品的其他操作。

2. 如何選用?

操作不同

操作不同:Toast 彈窗沒有任何操作鍵,而 Snackbar 是有操作鍵的。

案例:如圖馬蜂窩App 中給作者的文章點贊功能只需要告知用戶,點贊已成功即可,不需要其他操作,所以選用 Toast彈窗。而攜程中當(dāng)進(jìn)入酒店界面時,除了告知用戶下面還有更多信息外,還想引導(dǎo)用戶直接查看,所以選用了帶操作功能的 Snackbar。

退出狀態(tài)不同

退出狀態(tài)不同:Toast彈窗完全是通過超時后自動消失,不存在任何操作,而 Snackbar 可以超時消失也可以用戶主動上滑關(guān)閉。

案例:如下圖豆瓣App 廣播界面中,當(dāng)我點擊換一批后,換好的內(nèi)容會自動刷新到最前面,所以用戶不需要任何操作就可以看到內(nèi)容,就可以選用無操作必須等待超時后才會消失的 Toast彈窗。

而攜程App 中的酒店界面,因為更多精彩的內(nèi)容在下面,并沒有展示出來,為了不讓用戶在滑動瀏覽時造成視覺障礙。所以選擇了 Snackbar,除了超時后自動關(guān)閉外,也可以通過滑動界面讓彈窗主動關(guān)閉。

組成元素不同

組成元素不同:Toast彈窗主要是由文字和背景組成,也可以額外附加圖標(biāo)。而 Snackbar 除文字、背景,圖標(biāo)外還有操作鍵組成。

案例:如下圖得到App 中只需要提示用即可,所以選用 Toast,組成元素選用背景+文字+圖標(biāo),而小紅書App 需要加入操作鍵,所以選擇了 Snackbar。

總結(jié)

通過上面的分析,大家是不是對這八個組件有了更深的理解呢?

每個組件都有不可替代的作用,如果大家還有哪些不清楚的組件對比可以在文章下留言,之后我會選擇一些整理出來再次和大家分享,感謝大家的耐心閱讀。

藍(lán)藍(lán)設(shè)計www.sanmachine.cn )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計  cs界面設(shè)計 、 ipad界面設(shè)計  包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗 、交互設(shè)計、 網(wǎng)站建設(shè) 、平面設(shè)計服務(wù)

高手私藏的 UI 細(xì)節(jié)設(shè)計,這篇全都給你整理好了!

濤濤

如果您想訂閱本博客內(nèi)容,每天自動發(fā)到您的郵箱中, 請點這里

這篇文章滲透進(jìn)頁面中的每一個 Kit控件,深入的分析每一個控件所能帶給用戶的視覺以及心理感受。

藍(lán)藍(lán)設(shè)計www.sanmachine.cn )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計  包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗 、交互設(shè)計、 網(wǎng)站建設(shè) 、平面設(shè)計服務(wù)

譯文 | 掌握這25條小貼士,數(shù)據(jù)可視化秒提升!

鶴鶴

可視化不是單純的數(shù)據(jù)展示,其真正價值是設(shè)計出可以被讀者輕松理解的數(shù)據(jù)展示。設(shè)計過程中的每一個選擇,最終

都應(yīng)落腳于讀者的體驗,而非設(shè)計者個人。

用一個案例,告訴你我是如何把工作效率提高30%的!

濤濤

如果您想訂閱本博客內(nèi)容,每天自動發(fā)到您的郵箱中, 請點這里

最近剛做完一個項目,我發(fā)現(xiàn)我的設(shè)計效率相比之前竟然提升了30%以上。今天用「個人中心頁面從思考到設(shè)計全過程」這個案例給大家分享一下。

藍(lán)藍(lán)設(shè)計www.sanmachine.cn )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計  cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制  用戶體驗 、交互設(shè)計、 網(wǎng)站建設(shè) 、平面設(shè)計服務(wù)。

日歷

鏈接

個人資料

藍(lán)藍(lán)設(shè)計的小編 http://www.sanmachine.cn

存檔