上一篇博客viewpager从入门到精通3 无限轮播viewpager 我们做了一个无限轮询的viewpager但是这个pager的效果不是很贴切,滑动不是很美观这里我们需要两个辅助帮助我们的viewpager滑动更流畅。
首先要介绍的是ViewPagerScroller 代码如下
public class ViewPagerScroller extends Scroller {
private int mDuration;
public ViewPagerScroller(Context context) {
super(context);
}
public ViewPagerScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
}
public void setDuration(int mDuration) {
this.mDuration = mDuration;
}
@Override
public void startScroll(int startX, int startY, int dx, int dy) {
super.startScroll(startX, startY, dx, dy, this.mDuration);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
super.startScroll(startX, startY, dx, dy, this.mDuration);
}
}
都是实现的Scroller 的一些方法,接下来我们就将这个scoller放到自定义viewpager中去。
public class MyViewPager extends ViewPager {
private static final int START_SCROLL_ANIM = 0;//开启滚动处理
private static final int STOP_SCROLL_ANIM = 1;//关闭滚动处理
private static final int LOOP_MESSAGE = 2;//循环消息
MyHeaderPagerHandler handler;
private int changePagerSpeed = 2000;//切换页面速度
private int loopSpeed = 3000;//每个item切换间隔
private boolean ifStopAnim = false;
public MyViewPager(Context context) {
this(context, null);
}
public MyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
handler = new MyHeaderPagerHandler(new WeakReference<>(this));
setViewPagerScrollSpeed();
}
//pager切换控制--------------------------------------------------------------------------------------------------------------------------
private void setViewPagerScrollSpeed() {
try {
Field field = ViewPager.class.getDeclaredField("mScroller");
field.setAccessible(true);
ViewPagerScroller viewPagerScroller = new ViewPagerScroller(getContext(), new AccelerateDecelerateInterpolator());
field.set(this, viewPagerScroller);
viewPagerScroller.setDuration(changePagerSpeed);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
//滑动控制--------------------------------------------------------------------------------------------------------------------------
public void startScroll() {
ifStopAnim = false;
Message message = new Message();
message.what = START_SCROLL_ANIM;
handler.sendMessage(message);
}
public void startScroll(long delay) {
ifStopAnim = false;
Message message = new Message();
message.what = START_SCROLL_ANIM;
handler.sendMessageDelayed(message, delay);
}
public void stopScroll() {
ifStopAnim = true;
handler.removeCallbacksAndMessages(null);
}
private void loopMessage() {
Message message = new Message();
message.what = LOOP_MESSAGE;
handler.sendMessageDelayed(message, loopSpeed);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
stopScroll();
break;
case MotionEvent.ACTION_UP:
startScroll(6000);
break;
}
return super.onTouchEvent(ev);
}
private static class MyHeaderPagerHandler extends Handler {
private WeakReference<MyViewPager> myPager;
MyHeaderPagerHandler(WeakReference<MyViewPager> myPager) {
this.myPager = myPager;
}
@Override
public void handleMessage(Message msg) {
if (myPager.get() == null) return;
if (myPager.get().ifStopAnim) return;
super.handleMessage(msg);
switch (msg.what) {
case START_SCROLL_ANIM:
myPager.get().loopMessage();
break;
case STOP_SCROLL_ANIM:
break;
case LOOP_MESSAGE:
myPager.get().setCurrentItem(myPager.get().getCurrentItem() + 1, true);
myPager.get().loopMessage();
break;
}
}
}
}
重点是setViewPagerScrollSpeed这个方法我们再里面通过反射获取到了mScroller这个Field 然后通过field.set(this, viewPagerScroller); viewPagerScroller.setDuration(changePagerSpeed);设置切换时长以及切换的动画,这里我选择了AccelerateDecelerateInterpolator这个动画差值器即刚开始缓慢中间加速再到最后减速。
到这里其实我们的viewpager已经滑动非常流畅了效果也不错,为了更加提升显示效果我们这里可以给viewpager添加一个PageTransformer更改滑动过程的效果。
代码如下
public class MyPageTransform implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.85f;
private static final float MIN_ALPHA = 0.5f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position < -1) { // [-Infinity,-1)
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]//a页滑动至b页 ; a页从 0.0 -1 ;b页从1 ~ 0.0
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float vertMargin = pageHeight * (1 - scaleFactor) / 2;
float horzMargin = pageWidth * (1 - scaleFactor) / 2;
if (position < 0) {
view.setTranslationX(horzMargin - vertMargin / 2);
} else {
view.setTranslationX(-horzMargin + vertMargin / 2);
}
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
} else { // (1,+Infinity]// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
实现也是非常简单的接下来就是调用过程代码如下。
public class MainActivity4 extends AppCompatActivity {
private MyViewPager vp_mian1;
private MyPagerAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
vp_mian1 = findViewById(R.id.vp_mian1);
List<View> itemViews = installItems();
adapter = new MyPagerAdapter(itemViews);
vp_mian1.setAdapter(adapter);
vp_mian1.setCurrentItem(itemViews.size() * 500);
vp_mian1.setPageTransformer(true, new MyPageTransform());
vp_mian1.startScroll();
}
public List<View> installItems() {
List<View> views = new ArrayList<>();
int drawables[] = {R.drawable.d_01, R.drawable.d_02, R.drawable.d_03, R.drawable.d_04, R.drawable.d_05};
for (int i = 0; i < 5; i++) {
RelativeLayout rlHeaderItem = (RelativeLayout) LayoutInflater.from(this).inflate(R.layout.header_pager_view, null);
ImageView ivItem = rlHeaderItem.findViewById(R.id.iv_header_item);
ivItem.setBackgroundDrawable(getResources().getDrawable(drawables[i]));
views.add(rlHeaderItem);
}
return views;
}
@Override
protected void onDestroy() {
vp_mian1.stopScroll();
super.onDestroy();
}
}
通过 vp_mian1.setPageTransformer(true, new MyPageTransform());设置viewpager的PageTransforme,这样viewpager的效果就更加漂亮了。
接下来我们介绍在listview的headerview中添加viewpager链接如下。
viewpager从入门到精通5 listview中headerview添加viewpager
GitHub传送门点击这里