Android使用ViewPager实现导航页根据情况禁止滑动以及点击切换

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/JadynAi/article/details/50881392

前段时间由于项目原因,要做一个导航页面。但有时会需要用到根据某些条件禁止滑动,以及通过按钮点击切换页面的效果。
刚好趁现在把这些东西写下来,分享出来。

一、ViewPager点击切换

因为之前做的那个项目是一个安全卫士的项目,在手机防盗这一块需要做一个导航页面。导航页面嘛,大家懂得一页一页往下翻过去,底部再加上若干个小圆点随着滑动。
其实底部小圆点这个东西也好做,最笨的办法就是给每一个View下面都排上一排,这样切换的时候一样会有动画效果,但这样未免太捉急了点。
那么这里首先我们先解决一下底部小圆点的实现方式。这种方式是动态添加的,也就是有几个滑动的页面就有几个小圆点,以后你要再添加滑动页面的时候,完全不需要再做多余的动作,十分方便。

首先,我们要准备两张图片,一张是亮色的圆点图片,另一张是暗色的圆点图片。
然后在drawable文件下创建如下文件:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/presence_invisible" android:state_selected="false" />
    <item android:drawable="@drawable/presence_online" android:state_selected="true" />
</selector>


  • 这个文件是作为小圆点的背景使用的,方便后面调用时可以切换。

接着第二步,我们在ViewPager下面做一个布局,最好使用LinearLayout布局。随机在java代码中动态地添加这些小圆点组件。代码示下:
//小圆点将会添加到的父布局
 LinearLayout linearLayout = (LinearLayout) findViewById(R.id.guadrd_bottom_linear);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        //设置小圆点间的间隔,四个参数分别指距离左端的距离,距离顶部的距离,距离右端的距离,距离底端的距离
        params.setMargins(10, 0, 10, 0);

        //Viewpager有几页就有几个小圆点,data为ViewPager的数据源
        bottomPoints = new ImageView[data.size()];
        for (int i = 0; i < bottomPoints.length; i++) {
            ImageView point = new ImageView(this);
            //圆点组件设置参数
            point.setLayoutParams(params);                    point.setImageResource(R.drawable.selector_navi_point);
            if (i == 0) {
                point.setSelected(true);//默认第一个圆点打开
            } else {
                point.setSelected(false);
            }
            //得到每个小圆点的引用,用于滑动页面时,(onPageSelected方法中)更改它们的状态
            bottomPoints[i] = point;
            //添加到布局里面显示 
            linearLayout.addView(point);
        }


  • 以上代码为动态地添加圆点组件,有几页滑动的ViewPager就有几个小圆点。

好了,这下组件有了,接下来就是如何让它正确的随着ViewPager滑动的显示了。第三步,在实现ViewPager.OnPageChangeListener接口的onPageSelected方法内:

@Override
    public void onPageSelected(int position) {
        for (int i = 0; i < bottomPoints.length; i++) {
            if (position == i) {
                bottomPoints[i].setSelected(true);
            } else {
                bottomPoints[i].setSelected(false);
            }
        }
      }
  • 当滑到第几页时,相应的就会选择亮色的圆点组件,这样就实现了动态的添加底部圆点了。

二、ViewPager根据情况禁止滑动

说实话,如今我实现的ViewPager视情况禁止滑动,仍然有些小bug。譬如刚开始禁止滑动时,还可以往回滑动, 但划回来的时候再往回滑动就不行了。但这个bug目前,我也解决不了。只能先把先前的代码先放出来了。
首先,我们做一件事的时候,第一要知道的是会达到什么效果。其次需要了解什么原因会形成这种效果。
而这里ViewPager要禁止滑动,就必须先知道它是通过什么来实现滑动的。

在ViewPager的源码里,它是通过ScrollTo这个方法来实现滑动的。那么我们只需要重写这个方法,再加上一个标记位,是不是就可以实现禁止滑动了呢?代码见真章:
在这里,我首先自定义了一个ViewPager,重写了scrollTo方法:

package com.jadyn.mobilesafe.ui.view;

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;

public class MGuardViewPager extends ViewPager {

    private boolean mIsSlide = true;//是否可以滑动
    private boolean mRightCanSlide = true;//是否可以右滑动

    private float downX;//落下的x坐标
    private float moveX;//移动的xzuobiao 
    private float appartX;//两者相差

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

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

    @Override
    public void scrollTo(int x, int y) {
        if (mIsSlide)
            super.scrollTo(x, y);
    }

    //对外暴漏一个开关禁止滑动的方法
    public void toggleSlide(boolean isSlide) {
        this.mIsSlide = isSlide;
    }
    /*
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (mRightCanSlide) {
            return super.dispatchTouchEvent(ev);
        } else {
            switch (ev.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    downX = ev.getX();
                    break;
                case MotionEvent.ACTION_MOVE:
                    moveX = ev.getX();
                    appartX = moveX - downX;
                    if (appartX<0) {
                        return true;
                    }
                    downX = moveX;
                    break;

            }
            return super.dispatchTouchEvent(ev);
        }
    }

    public void toggleRightSlide(boolean rightCanSlide) {
        this.mRightCanSlide = rightCanSlide;
    }*/
}


  • 下面被注释的是重写了dispatchTouchEvent方法,在onTouchEvent里通过坐标的差值,再返回true值,将滑动事件就此消费,不再向外传递来禁止向右滑动或者向左滑动。不过太麻烦了,还是使用scrollTo方法把。
  • 上面代码,我对外提供了一个toggleSlide()方法来实现判断是否禁止滑动。

然后我们在布局中使用我们自定义的ViewPager。并且在onPageScrolled方法进行条件判定是否需要滑动。因为onPageScrolled是在滑动页面的时候会调用的方法。
譬如我的项目在第二页以及第三页的时候需要进行判定,那么我的代码示下:
@Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        //在第二页的时候,若是没有锁就不准滑动,锁了就可以滑动
        if (position == 1) {
            guardViewpager.toggleSlide(isLocked);
        }
        //在第三页如果对话框为空就不能滑动
        if (position == 2) {
            String phoneNum = et_phone.getText().toString();
            isPhoneEmpty = TextUtils.isEmpty(phoneNum);
            guardViewpager.toggleSlide(!isPhoneEmpty);
        }
        //在第四页,若是没有激活设备管理,就不能滑动
        if (position == 3) {
            guardViewpager.toggleSlide(mIsAdmin);
        }
    }

三、按钮点击切换

其实这个最简单了,我使用的是笨办法,就是用setCurrentItem()方法实现的。大家若是有什么好的方法,也可以分享分享。
譬如,“上一页”的点击事件是这样的:

if (currentItem > 0)
                    guardViewpager.setCurrentItem(currentItem - 1);
  • 怎么样是不是很简单,而在“下一页”按钮里,因为我要做一些判定,相应地也会复杂点,当然也就是代码复杂点。逻辑很简单,无非就是true就执行,false就不执行。

以上

猜你喜欢

转载自blog.csdn.net/JadynAi/article/details/50881392