ViewPager 简单介绍
前三节我们分别用不同的方式实现了普通底部导航栏的效果,而本节我们将会在 Fragment RadioButton 实现底部导航栏 基础上 加上ViewPager来实现滑动切换页面的效果
ViewPager 是一个页面切换的组件,我们可以往里面填充多个View,然后我们可以通过触摸屏幕左右滑动 切换不同的 View
更多 ViewPager
的知识可以访问我们的 Android ViewPager
我们先来看看最后的效果图
-
创建一个 空的 Android 项目
cn.twle.android.FragmentViewPager
-
下载解压 /static/i/android/fragment_tab_demo.zip,并把所有的图片拖到
res/drawable
目录下 -
在
res/drawable
目录下新建四个文件tab_menu_home.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/tab_home_pressed" android:state_checked="true" /> <item android:drawable="@drawable/tab_home" /> </selector>
tab_menu_category.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/tab_category_pressed" android:state_checked="true" /> <item android:drawable="@drawable/tab_category" /> </selector>
tab_menu_cart.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/tab_cart_pressed" android:state_checked="true" /> <item android:drawable="@drawable/tab_cart" /> </selector>
tab_menu_discover.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/tab_discover_pressed" android:state_checked="true" /> <item android:drawable="@drawable/tab_discover" /> </selector>
-
在
res/drawable
目录下新建文件tab_menu_text.xml
创建文字资源因为文字也会根据是否选中而改变颜色
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="#1296db" android:state_checked="true" /> <item android:color="#515151" /> </selector>
-
在
res/drawable
目录下新建文件tab_menu_bg.xml
创建背景资源选中的 tab 背景会有点灰色
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true"> <shape> <solid android:color="#ffdddddd" /> </shape> </item> <item> <shape> <solid android:color="#00FFFFFF" /> </shape> </item> </selector>
-
在
res/layout
目录下创建一个Fragment
的简单布局 fg_content.xml<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff"> <TextView android:id="@+id/ms_txt_content" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="简单教程,简单编程" android:textColor="#333333" android:textSize="20sp"/> </LinearLayout>
-
资源方面我们已经准备的差不多了,现在开始添加布局
仔细看效果图,我们可以把整个页面分成三大块
- 顶部的 title 栏
- 中间的具体页面
- 底部的 tabbar
-
添加底部导航栏布局
把每个
RadioButton
都相同的属性抽取出来,添加到 styles.xml 文件中<style name="tab_menu_item"> <item name="android:layout_width">0dp</item> <item name="android:layout_weight">1</item> <item name="android:layout_height">match_parent</item> <item name="android:background">@drawable/tab_menu_bg</item> <item name="android:button">@null</item> <item name="android:gravity">center</item> <item name="android:paddingTop">3dp</item> <item name="android:textColor">@drawable/tab_menu_text</item> <item name="android:textSize">18sp</item> </style>
-
修改
activity_main.xml
创建布局<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:id="@+id/ms_topbar" android:layout_width="match_parent" android:layout_height="48dp" android:background="#FCFCFC"> <TextView android:id="@+id/ms_topbar_title" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" android:gravity="center" android:textSize="18sp" android:textColor="#694E42" android:text="信息"/> <View android:layout_width="match_parent" android:layout_height="2px" android:background="#E5E5E5" android:layout_alignParentBottom="true"/> </RelativeLayout> <RadioGroup android:id="@+id/ms_tab_bar" android:layout_width="match_parent" android:layout_height="56dp" android:layout_alignParentBottom="true" android:background="#ffffff" android:orientation="horizontal"> <RadioButton android:id="@+id/ms_tab_home" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_home" android:text="首页" /> <RadioButton android:id="@+id/ms_tab_category" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_category" android:text="分类" /> <RadioButton android:id="@+id/ms_tab_discover" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_discover" android:text="发现" /> <RadioButton android:id="@+id/ms_tab_cart" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_cart" android:text="购物车" /> </RadioGroup> <View android:id="@+id/div_tab_bar" android:layout_width="match_parent" android:layout_height="2px" android:background="#E5E5E5" android:layout_above="@id/ms_tab_bar"/> <android.support.v4.view.ViewPager android:id="@+id/ms_content" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/div_tab_bar" android:layout_below="@id/ms_topbar" /> </RelativeLayout>
-
隐藏顶部导航栏
最后在 AndroidManifest.xml 设置下 theme 属性
android:theme="@style/Theme.AppCompat.NoActionBar"
-
在
MainActivity.java
同一目录下新建文件MsFragment.java
package cn.twle.android.fragmentviewpager; import android.annotation.SuppressLint; import android.support.v4.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; @SuppressLint("ValidFragment") public class MsFragment extends Fragment { private String content; public MsFragment(String content) { this.content = content; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fg_content,container,false); TextView txt_content = (TextView) view.findViewById(R.id.ms_txt_content); txt_content.setText(content); return view; } }
-
在
MainActivity.java
目录下新建MsFragmentPagerAdapter.java
package cn.twle.android.fragmentviewpager; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.view.ViewGroup; public class MsFragmentPagerAdapter extends FragmentPagerAdapter { private final int PAGER_COUNT = 4; private MsFragment mFragment1 = null; private MsFragment mFragment2 = null; private MsFragment mFragment3 = null; private MsFragment mFragment4 = null; public MsFragmentPagerAdapter(FragmentManager fm) { super(fm); mFragment1 = new MsFragment("第一个 Fragment"); mFragment2 = new MsFragment("第二个 Fragment"); mFragment3 = new MsFragment("第三个 Fragment"); mFragment4 = new MsFragment("第四个 Fragment"); } @Override public int getCount() { return PAGER_COUNT; } @Override public Object instantiateItem(ViewGroup vg, int position) { return super.instantiateItem(vg, position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { System.out.println("position Destory" + position); super.destroyItem(container, position, object); } @Override public Fragment getItem(int position) { Fragment fragment = null; switch (position) { case MainActivity.PAGE_ONE: fragment = mFragment1; break; case MainActivity.PAGE_TWO: fragment = mFragment2; break; case MainActivity.PAGE_THREE: fragment = mFragment3; break; case MainActivity.PAGE_FOUR: fragment = mFragment4; break; } return fragment; } }
-
修改
MainActivity.java
package cn.twle.android.fragmentviewpager;; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v4.view.ViewPager; import android.widget.RadioButton; import android.widget.RadioGroup; public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener, ViewPager.OnPageChangeListener { //UI Objects private RadioGroup ms_tab_bar; private RadioButton ms_tab_home ; private RadioButton ms_tab_category; private RadioButton ms_tab_discover; private RadioButton ms_tab_cart; private ViewPager ms_content; private MsFragmentPagerAdapter mAdapter; //几个代表页面的常量 public static final int PAGE_ONE = 0; public static final int PAGE_TWO = 1; public static final int PAGE_THREE = 2; public static final int PAGE_FOUR = 3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mAdapter = new MsFragmentPagerAdapter(getSupportFragmentManager()); bindViews(); ms_tab_home.setChecked(true); } private void bindViews() { ms_tab_bar = (RadioGroup) findViewById(R.id.ms_tab_bar); ms_tab_home = (RadioButton) findViewById(R.id.ms_tab_home); ms_tab_category = (RadioButton) findViewById(R.id.ms_tab_category); ms_tab_discover = (RadioButton) findViewById(R.id.ms_tab_discover); ms_tab_cart = (RadioButton) findViewById(R.id.ms_tab_cart); ms_tab_bar.setOnCheckedChangeListener(this); ms_content = (ViewPager) findViewById(R.id.ms_content); ms_content.setAdapter(mAdapter); ms_content.setCurrentItem(0); ms_content.addOnPageChangeListener(this); } @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.ms_tab_home: ms_content.setCurrentItem(PAGE_ONE); break; case R.id.ms_tab_category: ms_content.setCurrentItem(PAGE_TWO); break; case R.id.ms_tab_discover: ms_content.setCurrentItem(PAGE_THREE); break; case R.id.ms_tab_cart: ms_content.setCurrentItem(PAGE_FOUR); break; } } //重写ViewPager页面切换的处理方法 @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { } @Override public void onPageScrollStateChanged(int state) { //state的状态有三个,0表示什么都没做,1正在滑动,2滑动完毕 if (state == 2) { switch (ms_content.getCurrentItem()) { case PAGE_ONE: ms_tab_home.setChecked(true); break; case PAGE_TWO: ms_tab_category.setChecked(true); break; case PAGE_THREE: ms_tab_discover.setChecked(true); break; case PAGE_FOUR: ms_tab_cart.setChecked(true); break; } } } }
因为 ViewPager
是 v4 包下面的,所以 Fragment
,FragmentManager
,FragmentTransaction
都是需要使用
V4包下的哦
另外获取 FragmentManager
的方法不是直接用 getFragmentManager()
而是使用 getSupportFragmentManager()
注意:如果 ViewPager
放在 RadioButton
后,RadioButton
的点击事件会失效