继上一次写的 进行一次大调整,
效果图:
首先 看下自定义循环控件代码, 这个控件已经封装好了, 直接可以拿来用, 我会在下面 的文章介绍使用方法
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();//开始构建
以上就代码的全部了, 欢迎大家一起指点出错误