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