修改ViewPage的r预加载,左右滑动,切换经过中间页问题,ViewPager一屏显示多张图片

2017-04-16 19:40:01
1.屏蔽切换的时候需要经过中间页
2.屏蔽ViewPager的滑动
3.预加载问题

复制代码

import android.content.Context;import android.support.v4.view.ViewPager;import android.util.AttributeSet;import android.view.MotionEvent;/**
 * 1.屏蔽切换的时候需要经过中间页
 * 2.屏蔽ViewPager的滑动
 * 3.预加载问题 */public class MyViewPager extends ViewPager {    /**
     * 是否可以滑动     */
    private boolean isCanScroll = false;    public MyViewPager(Context context) {        super(context);
    }    public MyViewPager(Context context, AttributeSet attrs) {        super(context, attrs);
    }    /**
     * 解决切换需要经过中间页     */
    @Override    public void setCurrentItem(int item) {        //super.setCurrentItem(item);源码
        super.setCurrentItem(item,false);//false表示切换的时候,不经过两个页面的中间页    }    /**
     * 让ViewPager不能左右滑动     */
    @Override    public boolean onTouchEvent(MotionEvent ev) {        if(isCanScroll){            return super.onTouchEvent(ev);
        }else{            return false;
        }
    }    /**
     * 暴露出去的方法,屏蔽ViewPager的滑动,默认不可滑动
     * @param isCanScroll 为true可以左右滑动,为false不可滑动     */
    public void setIsCanScroll(boolean isCanScroll){        this.isCanScroll = isCanScroll;
    }

    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        if(isCanScroll){            return super.onInterceptTouchEvent(ev);
        }else{            return false;
        }
    }    /* 设置预加载页数的源码,默认为1,当设置的数大于1是有效的,小于1就无效了
       1)如果想预加载多页(默认预加载一页),可以使用setOffscreenPageLimit(int limit),意思为幕后页的限制,默认为1
       2)当你不想要预加载的时候,那是不是只需要将这个值设为0呢?答案是不行的,
      解决办法:复制ViewPager源码将DEFAULT_OFFSCREEN_PAGES这个值改为0就可以了
    public void setOffscreenPageLimit(int limit) {
        if (limit < DEFAULT_OFFSCREEN_PAGES) {
            limit = DEFAULT_OFFSCREEN_PAGES;//可见当设置的值小于1时无效
        }
        if (limit != mOffscreenPageLimit) {
            mOffscreenPageLimit = limit;
            populate();
        }
    }     */}

复制代码

但是切记,复制ViewPager源码别复制高版本的,防止出问题,因为现在Android都7.0了,版本都老高了,其实android虽然每个版本都有v4包,但是这些v4包是有差异的。这就造成高版本v4包里的ViewPager,即使你Copy它,将其DEFAULT_OFFSCREEN_PAGES的值改为0,还是不起作用的,其中的逻辑变了。具体哪里变了导致无效我也没有继续研究了,下面给出一份低版本修改好的(只修改了预加载)

 View Code

2.利用ViewPager实现一屏显示多张图片的问题

MainActivity代码:

复制代码

public class MainActivity extends AppCompatActivity {    private List<ImageView> list;    private int[] imgsId={R.drawable.a,R.drawable.b,R.drawable.c,R.drawable.d};

    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
        initData();
        viewPager.setAdapter(new MyPagerAdapter(list));
    }    
    //初始化显示的图片
    private void initData() {
        list = new ArrayList<>();        for (int i : imgsId) {
            ImageView imageView = new ImageView(MainActivity.this);
            imageView.setImageResource(i);
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            list.add(imageView);
        }
    }
}

复制代码

适配器:

复制代码

public class MyPagerAdapter extends PagerAdapter {    private List<ImageView> list;    public MyPagerAdapter(List<ImageView> list) {        this.list = list;
    }

    @Override    public int getCount() {        return list.size();
    }

    @Override    public boolean isViewFromObject(View view, Object object) {        return view == object;
    }

    @Override    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(list.get(position));        return list.get(position);
    }

    @Override    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
        object = null;
    }    /**
     * 设置该页内容所占屏幕的宽度     */
    @Override    public float getPageWidth(int position) {        //return 1.f; 默认返回1,代表该position占据了ViewPager的一整页,范围(0,1]
        return 0.8f;
    }
}

复制代码

布局文件:

 View Code

效果如下: 如果没重写getPageWidth()方法(左图)              重写后为(右图)

下面看下一屏显示多张图片的具体实现:

由于上面适配器中的getPageWidth方法只能控制一边的距离,不能实现左右两边显示,所以改功能需要删除上面适配器中的getPageWidth()方法

java代码:

复制代码

import android.os.Bundle;import android.support.v4.view.ViewPager;import android.support.v7.app.AppCompatActivity;import android.view.MotionEvent;import android.view.View;import android.widget.ImageView;import android.widget.LinearLayout;import java.util.ArrayList;import java.util.List;/**
 * ViewPager显示多张图片 */public class MainActivity extends AppCompatActivity {    private List<ImageView> list;    private int[] imgsId={R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d};

    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();//初始化数据        //ViewPager的父布局
        final LinearLayout viewPagerContainer  = (LinearLayout) findViewById(R.id.viewPager_layout);        final ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
        viewPager.setOffscreenPageLimit(3); // viewPager的缓存页数
        viewPager.setPageMargin(30); // 设置各页面的间距        // 将父节点Layout事件分发给viewpager,否则只能滑动中间的一个view对象
        viewPagerContainer.setOnTouchListener(new View.OnTouchListener() {
            @Override            public boolean onTouch(View v, MotionEvent event) {                return viewPager.dispatchTouchEvent(event);
            }
        });        //设置ViewPager的滑动监听,必须在滑动的时候刷新界面才能看到效果
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {                //必须刷新页面,才能看到效果
                if (viewPagerContainer != null) {
                    viewPagerContainer.invalidate();
                }
            }

            @Override            public void onPageSelected(int position) {

            }

            @Override            public void onPageScrollStateChanged(int state) {

            }
        });        //设置适配器
        viewPager.setAdapter(new MyPagerAdapter(list));
    }    //初始化显示的图片
    private void initData() {
        list = new ArrayList<>();        for (int i : imgsId) {
            ImageView imageView = new ImageView(MainActivity.this);
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            imageView.setImageResource(i);
            list.add(imageView);
        }
    }
}

复制代码

布局文件:

复制代码

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/viewPager_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:layerType="software"
    android:clipChildren="false">

    <!--
        一屏显示多张图片的步骤:
        1.配置ViewPager和其父布局的 android:clipChildren属性为”false”.
            (android:clipChildren表示是否限制子View在其范围内,默认为true. 代码设置setClipChildren(false))
            因为如果clipChildren属性设置为true,就表明我们要将children给clip掉,
            就是说对于子元素来说,超出当前view的部分都会被切掉,那我们在这里把它设置成false,
            就表明超出view的部分,不要切掉,依然显示。

        2.设置ViewPager的父布局,android:layerType="software",这样才能显示左右两边的图片,否则不显示为空白

        3.设置幕后item的缓存数目。如果一屏展示的pager数目多的话就需要设置此项。
            viewPager.setOffscreenPageLimit(3); //具体缓存页数看需求

        4.设置页与页之间的间距
            viewPager.setPageMargin(int marginPixls);// setPageMargin表示设置page之间的间距

        5.将ViewPager的父布局触摸事件分发给viewpager,否则只能滑动ViewPager中间的那个view对象

        6.必须在ViewPager的滑动监听中刷新界面才能看到效果
        
        具体代码见MainActivity的onCreate方法两空行之间的代码     -->

    <!--android:layout_marginLeft="50dp"
        android:layout_marginRight="50dp"代表居中显示的pager距离屏幕左右两边的距离-->
    <android.support.v4.view.ViewPager        android:id="@+id/viewPager"
        android:clipChildren="false"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="50dp"
        android:layout_width="match_parent"
        android:layout_height="300dp">
    </android.support.v4.view.ViewPager></LinearLayout>

复制代码

效果如下:

 如果需要切换效果可以看鸿洋大神的:   巧用ViewPager 打造不一样的广告轮播切换效果

https://github.com/hongyangAndroid/MagicViewPager


  • 2020-04-12 17:42:43

    Node.js设置CORS跨域请求中多域名白名单的方法

    在Node.js中,res的响应头Header中的 Access-Control-Allow-Origin 属性不能匹配除 (*) 以外的正则表达式的,域名之间不能也用逗号分隔。也就是说, Access-Control-Allow-Origin 的属性值只允许设置为单个确定域名字符串或者 (*)。

  • 2020-04-14 09:40:59

    CSS3实现文字描边的2种方法

    首先想到去看CSS3有没有什么属性可以实现,后来被我找到了text-stroke     该属性是一个复合属性,可以设置文字宽度和文字描边颜色      该属性使用很简单:text-stroke:1px #f00;(1px是文字宽度,#ff是文字描边颜色)

  • 2020-04-14 09:42:47

    用 TypeScript 编写 npm 模块

    自从开始使用 Node.js 已经一年多,写的代码越多,越是觉得自己提高的越慢。想来应该有没有将单一功能的代码封装在一个独立模块,而导致代码稍微多一点就维护困难的原因。

  • 2020-04-14 09:46:25

    TypeScript 入门教程

    TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法,因此现有的 JavaScript 代码可与 TypeScript 一起工作无需任何修改,TypeScript 通过类型注解提供编译时的静态类型检查。 TypeScript 可处理已有的 JavaScript 代码,并只对其中的 TypeScript 代码进行编译。

  • 2020-04-14 09:51:03

    package.json 字段说明

    package.json 有很多字段,也有很多官方字段,我们需要知道他们的具体是做什么的才能很好的运用

  • 2020-04-14 15:35:52

    caniuse前端兼容性检查和使用

    相信大家都曾用caniuse网站查询过css、js的一些兼容性问题,并且都从它反馈的兼容性数据中获益,让我们的线上项目更加稳定、和谐的跑在用户电脑里。不过对于caniuse页面上的一些细节,我们可能会感到困惑或者模棱两可,今天就带着大家一起来重新认识caniuse这个网站,并对它的原理和细节做些探究。