前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >android 中间大两边小,android 画廊效果(中间大两边小)的无限轮播banner「建议收藏」

android 中间大两边小,android 画廊效果(中间大两边小)的无限轮播banner「建议收藏」

作者头像
全栈程序员站长
发布2022-09-01 15:05:49
1.2K0
发布2022-09-01 15:05:49
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

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;

}

}

LoopPagerAdapterWrapper类

package com.hexin.cardservice.ui.customView;

/**

* Created by 15061 on 2018/12/21.

*/

import android.os.Parcelable;

import android.support.v4.view.PagerAdapter;

import android.view.View;

import android.view.ViewGroup;

public class LoopPagerAdapterWrapper extends PagerAdapter {

private PagerAdapter mAdapter;

LoopPagerAdapterWrapper(PagerAdapter adapter) {

this.mAdapter = adapter;

}

@Override

public void notifyDataSetChanged() {

super.notifyDataSetChanged();

}

public int toInnerPosition(int realPosition) {

return realPosition + getCount() / 2 – getCount() % getRealCount();

}

int toRealPosition(int position) {

return position % getRealCount();

}

@Override

public int getCount() {

return Integer.MAX_VALUE;

}

public int getRealCount() {

return mAdapter.getCount();

}

public PagerAdapter getRealAdapter() {

return mAdapter;

}

@Override

public Object instantiateItem(ViewGroup container, int position) {

int realPosition = position % getRealCount();

return mAdapter.instantiateItem(container, realPosition);

}

@Override

public void destroyItem(ViewGroup container, int position, Object object) {

int realPosition = position % getRealCount();

mAdapter.destroyItem(container, realPosition, object);

}

@Override

public void finishUpdate(ViewGroup container) {

mAdapter.finishUpdate(container);

}

@Override

public boolean isViewFromObject(View view, Object object) {

return mAdapter.isViewFromObject(view, object);

}

@Override

public void restoreState(Parcelable bundle, ClassLoader classLoader) {

mAdapter.restoreState(bundle, classLoader);

}

@Override

public Parcelable saveState() {

return mAdapter.saveState();

}

@Override

public void startUpdate(ViewGroup container) {

mAdapter.startUpdate(container);

}

@Override

public void setPrimaryItem(ViewGroup container, int position, Object object) {

mAdapter.setPrimaryItem(container, position, object);

}

}

配置文件代码

android:id=”@+id/relativelayout”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:layout_marginTop=”15dp”>

<.loopviewpager>

android:id=”@+id/myviewpager”

android:layout_width=”match_parent”

android:layout_height=”125dp” />

android:id=”@+id/layout_dots”

android:layout_width=”wrap_content”

android:layout_height=”30dp”

android:layout_alignParentBottom=”true”

android:layout_centerHorizontal=”true”

android:gravity=”center”

android:orientation=”horizontal”/>

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:这些就是轮播效果图了,希望对读者有帮助。。。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/142000.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年5月2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档