天天看點

【Android】Material Design 之一 TabLayout使用

之前實作如下圖中的導航效果時,都是頂部一個線性布局+ViewPager+Fragment,線性布局中再去部署TextView和View,ViewPager滑動時,線性布局的布局就要跟着變化。直到我遇到了Metrial Design的TabLayout,我才意識到原來實作一個這樣的導航效果還可以這麼友善,下面我就來使用TabLayout實作如圖的導航欄效果。

【Android】Material Design 之一 TabLayout使用

首先,要進行Material Design包的加載,我使用的是Android Studio 3.0版本,在app的build.gradle中添加依賴:

 implementation 'com.android.support:design:28.0.0-alpha1'

【Android】Material Design 之一 TabLayout使用

接着,實作如圖的導航,除了使用TabLayout,仍然需要ViewPager和Fragment的配合。

這裡設定導航分為文章、時尚、商品、新聞、店鋪、旅遊6個部分,對應的需要定義6個Fragment布局和類。

文章 fragment_article.xml如圖:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        android:textColor="#000000"
        android:id="@+id/tv_article"/>

</LinearLayout>      

文章 ArticleFragment.java如圖:

//注意:這裡的Fragment導入的包是v4下的,android.support.v4.app.Fragment
public class ArticleFragment extends Fragment {

    private TextView textView;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment_article,container,false);
        textView=view.findViewById(R.id.tv_article);
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        textView.setText("文章");
    }
}      

其他5個部分類似,此處就不貼代碼了。既然使用了ViewPager+Fragment就必須需要一個擴充卡來為ViewPager填充内容,下面是自定義的FragmentAdapter.java:

public class FragmentAdapter extends FragmentPagerAdapter {

    private List<String> titleList;  //存放導航的标題
    private List<Fragment> list;     //存放ViewPager中要填充的Fragment

    public FragmentAdapter(FragmentManager fm,List<String> titleList,List<Fragment> list) {
        super(fm);
        this.titleList=titleList;
        this.list=list;
    }


    @Override
    public Fragment getItem(int i) {
        return list.get(i);
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Nullable
    @Override
    //重載此方法  設定導航欄中對應的标題
    //如果不重載,導航欄的标題就沒有内容,隻有滑動條
    public CharSequence getPageTitle(int position) {
        return titleList.get(position);
    }
}
      

這裡要注意的是,一定要重載getPageTitle()這個方法,否則導航欄沒有标題,隻有一個導覽列,如下圖:

【Android】Material Design 之一 TabLayout使用

在布局中使用TabLayout,下面是activity_material_design.xml布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MaterialDesignActivity">

    <android.support.design.widget.TabLayout
        android:id="@+id/tablelayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="scrollable"
        app:tabTextColor="#cacaca"
        app:tabSelectedTextColor="#e62424"
        app:tabIndicatorColor="#e62424"
        app:tabBackground="@drawable/tab_bg"
        app:tabTextAppearance="@android:style/TextAppearance.Small">
    </android.support.design.widget.TabLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
    </android.support.v4.view.ViewPager>

</LinearLayout>      

這裡要說明一下TabLayout的幾個屬性:

app:tabBackground    設定TableLayout的背景色

app:tabTextColor     設定未被選中時文字的顔色

app:tabSelectedTextColor    設定選中時文字的顔色

app:tabIndicatorColor    設定滑動條的顔色

app:tabTextAppearance="@android:style/TextAppearance.Large"

設定TableLayout的文本主題,無法通過textSize來設定文字大小,隻能通過主題來設定

app:tabMode="scrollable"

設定TableLayout可滑動,當頁數較多時,一個界面無法呈現所有的導航标簽,此時就必須要用。

這裡app:tabBackground屬性使用的是我自己定義的一個背景tab_bg.xml,布局如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient android:startColor="#616fbe"
        android:endColor="@color/colorPrimary"
        android:type="linear"/>

</shape>      

下面再貼一下MaterialDesignActivity.java的代碼:

public class MaterialDesignActivity extends AppCompatActivity {

    private TabLayout tabLayout;
    private ViewPager viewPager;

    private List<String> titleList;
    private List<Fragment> list;
    private FragmentAdapter fragmentAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_material_design);

        initView();
        initData();
    }


    private void initView() {
        tabLayout=findViewById(R.id.tablelayout);
        viewPager=findViewById(R.id.viewpager);
    }

    private void initData() {
        titleList=new ArrayList<>();
        list=new ArrayList<>();

        titleList.add("文章");
        titleList.add("時尚");
        titleList.add("商品");
        titleList.add("新聞");
        titleList.add("店鋪");
        titleList.add("旅遊");

        list.add(new ArticleFragment());
        list.add(new FashionFragment());
        list.add(new GoodsFragment());
        list.add(new NewsFragment());
        list.add(new ShopFragment());
        list.add(new TourismFragment());

        fragmentAdapter=new FragmentAdapter(getSupportFragmentManager(),titleList,list);
        viewPager.setAdapter(fragmentAdapter);

        //此方法設定導航  作用有3:從ViewPager中擷取TableLayout的title
        //ViewPager滑動時設定TabLaout的Title和indicator(滑動條)
        //點選TabLayout時ViewPager相應變化
        tabLayout.setupWithViewPager(viewPager);

    }
}
      

 下面就可以運作項目,效果就是一開始的圖,這裡TabLayout使用了app:tabMode="scrollable"的屬性,是以運作結果導航欄是可以滑動。好了,TabLayout的簡單使用到這裡就完成了,最後感謝一下https://blog.csdn.net/chenyuan_jhon/article/details/62898808部落格的内容講解。