毕竟是第一次做项目,所以在每一点上都做得特别认真,接下来我来给大家大致讲述一下用ViewPager+Fragment来实现app Tab主界面,突然想起来LZ居然2天没去上课了......(>....<) 没办法,为了暑假的实习offer,只好拼了!!!
package com.bob.tabui; import android.support.v4.app.*; import android.os.Bundle; import android.support.v4.view.ViewPager; import android.util.Log; import android.view.View; import android.view.View.*; import android.widget.*; import java.util.*; public class MainActivity extends FragmentActivity implements OnClickListener { private ViewPager viewPager;//v4包下的一个控件,即就是一个可以左右滑动切换的东东 private FragmentPagerAdapter adapter;//和ListView一个道理,集合——>适配器——>控件 private List<Fragment> fragments = new ArrayList<>(); /* 底部的三个按钮以及所在布局,这里我们把这三个布局添加点击时间监听即可。三个按钮用来修改其背景图 */ private LinearLayout tab01; private LinearLayout tab02; private LinearLayout tab03; private ImageButton ib01; private ImageButton ib02; private ImageButton ib03; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPager = (ViewPager) findViewById(R.id.viewpager); initView();//集中实例化这几个控件 initEvent(); adapter = new FragmentPagerAdapter(getSupportFragmentManager()) {//定义一个数据适配器 @Override//相当于添加数据了 public Fragment getItem(int position) {//position即就是当前被选中或者要显示的数据在数据集合里的下标 return fragments.get(position);//返回需要显示的控件 } @Override public int getCount() {//获取数据集大小 return fragments.size(); } }; viewPager.setAdapter(adapter);//将适配器进行最后一步的操作,安装到控件中 viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {//为ViewPager添加监听以随其动作更新ui,这点不同于BaseAdapter //主要原因在于我们需要将ViewPager和底部按钮进行联动处理,否则也用不着监听了 @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } public void onPageSelected(int position) { Log.i("logging", position+""); resetTabBtn();//一定要在修改对应选中的按钮状态时先重置所有按钮,否则会让前边的效果影响后边 switch (position) {//在响应该页被选中时,需要同时修改底部对应的按钮状态 case 0: ib01.setImageResource(R.mipmap.one_clicked); break; case 1: ib02.setImageResource(R.mipmap.two_clicked); break; case 2: ib03.setImageResource(R.mipmap.one_clicked); } } @Override public void onPageScrollStateChanged(int state) { } }); //viewPager.setCurrentItem(0);//默认选中的是第一页,当然啦,我们也可以在这个地方进行自定义 /** *需要说明的是,如果你不设置这个或者设置为和系统默认的一样的话,onPageSelected是不会被调用的 * api: this method will be invoked when a new page becomes selected; * 接下来的读者自行脑补吧,哈哈~~~ */ } protected void resetTabBtn() {//重置每一个按钮的图标为灰暗 ib01.setImageResource(R.mipmap.one_normal); ib02.setImageResource(R.mipmap.two_normal); ib03.setImageResource(R.mipmap.three_normal); } private void initView() { tab01 = (LinearLayout) findViewById(R.id.ll_first); tab02 = (LinearLayout) findViewById(R.id.ll_second); tab03 = (LinearLayout) findViewById(R.id.ll_third); ib01 = (ImageButton) findViewById(R.id.btn_first);//在这里我觉得不用以上三个布局进行查找也可以,博友如有高见,还请指出 ib01.setImageResource(R.mipmap.one_clicked);//如果默认第一个,那就直接在这里进行选定高亮操作吧 ib02 = (ImageButton) findViewById(R.id.btn_second); ib03 = (ImageButton) findViewById(R.id.btn_third); Tab01 frag01 = new Tab01();//实例化3个Fragment Tab02 frag02 = new Tab02(); Tab03 frag03 = new Tab03(); fragments.add(frag01);//添加到集合 fragments.add(frag02); fragments.add(frag03); } private void initEvent() { tab01.setOnClickListener(this); tab02.setOnClickListener(this); tab03.setOnClickListener(this); } @Override public void onClick(View view) {//点击底部按钮对ViewPager进行切换 int currentIndex = 0; switch (view.getId()) {//只需要选择被选中页,底部按钮会自动在onPageSelected中更新 case R.id.ll_first: currentIndex = 0; break; case R.id.ll_second: currentIndex = 1; break; case R.id.ll_third: currentIndex = 2; } viewPager.setCurrentItem(currentIndex);//点击后切换当前选中page,或者说是fragment } /* 这一段是按照翔神写的,以上做了相应的重构 public void setSelect(int i) { switch (i) {//在响应该页被选中时,需要同时修改底部对应的按钮状态 case 0: ((ImageButton) findViewById(R.id.btn_first)).setImageResource(R.mipmap.one_clicked); break; case 1: ((ImageButton) findViewById(R.id.btn_second)).setImageResource(R.mipmap.two_clicked); break; case 2: ((ImageButton) findViewById(R.id.btn_third)).setImageResource(R.mipmap.one_clicked); } viewPager.setCurrentItem(i);//设置当前第i页为选中状态 }*/ }
大致思路:
step1、
用过ListView和GridView的同学们对本片博客实现的方式都有种似曾相识的感觉吧~~~ 哇哈哈,没错!!!骚年你猜对了,对于ViewPager而言它和ListView以及GridView用的是同一个套路。只不过这里的FragmentPageAdapter适配器的用法和BaseAdapter是一致的!!!
step2、
然后我们需做的就是对ViewPager对象用onPageChangeListener进行监听。(我靠,不是说和ListView用法一致么,怎么还??)哈哈,仔细想想,我们当年滑动ListView的时候,仅仅是滑动而已~~~如果你只是想滑动ViewPager,你也可以不要这个~~~当然啦,在这里作为Tab界面的组件,我们还是需要做出一个联动效果的(也就是类似于微信的底部栏按钮一一对应的效果)。所以这一步必不可少!!!可以联想到的是,我们的ListView在滑动的时候也可以通过类似的方法达到所谓的联动效果~~~在监听的方法onPageSelected里我们即可对对应的按钮进行界面更新!(ps:每次进入该方法之前一定要记得先调用重置所有按钮,要不然等你划完所有page之后,底栏目全都变高亮啦~~~)
step3、
仔细想想还有什么没做???妈蛋,微信里的那个效果不是还有点击按钮切换ViewPager界面的么~~~呦西,so easy,我们只需要给按钮或者按钮所在子布局进行点击事件监听,然后在对应的case里setCurrentItem即可,因为VIewPager在发现当前选定条目被更改之后,会invoke onPageSelected,然后它自然而然会去帮我们处理那个联动关系。。。
布局图如下: (想看效果图参考源码请猛戳项目地址 github地址)
Notice:
1、当我们设置默认选项页为0页或者不设置的时候,系统都会默认选中第0页,而此时的onPageSelected是不会被调用的,这样的话我们的高亮从何而来???解决办法:直接在初始化第一个按钮的时候对他进行高亮处理~~~
API论证:this method will be invoked when a new page becomes selected
2、在对按钮进行点击事件监听的时候,我们需要做的只有setCurrentItem(),因为在这以后,onPageSelected会自动被调用~~~希望翔哥能够看到!!!