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

来源:互联网 发布:红外预警卫星 算法 编辑:程序博客网 时间:2024/06/05 18:49

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

一、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就不执行。

以上

0 0
原创粉丝点击