智者不为愚者谋,勇者不为怯者死。这篇文章主要讲述android实现3D Gallery 轮播效果,触摸时停止轮播相关的知识,希望能为你提供帮助。
1、轮播控件涉及到的两个类
CarouselViewPager.java
public class CarouselViewPager extends ViewPager { @IntDef({RESUME, PAUSE, DESTROY}) @Retention(RetentionPolicy.SOURCE) public @interface LifeCycle { }public static final int RESUME = 0; public static final int PAUSE = 1; public static final int DESTROY = 2; /** * 生命周期状态,保证{@link #mCarouselTimer}在各生命周期选择执行策略 */ private int mLifeCycle = RESUME; /** * 是否正在触摸状态,用以防止触摸滑动和自动轮播冲突 */ private boolean mIsTouching = false; /** * 超时时间 */ private int timeOut = 2; /** * 轮播定时器 */ private ScheduledExecutorService mCarouselTimer; /** * 有数据时,才开始进行轮播 */ private boolean hasData; public CarouselViewPager(Context context) { super(context); }public CarouselViewPager(Context context, AttributeSet attrs) { super(context, attrs); }public void setLifeCycle(@LifeCycle int lifeCycle) { this.mLifeCycle = lifeCycle; }@Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: mIsTouching = true; break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: mIsTouching = false; break; } return super.onTouchEvent(ev); }@Override protected void onAttachedToWindow() { super.onAttachedToWindow(); startTimer(); }public void startTimer() { if (!hasData) { return; } shutdownTimer(); mCarouselTimer = Executors.newSingleThreadScheduledExecutor(); mCarouselTimer.scheduleAtFixedRate(new Runnable() { @Override public void run() { switch (mLifeCycle) { case RESUME: if (!mIsTouching & & getAdapter() != null & & getAdapter().getCount() > 1) { post(new Runnable() { @Override public void run() { setCurrentItem(getCurrentItem() + 1); } }); } break; case PAUSE: break; case DESTROY: shutdownTimer(); break; } } }, 0, 1000 * timeOut, TimeUnit.MILLISECONDS); }public void setHasData(boolean hasData) { this.hasData = https://www.songbingjia.com/android/hasData; }public void setTimeOut(int timeOut) { this.timeOut = timeOut; }@Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); shutdownTimer(); }private void shutdownTimer() { if (mCarouselTimer != null & & mCarouselTimer.isShutdown() == false) { mCarouselTimer.shutdown(); } mCarouselTimer = null; } }
CarouselPagerAdapter.java
/** * @描述 @link CarouselViewPager 轮播控件}所需的adapter */public abstract class CarouselPagerAdapter< V extends CarouselViewPager> extends PagerAdapter { /** * 系数,可以自行设置,但又以下原则需要遵循: * < ul> * < li> 必须大于1< /li> * < li> 尽量小< /li> * < /ul> */ private static final int COEFFICIENT = 10; private V mViewPager; public CarouselPagerAdapter(V viewPager) { this.mViewPager = viewPager; }/** * @return 实际数据数量 */ @IntRange(from = 0) public abstract int getRealDataCount(); @Override public final int getCount() { long realDataCount = getRealDataCount(); if (realDataCount > 1) { realDataCount = getRealDataCount() * COEFFICIENT; realDataCount = realDataCount > Integer.MAX_VALUE ? Integer.MAX_VALUE : realDataCount; } return (int) realDataCount; }@Override public final boolean isViewFromObject(View view, Object object) { return view == object; }@Override public final Object instantiateItem(ViewGroup container, int position) { position = position % getRealDataCount(); return this.instantiateRealItem(container, position); }public abstract Object instantiateRealItem(ViewGroup container, int position); @Override public final void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); }@Override public final void finishUpdate(ViewGroup container) { // 数量为1,不做position替换 if (getCount() < = 1) { return; }int position = mViewPager.getCurrentItem(); // ViewPager的更新即将完成,替换position,以达到无限循环的效果 if (position == 0) { position = getRealDataCount(); mViewPager.setCurrentItem(position, false); } else if (position == getCount() - 1) { position = getRealDataCount() - 1; mViewPager.setCurrentItem(position, false); } } }
2、实现3D效果需要用到的类
public class GalleryTransformer implements ViewPager.PageTransformer { @Override public void transformPage(View view, float position) { float scale = 0.5f; float scaleValue = https://www.songbingjia.com/android/1 - Math.abs(position) * scale; view.setScaleX(scaleValue); view.setScaleY(scaleValue); view.setAlpha(scaleValue); view.setPivotX(view.getWidth() * (1 - position - (position > 0 ? 1 : -1) * 0.75f) * scale); view.setElevation(position > -0.25 & & position < 0.25 ? 1 : 0); } }
3、使用方法
public class MainActivity extends AppCompatActivity { private CarouselViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPager = (CarouselViewPager) findViewById(R.id.id_viewpager); ImagePagerAdapter adapter = new ImagePagerAdapter(this, viewPager); viewPager.setOffscreenPageLimit(3); viewPager.setAdapter(adapter); // 设置轮播时间 viewPager.setTimeOut(5); // 设置3d效果 viewPager.setPageTransformer(true, new GalleryTransformer()); // 设置已经有数据了,可以进行轮播,一般轮播的图片等数据是来源于网络,网络数据来了后才设置此值,此处因为是demo,所以直接赋值了 viewPager.setHasData(true); // 开启轮播 viewPager.startTimer(); } }
public class ImagePagerAdapter extends CarouselPagerAdapter< CarouselViewPager> {public ImagePagerAdapter(Context context, CarouselViewPager viewPager) { super(viewPager); }int[] imgRes = { R.drawable.img_wallhaven_426244, R.drawable.img_wallhaven_431231, R.drawable.img_wallhaven_432740, /*R.drawable.img_wallhaven_426244, R.drawable.img_wallhaven_431231, R.drawable.img_wallhaven_432740, R.drawable.img_wallhaven_426244, R.drawable.img_wallhaven_431231, R.drawable.img_wallhaven_432740,*/ }; @Override public Object instantiateRealItem(ViewGroup container, int position) { ImageView view = new ImageView(container.getContext()); view.setScaleType(ImageView.ScaleType.FIT_XY); view.setAdjustViewBounds(true); view.setImageResource(imgRes[position]); view.setLayoutParams(new LinearLayout.LayoutParams(900, 400)); container.addView(view); return view; }@Override public int getRealDataCount() { return imgRes != null ? imgRes.length : 0; } }
【android实现3D Gallery 轮播效果,触摸时停止轮播】ps:
ImagePagerAdapter.java是一个普通的PagerAdapter类,用户自定义,需要继承CarouselPagerAdapter< CarouselViewPager> 并重写CarouselPagerAdapter的构造方法,在
public Object instantiateRealItem(ViewGroup container, int position) 方法中定义界面的具体显示
public int getRealDataCount() { return imgRes != null ? imgRes.length : 0; }方法中返回具体的页面总数
< ?xml version="1.0" encoding="utf-8"?> < RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" android:gravity="center" tools:context=".MainActivity"> < com.twiceyuan.galleryviewpager.CarouselViewPager android:id="@+id/id_viewpager" android:layout_width="240dp" android:layout_height="120dp" android:clipChildren="false"/> < /RelativeLayout>
文章图片
推荐阅读
- 解决ActiveAndroid在Android6.0及以上的设备上,表创建失败的问题
- Android的FixScrollView自定义控件
- AssertionError: View function mapping is overwriting an existing endpoint function: admin.main
- 英伦大厦游戏英伦大厦app定制开发系统
- Android - IPC之AIDL简介
- 在fedora25x86下编译opencv的Android版本的过程记录
- android之多进程下Application.getSharedPreferences的取值
- React Native组件之BackAndroid !安卓手机的物理返回键的使用
- 抓取Iphone上app的网络数据