viewPager 实现banner图 自动轮播

时间:2022-08-04 10:12:00

 继上一次写的 进行一次大调整,

效果图:

viewPager 实现banner图 自动轮播

viewPager 实现banner图 自动轮播


首先 看下自定义循环控件代码, 这个控件已经封装好了, 直接可以拿来用, 我会在下面 的文章介绍使用方法

package com.example.administrator.bbactivity.banner;

import android.content.Context;
import android.os.AsyncTask;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
* Created by yahui.hu on 2016/4/25.
*/
public class LoopBanner<T> extends RelativeLayout {

private ViewPager mViewPager;

private LinearLayout mIndicator;

private int mDp5;

private List<T> mDatas;

private int[] mIndicators;

private long mLoopTime;

private LoopBaseViewHold mViewHold;

private boolean mAutoLoop;
private boolean mCanLoop;

private int mDataSize;

private LoopAdapter mLoopAdapter;

private int mCurrentPosition;

private Context mContext;

private List<TextView> mIndicatorTextViews;

private int mIndicatorWidth;

private int mIndicatorSpace;

private Timer mTimer;

public LoopBanner(Context context) {
super(context);
}

public LoopBanner(Context context, AttributeSet attrs) {
super(context, attrs);
initViews(context);
}

public LoopBanner(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

private void initViews(Context context) {

mContext = context;


mDp5 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, context.getResources().getDisplayMetrics());

mIndicatorWidth = mDp5 * 2;
mIndicatorSpace = mDp5 / 5;
mTimer = new Timer();
mLoopTime = 3000;
mAutoLoop = true;
mCanLoop = true;

mViewPager = new ViewPager(context);
LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
mViewPager.setLayoutParams(params);
this.addView(mViewPager);

mIndicator = new LinearLayout(context);
LayoutParams indicatorParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
indicatorParams.addRule(ALIGN_PARENT_BOTTOM);
indicatorParams.bottomMargin = mDp5;
mIndicator.setLayoutParams(indicatorParams);
this.addView(mIndicator);

}

public LoopBanner setIndicator(int[] indicators) {
mIndicators = indicators;
return this;
}

public LoopBanner setIndicatorWidth(int width) {
mIndicatorWidth = width;
return this;
}

public LoopBanner setIndicatorSpace(int space) {
mIndicatorSpace = space;
return this;
}

public LoopBanner setDatas(List<T> datas) {
mDatas = datas;
return this;
}

public LoopBanner setLoopTime(long time) {
mLoopTime = time;
return this;
}

public LoopBanner setViewHold(LoopBaseViewHold viewHold) {
mViewHold = viewHold;
return this;
}

public LoopBanner setCanAutoLoop(boolean canAutoLoop) {
mAutoLoop = canAutoLoop;
mCanLoop = canAutoLoop;
return this;
}

public void builder() {
checkRequireItems();
mDataSize = mDatas.size();
initLoopPageAdapter();

if (mDataSize > 1) {
mViewPager.setCurrentItem(1, false);
mIndicatorTextViews = new ArrayList<>();
createIndicator();
initLoopTime();
}
}

public void notificationDataChange() {
mDataSize = mDatas.size();
mLoopAdapter.notificationDataChange();
}



private void createIndicator() {
mIndicator.removeAllViews();
mIndicatorTextViews.clear();
if (mIndicators != null && mIndicators.length > 1) {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(mIndicatorWidth, mIndicatorWidth);
layoutParams.rightMargin = mIndicatorSpace;
for (int i = 0; i < mDataSize; i ++) {
TextView textView = new TextView(mContext);
textView.setLayoutParams(layoutParams);
mIndicatorTextViews.add(textView);
textView.setBackgroundResource(mIndicators[1]);
mIndicator.addView(textView);
}
mIndicator.setGravity(Gravity.CENTER_HORIZONTAL);
mIndicatorTextViews.get(0).setBackgroundResource(mIndicators[0]);
mPreSelectPosition = 0;
}
}

private int mPreSelectPosition;
private void changeIndicator(int currentSelectPosition) {
if (mPreSelectPosition != currentSelectPosition) {
mIndicatorTextViews.get(mPreSelectPosition).setBackgroundResource(mIndicators[1]);
mIndicatorTextViews.get(currentSelectPosition).setBackgroundResource(mIndicators[0]);
mPreSelectPosition = currentSelectPosition;
}
}

private void initLoopPageAdapter() {
mLoopAdapter = new LoopAdapter();
mViewPager.setAdapter(mLoopAdapter);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
public void onPageSelected(int position) {
mCurrentPosition = position;
changeIndicator(mLoopAdapter.getRealPosition(position));
}

@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
if (mCurrentPosition == 0) {
mViewPager.setCurrentItem(mDataSize, false);
}

if (mCurrentPosition == mDataSize + 1) {
mViewPager.setCurrentItem(1, false);
}
}
}
});


}


private void initLoopTime() {
mTimer.schedule(new TimerTask() {
@Override
public void run() {
if (!mAutoLoop) return;
mCurrentPosition ++;

new LoopScroll().execute(mCurrentPosition);

}
}, mLoopTime, mLoopTime);

}

private void checkRequireItems() {
try {
if (mDatas == null || mDatas.size() < 1) {
throw new Exception("data size must be greater than 1");
}
if (mViewHold == null) {
throw new Exception("mViewHold is null, please call the method 'setViewHold()'");
}
} catch (Exception e) {
e.printStackTrace();
}
}


class LoopAdapter extends PagerAdapter {

private HashMap<Integer, ObjectHolder> mViewMap = new HashMap<>();
private int getRealPosition(int position) {
int dataSize = mDataSize;
if (dataSize < 2) return position;
int realPosition = (position - 1) % dataSize;
if (realPosition < 0) {
realPosition += dataSize;
}
return realPosition;
}

@Override
public int getCount() {
return (mDataSize == 1) ? mDataSize : mDataSize + 2;
}

@Override
public boolean isViewFromObject(View view, Object object) {

return view == object;
}


@Override
public Object instantiateItem(ViewGroup container, int position) {
final int realPosition = getRealPosition(position);
ObjectHolder objectHolder = mViewMap.get(realPosition);
if (objectHolder == null) {
objectHolder = new ObjectHolder(mViewHold.createViewHolder(realPosition), realPosition, container);
objectHolder.object.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mViewHold.setViewData(realPosition, mDatas.get(realPosition));
}
});

}
if (container.indexOfChild(objectHolder.object) == -1) {
container.addView( objectHolder.object);
}


return objectHolder.object;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
int realPosition = getRealPosition(position);
if (!(realPosition == 0 || realPosition == mDataSize - 1)) {
container.removeView((View) object);
}
}

void notificationDataChange() {
mViewMap.clear();
this.notifyDataSetChanged();

}
}

class ObjectHolder {
View object;
int position;
ViewGroup container;

public ObjectHolder(View object, int position, ViewGroup container) {
this.object = object;
this.position = position;
this.container = container;
}
}

class LoopScroll extends AsyncTask<Integer, Integer, Integer> {

@Override
protected Integer doInBackground(Integer... params) {
return params[0];
}

@Override
protected void onPostExecute(Integer integer) {

mViewPager.setCurrentItem(integer);
}
}
}

下面这个类也是必须需要的, 这个类主要是创建view, 点击veiw 触发事件的回调.

package com.example.administrator.bbactivity.banner;

import android.view.View;

/**
* Created by yahui.hu on 2016/4/25.
*/
public abstract class LoopBaseViewHold<T> {
public abstract View createViewHolder(int position);
public abstract void setViewData(int position, T viewData);
}


下面是该类的使用方法:

  mLoopBanner = (LoopBanner) findViewById(R.id.my_test_banner);
mLoopBanner.setDatas(imageViews) //这个是必须要的不然会报错,设置对象数据.
.setViewHold(new LoopBaseViewHold<ImageView>() { //这个是必须要的不然会报错, 回调类
@Override
public View createViewHolder(int position) {
//当前页面该展示什么view
return imageViews.get(position);
}

@Override
public void setViewData(int position, ImageView viewData) {
//当前页面被点击了时间, viewData 是setDatas()中 position位置的数据
}

}).setIndicator(new int[]{R.drawable.btn_top_pressed, R.drawable.dot_normal}) // 指示点, 第一个是选中状态,第二个是未选中的, 不设值将无法显示指示点
.setIndicatorWidth(10)//设置指示点大小,
.setIndicatorSpace(10)//设置指示点间距
.setCanAutoLoop(true)//设置是否自动循环轮播, 默认是true
.setLoopTime(3000)//设置轮播时间,默认是3000
.builder();//开始构建



以上就代码的全部了, 欢迎大家一起指点出错误