大家好,又见面了,我是你们的朋友全栈君。
废话不多说,先上效果图
根据效果所示,第一步实现适配器,完成无限循环
首先做数据上的处理
public static class LoopViewPagerAdapter extends PagerAdapter{
.....
LoopViewPagerAdapter(Context context, ArrayList<Integer> imgIds){
this.context = context;
this.ids.add(imgIds.get(imgIds.size()-1)); 将原本的最后一页复制一份放到第一页
this.ids.addAll(imgIds);
this.ids.add(imgIds.get(0)); 将原本的第一页复制一份放到最后一页
views = new View[ids.size()];
}
.....
}
配合OnPageChangeListener 即可实现无限循环
private OnPageChangeListener onPageChangeListener = new OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
LogUtils.d("LoopViewPager onPageSelected --> " + loopViewPagerAdapter.getCount() + " : " + position);
if (position == 0){
// 滑动到第一页的时候直接跳到倒数第二页,因为两页内容完全一致,跳的过程不会被人眼捕捉到
setCurrentItem(loopViewPagerAdapter.getCount() - 2, false);
}
if (position == loopViewPagerAdapter.getCount() - 1){
// 同理滑动到倒数第一页的时候直接跳到第二页
setCurrentItem(1, false);
}
}
...
}
第二步 实现放大效果
借助OnPageChangeListener 的 onPageScrolled 滑动进度给指定的Item放大和缩小
private static final float BASE_SCALE = 0.9f; // 为方便调整放大幅度,设立的最小倍数
private static final float BASE_INCREMENT = 0.2f; // 最大放大倍数与最小放大倍数的差值
private OnPageChangeListener onPageChangeListener = new OnPageChangeListener() {
...
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
float zoom = BASE_SCALE + (BASE_INCREMENT - Math.abs(positionOffset * BASE_INCREMENT));
loopViewPagerAdapter.getViews(position).setScaleX(zoom);
loopViewPagerAdapter.getViews(position).setScaleY(zoom);
if (positionOffset > 0) {
// 左滑,右侧放大
View leftView = loopViewPagerAdapter.getViews(position + 1);
if (leftView != null){
float zoomNext = BASE_SCALE + Math.abs(positionOffset * BASE_INCREMENT);
leftView.setScaleX(zoomNext);
leftView.setScaleY(zoomNext);
}
}
if (positionOffset < 0) {
// 右滑,左侧放大
View rightView = loopViewPagerAdapter.getViews(position - 1);
if (rightView != null){
float zoomNext = BASE_SCALE + Math.abs(positionOffset * BASE_INCREMENT);
rightView.setScaleX(zoomNext);
rightView.setScaleY(zoomNext);
}
}
@Override
public void onPageScrollStateChanged(int state) {
LogUtils.d("LoopViewPager onPageScrollStateChanged --> " + state);
if (state == 0) {
int position = getCurrentItem();
for (int i = 0; i < loopViewPagerAdapter.getViews().length; i++) {
View itemView = loopViewPagerAdapter.getViews(i);
if (itemView != null){
if (i == position){
loopViewPagerAdapter.getViews(i).setScaleX(BASE_SCALE + BASE_INCREMENT);
loopViewPagerAdapter.getViews(i).setScaleY(BASE_SCALE + BASE_INCREMENT);
}else {
loopViewPagerAdapter.getViews(i).setScaleX(BASE_SCALE);
loopViewPagerAdapter.getViews(i).setScaleY(BASE_SCALE);
}
}
}
}
}
}
第三步 增加自动轮播功能
@SuppressLint("HandlerLeak")
private class MyHandler extends Handler {
WeakReference<Context> mWeakReference;
MyHandler(Context context) {
mWeakReference = new WeakReference<>(context);
}
@Override
public void handleMessage(Message msg) {
Context context = mWeakReference.get();
if (context == null) {
return;
}
if (msg.what == HANDLE_LOOP_MSG) {
int curItem = getCurrentItem() + 1;
setCurrentItem(curItem);
}
if (isAutoLoop.get()){
mHandler.sendEmptyMessageDelayed(HANDLE_LOOP_MSG, 3000);
}
}
}
// 开始自动轮播
MyHandler mHandler = new MyHandler(getContext());
mHandler.sendEmptyMessageDelayed(HANDLE_LOOP_MSG, 3000);
大功告成,附上完整代码
package com.zhlm.babyhearread.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.zhlm.babyhearread.base.utils.LogUtils;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* 自动轮播ViewPager,画廊效果(当前展示的放大,两侧待展示的缩小),两侧可看到部分
* 目前仅支持使用图片,需要其他的话请自行将PagerAdapter改造成FragmentPagerAdapter
*
* 使用方法
* <xxx.xxx.LoopViewPager
* android:id="@+id/loopViewPager"
* android:layout_width="match_parent"
* android:layout_height="wrap_content"
* android:paddingStart="40dp"
* android:paddingEnd="40dp"
* android:clipToPadding="false"
* />
*
* ArrayList<Integer> ids = new ArrayList<>();
* ids.add(R.drawable.img1);
* ids.add(R.drawable.img2);
* ids.add(R.drawable.img3);
* ids.add(R.drawable.img4);
* LoopViewPager loopViewPager = findViewById(R.id.loopViewPager);
* loopViewPager.setDates(ids); // 设置数据
* loopViewPager.autoLoop(true); // 自动轮播
*
* author liming 2019/12/9 16:40
* e-mail : limit_round@163.com
*
*/
public class LoopViewPager extends ViewPager {
private MyHandler mHandler;
private LoopViewPagerAdapter loopViewPagerAdapter;
private final static int HANDLE_LOOP_MSG = 101;
private AtomicBoolean isAutoLoop = new AtomicBoolean();
private static final float BASE_SCALE = 0.9f;
private static final float BASE_INCREMENT = 0.2f;
public LoopViewPager(Context context) {
this(context, null);
}
public LoopViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void autoLoop(boolean isAuto) {
if (mHandler == null) {
mHandler = new MyHandler(getContext());
}
if (isAuto) {
mHandler.sendEmptyMessageDelayed(HANDLE_LOOP_MSG, 3000);
} else {
mHandler.removeCallbacksAndMessages(null);
}
isAutoLoop.set(isAuto);
}
public void setDates(ArrayList<Integer> imgIds){
setOffscreenPageLimit(5);
loopViewPagerAdapter = new LoopViewPagerAdapter(getContext(), imgIds);
loopViewPagerAdapter.initItem();
setAdapter(loopViewPagerAdapter);
setCurrentItem(1);
setOnPageChangeListener(onPageChangeListener);
}
private OnPageChangeListener onPageChangeListener = new OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
LogUtils.d("LoopViewPager onPageSelected --> " + loopViewPagerAdapter.getCount() + " : " + position);
if (position == 0){
setCurrentItem(loopViewPagerAdapter.getCount() - 2, false);
}
if (position == loopViewPagerAdapter.getCount() - 1){
setCurrentItem(1, false);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
float zoom = BASE_SCALE + (BASE_INCREMENT - Math.abs(positionOffset * BASE_INCREMENT));
loopViewPagerAdapter.getViews(position).setScaleX(zoom);
loopViewPagerAdapter.getViews(position).setScaleY(zoom);
if (positionOffset > 0) {
// 左滑,右侧放大
View leftView = loopViewPagerAdapter.getViews(position + 1);
if (leftView != null){
float zoomNext = BASE_SCALE + Math.abs(positionOffset * BASE_INCREMENT);
leftView.setScaleX(zoomNext);
leftView.setScaleY(zoomNext);
}
}
if (positionOffset < 0) {
// 右滑,左侧放大
View rightView = loopViewPagerAdapter.getViews(position - 1);
if (rightView != null){
float zoomNext = BASE_SCALE + Math.abs(positionOffset * BASE_INCREMENT);
rightView.setScaleX(zoomNext);
rightView.setScaleY(zoomNext);
}
}
}
@Override
public void onPageScrollStateChanged(int state) {
LogUtils.d("LoopViewPager onPageScrollStateChanged --> " + state);
if (state == 0) {
int position = getCurrentItem();
for (int i = 0; i < loopViewPagerAdapter.getViews().length; i++) {
View itemView = loopViewPagerAdapter.getViews(i);
if (itemView != null){
if (i == position){
loopViewPagerAdapter.getViews(i).setScaleX(BASE_SCALE + BASE_INCREMENT);
loopViewPagerAdapter.getViews(i).setScaleY(BASE_SCALE + BASE_INCREMENT);
}else {
loopViewPagerAdapter.getViews(i).setScaleX(BASE_SCALE);
loopViewPagerAdapter.getViews(i).setScaleY(BASE_SCALE);
}
}
}
}
}
};
@SuppressLint("HandlerLeak")
private class MyHandler extends Handler {
WeakReference<Context> mWeakReference;
MyHandler(Context context) {
mWeakReference = new WeakReference<>(context);
}
@Override
public void handleMessage(Message msg) {
Context context = mWeakReference.get();
if (context == null) {
return;
}
if (msg.what == HANDLE_LOOP_MSG) {
int curItem = getCurrentItem() + 1;
setCurrentItem(curItem);
}
if (isAutoLoop.get()){
mHandler.sendEmptyMessageDelayed(HANDLE_LOOP_MSG, 3000);
}
}
}
public int getWidth(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
if (wm != null) {
wm.getDefaultDisplay().getMetrics(outMetrics);
}
return outMetrics.widthPixels;
}
public static class LoopViewPagerAdapter extends PagerAdapter{
private Context context;
private ArrayList<Integer> ids = new ArrayList<>();
private View[] views;
private int currItem = -1;
LoopViewPagerAdapter(Context context, ArrayList<Integer> imgIds){
this.context = context;
this.ids.add(imgIds.get(imgIds.size()-1));
this.ids.addAll(imgIds);
this.ids.add(imgIds.get(0));
views = new View[ids.size()];
}
View getViews(int position) {
return views[position];
}
View[] getViews() {
return views;
}
void initItem(){
currItem = 1;
}
@Override
public int getCount() {
return ids.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
ImageView imageView = new ImageView(context);
imageView.setImageResource(ids.get(position));
if (position == currItem){
imageView.setScaleX(BASE_SCALE + BASE_INCREMENT);
imageView.setScaleY(BASE_SCALE + BASE_INCREMENT);
currItem = -1;
}else {
imageView.setScaleX(BASE_SCALE);
imageView.setScaleY(BASE_SCALE);
}
container.addView(imageView);
views[position] = imageView;
return imageView;
}
}
}
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/131247.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...