码迷,mamicode.com
首页 > 移动开发 > 详细

Android底部Tab页基于ViewPager的实现

时间:2015-07-09 21:32:01      阅读:256      评论:0      收藏:0      [点我收藏+]

标签:android   tablet   viewpager   底部导航   

在众多主流App中,包括QQ,微信等,为了和ios的UI保持统一,很多App使用的都是底部导航,当然在Android中也并不反对这种设计。这篇文章使用ViewPager实现这种效果。首先看实现效果图吧。效果图中包含了ViewPager的嵌套。

技术分享

技术分享

在讨论实现之前,我们先来回忆一下,之前我们是如何实现的。

之前的实现方法,我们无法是先进行布局,再编写逻辑。而布局,底部有一定高度的Tab,一般由4个或者5个,也有3个的,具体视应用而定,而Tab上方则是一个FrameLayout,用于作为fragment的容器。在Activity中处理对应的点击事件的逻辑,需要自己控制Fragment的显示与隐藏,有时候控制不好甚至会带来莫名其妙的问题。

那么有没有一种简单的方法,避免我们自己编写Fragment切换的逻辑呢,其实是有的,ViewPager正是这个控件,这时候有人问了,一般放在底部的导航内容区域是点击切换的,不会滑动切换(微信除外),ViewPager是会滑动切换的,那么怎么解决这个问题呢。答案是重写ViewPager,提供一个布尔变量,用于控制是否支持滑动切换,通过这个变量,对对应事件的函数onTouchEvent和onInterceptTouchEvent进行重写,如果该变量设置为true,即支持滑动切换,也就是ViewPager的默认行为,我们使用父类的方法进行处理。如果是false,我们不进行处理或者不进行拦截,返回false即可。这样,我们的ViewPager子类的代码就成了这样。

public class CustomViewPager extends ViewPager {
    private boolean isCanScroll = false;

    public CustomViewPager(Context context) {
        super(context);
    }

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public boolean isCanScroll() {
        return isCanScroll;
    }

    public void setCanScroll(boolean isCanScroll) {
        this.isCanScroll = isCanScroll;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (isCanScroll) {
            return super.onTouchEvent(ev);
        } else {
            return false;
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (isCanScroll) {
            return super.onInterceptTouchEvent(ev);
        } else {
            return false;
        }
    }
}

使用我们自己的ViewPager代替默认的ViewPager进行布局就可以了,如下

    <com.kltz.tabdemo.view.CustomViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        >
    </com.kltz.tabdemo.view.CustomViewPager>

然后我们简单进行底部Tab的布局

<RadioGroup
        android:id="@+id/radio"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#e8e8e8"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/tab1"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/btn"
            android:button="@drawable/btn"
            android:gravity="center"
            android:text="Tab1"
            />

        <RadioButton
            android:id="@+id/tab2"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/btn"
            android:button="@null"
            android:gravity="center"
            android:text="Tab2"
            />

        <RadioButton
            android:id="@+id/tab3"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/btn"
            android:button="@null"
            android:gravity="center"
            android:text="Tab3"
            />

        <RadioButton
            android:id="@+id/tab4"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/btn"
            android:button="@null"
            android:gravity="center"
            android:text="Tab4"
            />
    </RadioGroup>

上面两段布局外围是一个线性布局,使用了layout_weight属性控制了内容区域的高度。

然后Tab按钮的点击是有效果的,编写我们的Selector作为按钮的背景,这里随便选了两个颜色,实际开发中用对应图片代替。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:drawable="@color/accent_material_light"/>
    <item android:drawable="@color/abc_search_url_text_normal"/>
</selector>

最后来看看我们简单的逻辑处理,对RadioGroup设置监听,当点击了之后判断是哪一个Button,将ViewPager显示为对应的页,使用setCurrentItem函数,第二个参数传false,代表无切换动画。

public class MainActivity extends AppCompatActivity{
    private CustomViewPager mViewPager;
    private RadioGroup mRadioGroup;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        mViewPager= (CustomViewPager) findViewById(R.id.viewpager);
        mRadioGroup= (RadioGroup) findViewById(R.id.radio);
        mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
            @Override
            public Fragment getItem(int i) {
                return BaseFragment.newInstance(i);
            }

            @Override
            public int getCount() {
                return 4;
            }
        });
        mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                    case R.id.tab1:
                        mViewPager.setCurrentItem(0, false);
                        break;
                    case R.id.tab2:
                        mViewPager.setCurrentItem(1, false);
                        break;
                    case R.id.tab3:
                        mViewPager.setCurrentItem(2, false);
                        break;
                    case R.id.tab4:
                        mViewPager.setCurrentItem(3, false);
                        break;
                }
            }
        });
    }

}

很简单的Tab实现有木有,有时候系统有的组件,我们需要的功能如果与其相似,可以改造一下直接拿来用,没必要重复造轮子。

源码下载

http://download.csdn.net/detail/sbsujjbcy/8881617

如果你觉得对你有帮助,点个赞吧!

版权声明:本文为博主原创文章,未经博主允许不得转载。

Android底部Tab页基于ViewPager的实现

标签:android   tablet   viewpager   底部导航   

原文地址:http://blog.csdn.net/sbsujjbcy/article/details/46808177

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!