之前實作如下圖中的導航效果時,都是頂部一個線性布局+ViewPager+Fragment,線性布局中再去部署TextView和View,ViewPager滑動時,線性布局的布局就要跟着變化。直到我遇到了Metrial Design的TabLayout,我才意識到原來實作一個這樣的導航效果還可以這麼友善,下面我就來使用TabLayout實作如圖的導航欄效果。
首先,要進行Material Design包的加載,我使用的是Android Studio 3.0版本,在app的build.gradle中添加依賴:
implementation 'com.android.support:design:28.0.0-alpha1'
接着,實作如圖的導航,除了使用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()這個方法,否則導航欄沒有标題,隻有一個導覽列,如下圖:
在布局中使用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部落格的内容講解。