zoukankan      html  css  js  c++  java
  • Android Studio精彩案例(三)《模仿微信ViewPage+Fragment实现方式二》

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

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


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

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

    一、底部tab的布局:

    看一下继承结构:


    核心代码:

    <LinearLayout
        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" >
    
        <ImageButton
            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" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="微信"
            android:textColor="#ffffff" />
    </LinearLayout>
    连续添加四个按钮就好了。

    注意:

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

     我们知道:项目中的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<BaseFragment> mFragments = new ArrayList<BaseFragment>();
    
        public FragmentAdapter(FragmentManager fm, List<BaseFragment> 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设置好适配器:

    //添加fragment
    List<BaseFragment> mFragments = new ArrayList<BaseFragment>();
    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);
    }
    
    @Override
    public 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文章。

    微信公众号图片:


  • 相关阅读:
    [轉]javascript 的 location 各種用法
    [轉]PHP命名空间规则解析及高级功能
    [轉]虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器
    [轉]深入理解SQL Server 2005 中的 COLUMNS_UPDATED函数
    [連接]JavaScript中链式调用之研习
    [轉]安装SQL SERVER 2008时,提示:服务SQLBrowser启动请求失败
    AS支除兩邊的空格
    [轉]详解UML六大关系(依赖、类属(继承)、关联、实现、聚合和组合)
    [轉]jQuery UI 关闭父窗口打开的Dialog
    [轉]让PHP支持像jQuery那样的链式操作
  • 原文地址:https://www.cnblogs.com/wanghang/p/6299483.html
Copyright © 2011-2022 走看看