转载本专栏文章,请注明出处,尊重原创 。文章博客地址:道龙的博客

写在前面的话:此专栏是博主在工作之余所写,每一篇文章尽可能写的思路清晰一些,属于博主的“精华”部分,不同于以往专栏的文章,是直接结合实际开发的。喜欢的朋友可以关注我,给与更好的思路或者意见,哪怕有一点点帮助到您,这才是最重要的。


上一篇模仿微信底部tab的方式实现滑动效果,那里的手段是通过动态添加View的方式,上一篇就提到,实现tab切页面的手段有很多种,本篇就使用另一种方式——ViewPage+Fragment;并对对其中的核心功能做一下封装。

使用过ViewPager小伙伴们都知道,Viewpager加载数据,需要数据源,这里我们定义4个Fragment。为了方便其他同事使用,可以给这4个Fragment添加了一个基类,核心代码如下:

一、底部tab的布局:

看一下继承结构:


核心代码:

    android:id="@+id/id_tab_bottom_weixin"    android:layout_width="0dp"    android:layout_height="fill_parent"    android:layout_weight="1"    android:descendantFocusability="beforeDescendants"    android:gravity="center"    android:orientation="vertical" >            android:id="@+id/btn_tab_bottom_weixin"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="#0000"        android:src="@drawable/tab_weixin" />            android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="微信"        android:textColor="#ffffff" />
连续添加四个按钮就好了。

注意:

对于布局中设置控件是否获取焦点,有以下知识点:

 我们知道:项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写。诸如ImageButton,Button,CheckBox等子控件(也可以说是Button或者Checkable的子类控件)此时这些子控件会将焦点获取到,所以常常当点击item时变化的是子控件,item本身的点击没有响应。  

     android:descendantFocusability

Defines the relationship between the ViewGroup and its descendants when looking for a View to take focus.

Must be one of the following constant values.


该属性是当一个为view获取焦点时,定义viewGroup和其子控件两者之间的关系。

属性的值有三种:

        beforeDescendants:viewgroup会优先其子类控件而获取到焦点

        afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点

        blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点

至于用法么,就是在item 里的RelativeLayout 加入android:descendantFocusability="beforeDescendants"

二、创建Fragment的基类,实现子类

public abstract class BaseFragment extends Fragment {    public Context mContext;    @Override    public void onCreate(@Nullable Bundle savedInstanceState) {        //获取上下文操作        mContext = getActivity();        super.onCreate(savedInstanceState);    }    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {        View curentView = initView();        return curentView;    }    @Override    public void onActivityCreated(@Nullable Bundle savedInstanceState) {        initData();//初始化数据        super.onActivityCreated(savedInstanceState);    }    /**抽象方法,子类调用*/    public abstract View initView();    public abstract View initData();}
代码太简单了,增加了一个抽象的initView和一个初始化数据的initData。那么咱们看看一个子类的代码:

public class AddressFragment extends BaseFragment {    @Override    public View initView() {        return View.inflate(mContext, R.layout.fragment_address,null);    }    @Override    public View initData() {        return null;    }}
其中每个fragment的布局都仅仅是显示一段文本即可。

三、完成核心代码,完成主活动。

我们创建viewPager的adapter类:

public class FragmentAdapter extends FragmentPagerAdapter {    List mFragments = new ArrayList();    public FragmentAdapter(FragmentManager fm, List fragments) {        super(fm);        this.mFragments = fragments;    }    @Override    public Fragment getItem(int position) {        return mFragments.get(position);    }    @Override    public int getCount() {        return mFragments.size();    }}
然后在活动里面,添加四个fragment,并给viewpage设置好适配器:

//添加fragmentList mFragments = new ArrayList();mFragments.add(new WeChatFragment());mFragments.add(new FriendFragment());mFragments.add(new AddressFragment());mFragments.add(new SettingFragment());//设置不进行预加载mViewpages.setOffscreenPageLimit(0);FragmentAdapter mAdapter = new FragmentAdapter(getSupportFragmentManager(), mFragments);mViewpages.setAdapter(mAdapter);
剩下的就是根据点击tab,切换对应的页面就好了。设置如下:

//ViewPage添加监听事件    mViewpages.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {        @Override        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {        }        @Override        public void onPageSelected(int position) {            //选中当前的page页面的时候,调用            changeTab(position);        }        @Override        public void onPageScrollStateChanged(int state) {        }    });    /**     * 给独步tabbtn加入点击事件     */    mBtnTabBottomWeixin.setOnClickListener(this);    mBtnTabBottomFriend.setOnClickListener(this);    mBtnTabBottomContact.setOnClickListener(this);    mBtnTabBottomSetting.setOnClickListener(this);}/** * 根据当前位置切换对应的fragment */public void changeTab(int position) {    //先清空原来的状态    mBtnTabBottomContact.setSelected(false);    mBtnTabBottomFriend.setSelected(false);    mBtnTabBottomSetting.setSelected(false);    mBtnTabBottomWeixin.setSelected(false);    //针对当前position    switch (position) {        case 0://第零页的page            mBtnTabBottomWeixin.setSelected(true);            break;        case 1://第一页            mBtnTabBottomFriend.setSelected(true);            break;        case 2:            mBtnTabBottomContact.setSelected(true);            break;        case 3:            mBtnTabBottomSetting.setSelected(true);            break;    }    //根据当前的btn位置,切换fragment页面    mViewpages.setCurrentItem(position);}@Overridepublic void onClick(View v) {    switch (v.getId()) {        case R.id.btn_tab_bottom_weixin:            changeTab(0);            break;        case R.id.btn_tab_bottom_friend:            changeTab(1);            break;        case R.id.btn_tab_bottom_contact:            changeTab(2);            break;        case R.id.btn_tab_bottom_setting:            changeTab(3);            break;    }}
最后运行程序看看结果:


看着效果还是蛮好的~

喜欢我的朋友可以关注我哈,也可以直接去下载源码


点击可下载地址:源码地址

也可以打开微信搜索公众号  Android程序员开发指南  或者手机扫描下方二维码 在公众号阅读更多Android文章。

微信公众号图片:


更多相关文章

  1. Android上hook AMS和PMS
  2. Android获取数据时 浮点型整数位数值(超8位)过大导致科学计数法
  3. 从0系统学Android--3.2四种基本布局
  4. android通过指定目录获取该目录下所有类(反编译)
  5. 基于android的网络音乐播放器-网络音乐的搜索和展示(五)
  6. android 新闻图片加载,缓存处理
  7. Layout___模块重用之include布局整合
  8. Android使用自己的字体库让你的APP更漂亮
  9. Android(安卓)图片获取及上传

随机推荐

  1. Android实现高定制化日历控件
  2. Android(安卓)NFC 对sim卡读写注意事项
  3. Android虚拟机与Java虚拟机——两种虚拟
  4. android与html5的交互——数据库操作,UI操
  5. android app签名(debug和release)
  6. PHP基础 -(六)重载/命名空间/自动加载
  7. IntelliJ iDEA激活码 | 2022 IntelliJ iD
  8. mysql:1. 实例演示数据库的CURD操作 2.
  9. 数组函数实例演示
  10. 文件上传学习小结