修改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


  • 2017-04-12 11:22:43

    WebView你真的熟悉吗?看了才知道

    在Android手机中内置了一款高性能webkit内核浏览器,在SDK中封装为一个叫做WebView组件。下面总结一下使用webview遇到的那些事、那些坑。

  • 2017-04-12 11:28:14

    史上最全webview详解

    WebView在现在的项目中使用的频率应该还是非常高的。 我个人总觉得HTML5是一种趋势。找了一些东西,在此总结。 本篇最后有一个非常不错 的 Html5Activity 加载类,不想看的可以直接跳下载。

  • 2017-04-12 23:11:59

    Android Studio签名打包的两种方式

    给我们自己开发的app签名,就代表着我自己的版权,以后要进行升级,也必须要使用相同的签名才行。签名就代表着自己的身份(即keystore),多个app可以使用同一个签名。

  • 2017-04-13 10:57:08

    webstorm 怎么关闭jshint

    You need to configure the inspections in Settings/Editor/Inspections, then in the list on the right, find JavaScript/JavaScript validity issues. That worked for me to remove the Chai warnings. (I am using the WebStorm 11 EAP at the moment.)

  • 2017-04-13 14:11:14

    MySQL中的describe关键字

    今天写代码的时候,有一个类的数据始终不能插入,老是提示在You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'describe, picPath1, picPath2, picPath3, picPath4, picPath5, agentId, belongStore' at line 1。因为用的是SSH进行插入,所以SQL语句不用自己写,检查了每个字段也没写错。

  • 2017-04-15 13:34:08

    Android官方技术文档翻译——清单合并

    一般情况下,有三种类型的清单文件需要合并成一个最终的应用程序清单,这里按照优先级顺序列出: Product flavors 和构建类型所指定的清单文件。 应用程序的主清单文件。 类库的清单文件。

  • 2017-04-15 21:47:44

    Android开发笔记——圆角和边框们

    在做Android界面开发时,我们往往希望它尽可能优美,尽可能显得专业。于是你看了看其他应用,哇,好多边框和圆角啊。你是不是也想给自己的应用加上边框和圆角效果?呃……那怎么做呢?如果你是从web前端跑到Android来的,那么我想你一定想到了不下三种解决方案。如用图片替代,用CSS3定义,用JS画。在Android中,其实也有类似的用法,本文将简单介绍两种Android圆角和边框的实现。