引言:
当我们的启动页、引导页、网络请求管理类和用户管理类都一步步完善好之后,就要开始实现整个应用的界面了,根据主流应用和多数用户的习惯。首页(主页面)一般都是有底部导航栏的,根据所点击的导航栏中不同的按钮,完成对应的Fragment的切换是主流的做法。
效果如下,上方是ViewPager中的“日更”Fragment,底下一排就是用来切换不同Fragment的TabBar的按钮:
首先整理一下思路:
整个布局在一个Activity中,上方是一个ViewPager,底部是一个TabBar。通过点击TabBar中的不同按钮,实现ViewPager中不同的Fragment之间的切换,从而实现该功能。这里的底部TabBar可以自己写,也可以用第三方的,这里采用第三方。
实现:
步骤一、
引入依赖:
compile 'me.majiajie:pager-bottom-tab-strip:2.2.4'
步骤二、
主页面:
- xml布局:
其中 NoScrollMainViewpage是继承自ViewPager的自定义控件,其作用是使ViewPager不滑动,可先直接复制下来放入项目中备用(后面有源代码)。
PageNavigationView为第三方的TabBar切换工具。
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:fitsSystemWindows="true">
<!--首页ViewPager,不可左右滑动的VP,-->
<com.smartlib.cmnObject.ui.NoScrollMainViewpage
android:id="@+id/vp_main_home"
android:background="@color/white"
android:layout_above="@+id/ll_bottom_tab_bar"
android:layout_below="@id/rl_main_navigation"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.smartlib.cmnObject.ui.NoScrollMainViewpage>
<LinearLayout
android:id="@+id/ll_bottom_tab_bar"
android:orientation="vertical"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="49.5dp">
<!--用于底部切换的TabBar-->
<me.majiajie.pagerbottomtabstrip.PageNavigationView
android:id="@+id/tab_bar"
android:background="@color/transparent"
android:layout_width="match_parent"
android:layout_height="49dp">
</me.majiajie.pagerbottomtabstrip.PageNavigationView>
</LinearLayout>
</RelativeLayout>
NoScrollMainViewpage源代码如下,直接复制到项目中:
/**
* 不可以滑动的viewpager
*/
public class NoScrollMainViewpage extends ViewPager {
private boolean noScroll = false;
/**
* 上一次x坐标
*/
private float beforeX;
private int xDown, xUp, yDown, yUp;
private int pageIndex;
private OnTouchListener onTouchListener;
public void setIndex(int index) {
this.pageIndex = index;
}
public NoScrollMainViewpage(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public NoScrollMainViewpage(Context context) {
super(context);
}
public void setNoScroll(boolean noScroll) {
this.noScroll = noScroll;
}
@Override
public void scrollTo(int x, int y) {
super.scrollTo(x, y);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (noScroll)
return false;
else
return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int index = getCurrentItem();
if (noScroll) {
return super.dispatchTouchEvent(ev);
} else {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN://按下如果‘仅’作为‘上次坐标’,不妥,因为可能存在左滑,motionValue大于0的情况(来回滑,只要停止坐标在按下坐标的右边,左滑仍然能滑过去)
beforeX = ev.getX();
break;
case MotionEvent.ACTION_MOVE:
float motionValue = ev.getX() - beforeX;
if (motionValue > 0 && index == 1 && pageIndex == 0) {//禁止左滑
return true;
}
beforeX = ev.getX();//手指移动时,再把当前的坐标作为下一次的‘上次坐标’,解决上述问题
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
if (onTouchListener != null) {
onTouchListener.onTouch(this, ev);
}
return super.dispatchTouchEvent(ev);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (noScroll){
return false;
} else {
return super.onInterceptTouchEvent(event);
}
}
@Override
public void setCurrentItem(int item) {
super.setCurrentItem(item);
}
@Override
public void setOnTouchListener(OnTouchListener l) {
super.setOnTouchListener(l);
onTouchListener = l;
}
}
主页面的布局到此完成。
- Activity中的java代码:
其中HomeViewPagerAdapter是自定义的适配器(后面有源代码)
/**
*主页面
*/
public class MainActivity extends AppCompatActivity{
private NoScrollMainViewpage mViewPager;
//TabBar的外层容器
private LinearLayout mBottomTabBarLL;
//将要在ViewPager中切换的三个Fragment
private HomeListFragment homeListFragment;//日更
private CatCircleFragment suckCatFragment;//吸猫
private MineFragment mineFragment;//我的
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
/**
* 主页视图初始化
*/
private void initView() {
configViewPager();
configTabBar();
//TabBar的外层容器
mBottomTabBarLL = (LinearLayout) findViewById(R.id.ll_bottom_tab_bar);
}
/**
* 设置VP关联Fragment
*/
private void configViewPager() {
mViewPager = (NoScrollMainViewpage) findViewById(R.id.vp_main_home);
mViewPager.setNoScroll(true);
List<Fragment> fragmentList = new ArrayList<>();
homeListFragment = new HomeListFragment();//日更
suckCatFragment = new CatCircleFragment();//吸猫
mineFragment = new MineFragment();//我的
fragmentList.add(homeListFragment);
fragmentList.add(suckCatFragment);
fragmentList.add(mineFragment);
FragmentManager fragmentManager = getSupportFragmentManager();
//自定义适配器
HomeViewPagerAdapter viewPagerAdapter = new HomeViewPagerAdapter(fragmentManager, fragmentList);
mViewPager.setAdapter(viewPagerAdapter);
mViewPager.setCurrentItem(0);
mViewPager.setOffscreenPageLimit(2);//预加载2个
}
/**
* 初始化底部导航
*/
private void configTabBar() {
PageNavigationView tabBar = (PageNavigationView) findViewById(R.id.tab_bar);
NavigationController navigationController = tabBar.custom()
.addItem(createTabBarItem(R.drawable.ic_day_up_date_normal, R.drawable.ic_day_up_date_selected, "日更"))
.addItem(createTabBarItem(R.drawable.ic_cat_circlr_normal, R.drawable.ic_cat_circle_selected, "吸猫"))
.addItem(createTabBarItem(R.drawable.ic_mine_normal, R.drawable.ic_mine_selected, "我的"))
.build();
navigationController.setupWithViewPager(mViewPager);
//此方法决定点击按钮切换不同的Fragment
navigationController.addTabItemSelectedListener(new OnTabItemSelectedListener() {
@Override
public void onSelected(int index, int old) {
//需要注意的是,本方法可能会对Fragment中的生命周期产生影响,尽量不要在本方法中使用各Fragment的对象去调用其中的方法
if (index == 0) {
//第一个按钮的逻辑
xxx.setText("日更");
} else if (index == 1) {
//第二个按钮的逻辑
xxx.setText("吸猫");
} else if (index == 2) {
//第三个按钮的逻辑
xxx.setText("我的");
}
}
@Override
public void onRepeat(int index) {
}
});
}
/**
* tabBar 初始图文及其颜色
*/
private BaseTabItem createTabBarItem(int normalDrawable, int selectedDrawable, String text) {
MainTabItemView itemView = new MainTabItemView(this);
itemView.initialize(normalDrawable, selectedDrawable, text);
itemView.setTextDefaultColor(getResources().getColor(R.color.color_home_list_bar_normal));
itemView.setTextCheckedColor(getResources().getColor(R.color.color_home_list_bar_selected));
return itemView;
}
}
Activity中的代码到此完成,下面看一下HomeViewPagerAdapter:
3.自定义VP适配器:HomeViewPagerAdapter
代码如下:
/**
* 主页VP适配器
* 用来切换页卡中不同Fragment
*/
public class HomeViewPagerAdapter extends FragmentPagerAdapter {
private FragmentManager fragmentManager;
private List<Fragment> fragmentList;
public HomeViewPagerAdapter(FragmentManager fm, List<Fragment> list) {
super(fm);
this.fragmentManager = fm;
this.fragmentList = list;
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
}
以上,完成了应用的页面切换功能,该第三方控件还有其他更多的功能,共同学习。
结束。