早期Android应用通常使用TabHost实现页面之间的切换,现在更多的选择ViewPager与Fragment结合的方式实现页面切换。Android提供了专门的适配器-FragmentPagerAdapter和FragmentStatePagerAdapter让ViewPager与Fragment一起工作。
ViewPager
ViewPager控件继承自ViewGroup,所以它是一个容器类,可以包含其他View类。ViewPager是android扩展包v4包中的类,这个类通过适配器PagerAdapter管理页面,可以实现让用户左右滑动切换当前的view。
案例目录:
具体使用步骤如下:
在主活动(ViewPagerActivity)对应的xml(viewpager_layout.xml)文件下添加ViewPager控件:
<?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">
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.viewpager.widget.ViewPager>
</LinearLayout>
准备几个要切换的视图:home_activity.xml、near_activity.xml、order_activity.xml、mine_activity.xml
样例:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:text="具体的内容"
android:textSize="25sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_home"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
ViewPager类需要一个PagerAdapter适配器给它提供数据,接下来实现PagerAdapter:
public class MyPagerAdapter extends PagerAdapter {
private List<View> pageList;
public MyPagerAdapter(List<View> pageList) {
this.pageList = pageList;
}
@Override
//返回展示的页面数量
public int getCount() {
return pageList.size();
}
@Override
//负责初始化指定位置的页面,并且需要返回当前页面本本身
public Object instantiateItem(ViewGroup container, int position) {
container.addView(pageList.get(position));
return pageList.get(position);
}
@Override
//负责移除指定位置的页面
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(pageList.get(position));
}
@Override
//直接写"return view ==object;"即可
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
}
编写主活动文件:
声明ViewPager、适配器及相关页面,然后进行初始化和相关绑定。
public class ViewPagerActivity extends Activity {
private ViewPager myViewPager; // 要使用的ViewPager
private View pageHome, pageNear, pageOrder, pageMine; // ViewPager包含的页面
private List<View> pageList; // ViewPager包含的页面列表,一般给adapter传的是一个list
private MyPagerAdapter myPagerAdapter; // 适配器
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager_layout);
myViewPager = (ViewPager) findViewById(R.id.viewpager);
pageList = new ArrayList<View>();
LayoutInflater inflater = getLayoutInflater();
pageHome = inflater.inflate(R.layout.home_activity, null);
pageNear = inflater.inflate(R.layout.near_activity, null);
pageOrder = inflater.inflate(R.layout.order_activity, null);
pageMine = inflater.inflate(R.layout.mine_activity, null);
pageList.add(pageHome);
pageList.add(pageNear);
pageList.add(pageOrder);
pageList.add(pageMine);
myPagerAdapter = new MyPagerAdapter(pageList);
myViewPager.setAdapter(myPagerAdapter);
}
}
运行结果:
ViewPager与Fragment结合
Android运行在各种各样的屏幕分辨率的设备中,为了使App能够适应各种设备(手机、平板),可以使用碎片Fragment;
新建活动MyFragmentActivity,修改配置文件fragment_layout.xml:官方建议将ViewPager与Fragment配合使用,实现不同页面独立布局及响应,接下来布局上,使用ViewPager与底部RadioButton进行结合。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager.widget.ViewPager
android:id="@+id/fragment_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.viewpager.widget.ViewPager>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@android:color/black"
android:orientation="horizontal" >
<RadioButton
android:id="@+id/home_tab"
style="@style/bottom_tab"
android:checked="true"
android:drawableTop="@mipmap/icon_home"
android:text="首页" />
<RadioButton
android:id="@+id/near_tab"
style="@style/bottom_tab"
android:drawableTop="@mipmap/icon_nearby"
android:text="附近" />
<RadioButton
android:id="@+id/order_tab"
style="@style/bottom_tab"
android:drawableTop="@mipmap/icon_order"
android:text="预约" />
<RadioButton
android:id="@+id/mine_tab"
style="@style/bottom_tab"
android:drawableTop="@mipmap/icon_mine"
android:text="我的" />
</RadioGroup>
</LinearLayout>
</RelativeLayout>
之后对应home_activity.xml、near_activity.xml、order_activity.xml、mine_activity.xml
四个Layout文件准备对应的Frament类,以home_activity.xml为例,新建一个HomeFragment:
public class HomeFragment extends Fragment {
private Button btn_home;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.home_activity, container, false);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
btn_home = (Button) getActivity().findViewById(R.id.btn_home);
//点击跳转到另一个Activity
btn_home.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(getActivity(), ViewPagerActivity.class);
startActivity(intent);
}
});
}
}
之后设置适配器,Android中提供了一些专门的适配器ViewPager与Frament一起工作,即FragmentPagerAdapter(适用于少量相对静态的页面)与FragmentStatePagerAdapter(多用于大量的页面)。它们都继承自PagerAdapter,存在许多相似之处。
适配器采用FragmentPagerAdapter,我们需要至少实现getCount、getItem方法:
public class MyFragmentAdapter extends FragmentPagerAdapter {
public final static int TAB_COUNT = 4;
public MyFragmentAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position){
case MyFragmentActivity.TAB_HOME:
HomeFragment homeFragment = new HomeFragment();
return homeFragment;
case MyFragmentActivity.TAB_NEAR:
NearFragment nearFragment = new NearFragment();
return nearFragment;
case MyFragmentActivity.TAB_ORDER:
OrderFragment orderFragment = new OrderFragment();
return orderFragment;
case MyFragmentActivity.TAB_MINE:
MineFragment mineFragment = new MineFragment();
return mineFragment;
}
return null;
}
@Override
public int getCount() {
return TAB_COUNT;
}
}
接下来编辑MyFragmentActivity实现,测试运行时不要忘记修改主活动:
public class MyFragmentActivity extends FragmentActivity implements View.OnClickListener{
public static final int TAB_HOME = 0;
public static final int TAB_NEAR = 1;
public static final int TAB_ORDER = 2;
public static final int TAB_MINE = 3;
private ViewPager viewPager;
private RadioButton homeBtn;
private RadioButton nearBtn;
private RadioButton orderBtn;
private RadioButton mineBtn;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_layout);
initView();
}
private void initView() {
viewPager = (ViewPager) findViewById(R.id.fragment_viewpager);
homeBtn = (RadioButton) findViewById(R.id.home_tab);
nearBtn = (RadioButton) findViewById(R.id.near_tab);
orderBtn = (RadioButton) findViewById(R.id.order_tab);
mineBtn = (RadioButton) findViewById(R.id.mine_tab);
homeBtn.setOnClickListener(this);
nearBtn.setOnClickListener(this);
orderBtn.setOnClickListener(this);
mineBtn.setOnClickListener(this);
MyFragmentAdapter adapter = new MyFragmentAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
switch (position) {
case TAB_HOME:
homeBtn.setChecked(true);
break;
case TAB_NEAR:
nearBtn.setChecked(true);
break;
case TAB_ORDER:
orderBtn.setChecked(true);
break;
case TAB_MINE:
mineBtn.setChecked(true);
break;
default:
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.home_tab:
viewPager.setCurrentItem(TAB_HOME);
break;
case R.id.near_tab:
viewPager.setCurrentItem(TAB_NEAR);
break;
case R.id.order_tab:
viewPager.setCurrentItem(TAB_ORDER);
break;
case R.id.mine_tab:
viewPager.setCurrentItem(TAB_MINE);
break;
}
}
}
运行结果: