android 画廊效果(中间大两边小)的无限轮播banner
16lz
2021-01-26
android 画廊效果(中间大两边小)的无限轮播banner
ps: 项目要求做一个中间大两边小的轮播图,百度了一圈有了些灵感,分享一下心得,国际惯例先上效果图
banner.gif废话不多说,直接上关键代码:
/** * Created by tf on 2018/12/21. */import android.content.Context;import android.os.Handler;import android.os.Message;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.view.WindowManager;import android.view.animation.Interpolator;import android.widget.Scroller;import android.widget.TextView;import com.hexin.cardservice.R;import java.lang.ref.WeakReference;import java.lang.reflect.Field;import java.util.List;import java.util.concurrent.atomic.AtomicBoolean;public class LoopViewPager extends ViewPager { OnPageChangeListener mOuterPageChangeListener; private LoopPagerAdapterWrapper mAdapter; private MyHandler mHandler; private final static int HANDLE_LOOP_MSG = 101; private AtomicBoolean isAutoLoop = new AtomicBoolean(); public void setTxtPoints(List txtPoints) { this.txtPoints = txtPoints; } private List txtPoints; public void changePoints(int pos) { if (txtPoints != null) { for (int i = 0; i < txtPoints.size(); i++) { if (pos == i) { txtPoints.get(i).setBackgroundResource(R.mipmap.home_yuan_sel); } else { txtPoints.get(i).setBackgroundResource(R.mipmap.home_yuan); } } } } @Override public void setAdapter(PagerAdapter adapter) { mAdapter = new LoopPagerAdapterWrapper(adapter); super.setAdapter(mAdapter); isAutoLoop.set(false); setCurrentItem(0, false); } @Override public PagerAdapter getAdapter() { return mAdapter != null ? mAdapter.getRealAdapter() : mAdapter; } /** * 获取当前真实的item * * @return */ public int getRealItem() { return mAdapter != null ? mAdapter.toRealPosition(super.getCurrentItem()) : 0; } public void setCurrentItem(int item, boolean smoothScroll) { int realItem = mAdapter.toInnerPosition(item); super.setCurrentItem(realItem, smoothScroll); } @Override public void setOnPageChangeListener(OnPageChangeListener listener) { mOuterPageChangeListener = listener; } public LoopViewPager(Context context) { super(context); init(); } public LoopViewPager(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { super.setOnPageChangeListener(onPageChangeListener); try { Field scrollerField = ViewPager.class.getDeclaredField("mScroller"); scrollerField.setAccessible(true); Field interpolator = ViewPager.class.getDeclaredField("sInterpolator"); interpolator.setAccessible(true); Scroller scroller = new Scroller(getContext(), (Interpolator) interpolator.get(null)) { @Override public void startScroll(int startX, int startY, int dx, int dy, int duration) { //控制滑动速度 super.startScroll(startX, startY, dx, dy, (int) (1300 * (double) Math.abs(dx) / getWidth(getContext()))); } }; scrollerField.set(this, scroller); } catch (Exception e) { e.printStackTrace(); } } 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); } private OnPageChangeListener onPageChangeListener = new OnPageChangeListener() { private float mPreviousOffset = -1; private float mPreviousPosition = -1; @Override public void onPageSelected(int position) { int realPosition = mAdapter.toRealPosition(position); changePoints(realPosition); if (mPreviousPosition != realPosition) { mPreviousPosition = realPosition; if (mOuterPageChangeListener != null) { mOuterPageChangeListener.onPageSelected(realPosition); } } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { int realPosition = position; if (mAdapter != null) { realPosition = mAdapter.toRealPosition(position); if (positionOffset == 0 && mPreviousOffset == 0 && (position == 0 || position == mAdapter.getCount() - 1)) { setCurrentItem(realPosition, false); } } mPreviousOffset = positionOffset; if (mOuterPageChangeListener != null) { if (realPosition != mAdapter.getRealCount() - 1) { mOuterPageChangeListener.onPageScrolled(realPosition, positionOffset, positionOffsetPixels); } else { if (positionOffset > .5) { mOuterPageChangeListener.onPageScrolled(0, 0, 0); } else { mOuterPageChangeListener.onPageScrolled(realPosition, 0, 0); } } } } @Override public void onPageScrollStateChanged(int state) { switch (state) { case SCROLL_STATE_DRAGGING: if (isAutoLoop.get()) { mHandler.removeCallbacksAndMessages(null); } break; case SCROLL_STATE_IDLE: if (isAutoLoop.get()) { mHandler.sendEmptyMessageDelayed(HANDLE_LOOP_MSG, 3000); } break; case SCROLL_STATE_SETTLING: break; } if (mOuterPageChangeListener != null) { mOuterPageChangeListener.onPageScrollStateChanged(state); } } };// @Override// protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//// int height = 0;// for (int i = 0; i < getChildCount(); i++) {// View child = getChildAt(i);// child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));// int h = child.getMeasuredHeight();// if (h > height)// height = h;// }// int width = 0;// for (int i = 0; i < getChildCount(); i++) {// View child = getChildAt(i);// child.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), heightMeasureSpec);// int h = child.getMeasuredWidth();// if (h > width)// width = h;// }//// heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);// widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);//// super.onMeasure(widthMeasureSpec, heightMeasureSpec);// } private class MyHandler extends Handler { WeakReference mWeakReference; public MyHandler(Context context) { mWeakReference = new WeakReference<>(context); } @Override public void handleMessage(Message msg) { final Context context = mWeakReference.get(); if (context == null) { return; } switch (msg.what) { case HANDLE_LOOP_MSG: int curItem = getCurrentItem(); setCurrentItem(++curItem); changePoints(curItem % txtPoints.size() ); break; } } } public int getWidth(Context context) { WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); return outMetrics.widthPixels; }}
配置文件代码
<.LoopViewPager android:id="@+id/myviewpager" android:layout_width="match_parent" android:layout_height="125dp" />
MainActivity 应用
初始化ViewPager
private void initViewPager() { mViewpager = view.findViewById(R.id.myviewpager); //图片圆角处理 for (int i = 0; i < mBannerArr.length; i++) { ImageView view1 = new ImageView(getContext()); RoundedBitmapDrawable roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(getResources(), BitmapFactory.decodeResource(getResources(), mBannerArr[i])); //view1.setImageResource(R.mipmap.pic); roundedBitmapDrawable.setCornerRadius(30); view1.setImageDrawable(roundedBitmapDrawable); mImageList.add(view1); } mViewpager.setClipChildren(false); DisplayMetrics dm = getResources().getDisplayMetrics(); mViewpager.setPageMargin(-dm.widthPixels / 13);//设置viewpage之间的间距 RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mViewpager.getLayoutParams(); //高度根据图片进行适配(这里图片为750 *300) params.height = (int) (getResources().getDisplayMetrics().widthPixels * 330 / 750.0); params.width = getResources().getDisplayMetrics().widthPixels; mViewpager.setLayoutParams(params); mViewpager.setAdapter(new MyAdapter()); mViewpager.setPageTransformer(true, new ViewPager.PageTransformer() { float scale = 0.85f; @Override public void transformPage(View page, float position) { if (position >= 0 && position <= 1) { page.setScaleY(scale + (1 - scale) * (1 - position)); } else if (position > -1 && position < 0) { page.setScaleY(1 + (1 - scale) * position); } else { page.setScaleY(scale); } } }); mViewpager.autoLoop(true);}
初始化指示器小圆点
/** * 初始化小圆点 */ private void initCircle() { mLayoutPoints = view.findViewById(R.id.layout_dots); mTxtPoints = new ArrayList<>(); int d = DensityUtils.dp2px(mContext, 6); int m = 10; for (int i = 0; i < mImageList.size(); i++) { TextView txt = new TextView(getContext()); if (i == 0) { txt.setBackgroundResource(R.mipmap.home_yuan_sel); } else { txt.setBackgroundResource(R.mipmap.home_yuan); } LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(d, d); params.setMargins(m, m, m, m); txt.setLayoutParams(params); mTxtPoints.add(txt); mLayoutPoints.addView(txt); } mViewpager.setTxtPoints(mTxtPoints); }
viewpager自定义适配器:
class MyAdapter extends PagerAdapter { @Override public int getCount() { return mImageList.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, final int position) { ImageView view = mImageList.get(position); ViewParent viewParent = view.getParent(); if (viewParent == null) { container.addView(view); } view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { log.d(TAG, "点击了第" + postion + "张图"); } }); return view; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } }
PS:这些就是轮播效果图了,希望对读者有帮助。。。
更多相关文章
- android 使用opencv4 图片相似度对比
- Android周报第四期
- 内容提供者 (获取媒体库图片显示出来)Android10.0 适配
- android避免decodeResource图片时占用太大的内存
- MVP模式的Android(安卓)调用系统拍照,相册,剪裁,适配到7.0,修复拍照
- Glide 在Android(安卓)9.0上不显示图片
- 居中显示并旋转 android Button 里的属性drawableLeft
- android ListView中自定义SimpleAdapter动态添加ratingBar及图片
- 高通Android(安卓)display架构分析