Android自定义轮播图
吹着空调哼着歌 人气:0定义Banner
主要使用ViewPager实现滑动
public class Banner extends FrameLayout { public Context context; private @LayoutRes int layoutId = R.layout.banner_view; private View inflate; private ViewPager pager; private AutoHandler mHandler; private PagerAdapter adapter; public IndicatorView indicatorView; public Banner(@NonNull Context context) { this(context, null); } public Banner(@NonNull Context context, @Nullable AttributeSet attrs) { this(context, attrs, -1); } public Banner(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs, defStyleAttr); } public void setAdapter(PagerAdapter adapter) { this.adapter = adapter; pager.setAdapter(adapter); indicatorView.setPager(pager); } private void init(Context context, AttributeSet attrs, int defStyleAttr) { this.context = context; inflate = LayoutInflater.from(context).inflate(layoutId, this, true); pager = inflate.findViewById(R.id.banner_pager); indicatorView = inflate.findViewById(R.id.indicatorView); mHandler = new AutoHandler(pager); mHandler.start(); } public abstract static class BannerAdapter extends PagerAdapter { private List list; private Context context; public BannerAdapter(List list, Context context) { this.list = list; this.context = context; } @Override public int getCount() { if (null == list || list.size() == 0) { return 1; } else { return list.size(); } } @Override public boolean isViewFromObject(@NonNull View view, @NonNull Object object) { return view == object; } @NonNull @Override public Object instantiateItem(@NonNull ViewGroup container, int position) { if (getLayout() > 0) { View inflate = LayoutInflater.from(context).inflate(getLayout(), container, false); container.addView(inflate); setView(inflate, position); return inflate; } else { ImageView imageView = new ImageView(context); container.addView(imageView); if (list.size() > 0) { Glide.with(context).load(list.get(position)) .apply(new RequestOptions().centerCrop()) .into(imageView); } else { // Glide.with(context) // .load(R.mipmap.ic_launcher) // .apply(new RequestOptions().centerCrop()) // .into(imageView); imageView.setBackgroundResource(R.mipmap.ic_launcher); } return imageView; } } @Override public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { container.removeView((View) object); } protected abstract void setView(View inflate, int position); protected abstract int getLayout(); } }
定义定时器Handler
主要处理ViewPager的滚动 开启定时任务 ViewPager自动滚动
public class AutoHandler extends Handler { private ViewPager pager; public static int TIME = 1000 * 2; public boolean stopHandler; public AutoHandler(ViewPager pager) { this.pager = pager; } @Override public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); switch (msg.what) { case 100: if (!stopHandler) { sendEmptyMessageDelayed(100, TIME); int position = pager.getCurrentItem() + 1; if (position >= pager.getAdapter().getCount()) { position = 0; } pager.setCurrentItem(position); } else { removeMessages(100); } break; default: removeMessages(100); break; } } public void start() { stopHandler = false; if (!hasMessages(100)) { sendEmptyMessageDelayed(100, TIME); } } public void stop() { stopHandler = true; if (hasMessages(100)) { removeMessages(100); } } }
绘制一个下标指示器
主要根据需求自行绘制 可有可无 和ViewPager关联在一起 实现联动
public class IndicatorView extends View { private Context context; private ValueAnimator valueAnimator; private float value; public int indiWidth; public int indiHeight; public int indiDivide; //0圆角 1直角 public int mode; private int normalColor; private int selectColor; private int curPosition; private int count; private Paint paint; private int width; private int height; private double lastPosition; private ViewPager pager; private PagerAdapter adapter; private DataSetObserver dataSetObserver; public void setPager(final ViewPager pager) { this.pager = pager; this.adapter = pager.getAdapter(); dataSetObserver = new DataSetObserver() { @Override public void onChanged() { super.onChanged(); setCount(adapter.getCount()); setCurPosition(pager.getCurrentItem()); } }; if (null != adapter) { setCount(adapter.getCount()); setCurPosition(pager.getCurrentItem()); adapter.registerDataSetObserver(dataSetObserver); } pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { lastPosition = position; } @Override public void onPageSelected(int position) { curPosition = position; setCurPosition(position); } @Override public void onPageScrollStateChanged(int state) { } }); pager.addOnAdapterChangeListener(new ViewPager.OnAdapterChangeListener() { @Override public void onAdapterChanged(@NonNull ViewPager viewPager, @Nullable PagerAdapter oldAdapter, @Nullable PagerAdapter newAdapter) { if (oldAdapter != newAdapter) { adapter = newAdapter; setCount(adapter.getCount()); setCurPosition(viewPager.getCurrentItem()); } } }); } public void setCount(int count) { this.count = count; if (count <= 1) { setVisibility(INVISIBLE); } requestLayout(); postInvalidate(); } public void setCurPosition(int curPos) { /*记录上次记录*/ //lastPos = this.curPos; this.curPosition = curPos; //postInvalidate(); valueAnimator.start(); } public IndicatorView(Context context) { this(context, null); } public IndicatorView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, -1); } public IndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs, defStyleAttr); } private void init(Context context, AttributeSet attrs, int defStyleAttr) { this.context = context; valueAnimator = ValueAnimator.ofFloat(0, 1f); valueAnimator.setDuration(200); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { value = (float) animation.getAnimatedValue(); postInvalidate(); } }); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.IndicatorView); indiHeight = (int) typedArray.getDimension(R.styleable.IndicatorView_indi_height, getResources().getDimension(R.dimen.dp4)); indiWidth = (int) typedArray.getDimension(R.styleable.IndicatorView_indi_width, getResources().getDimension(R.dimen.dp4)); indiDivide = (int) typedArray.getDimension(R.styleable.IndicatorView_indi_divier, getResources().getDimension(R.dimen.dp4)); normalColor = typedArray.getColor(R.styleable.IndicatorView_indi_color, Color.parseColor("#66dddddd")); selectColor = typedArray.getColor(R.styleable.IndicatorView_indi_color_select, Color.parseColor("#eedddddd")); mode = typedArray.getInteger(R.styleable.IndicatorView_indi_mode, 0); curPosition = 0; count = 0; paint = new Paint(); paint.setAntiAlias(true); paint.setColor(normalColor); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); width = indiWidth * count + (count - 1) * indiDivide;//每个的宽度加上中间间距的宽度 height = indiHeight; setMeasuredDimension(width, height); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); for (int i = 0; i < count; i++) { int x = i * (indiDivide + indiWidth); if (mode == 0) { paint.setColor(normalColor); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { canvas.drawRoundRect(x, 0, x + indiWidth, indiHeight, indiHeight / 2, indiHeight / 2, paint); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (curPosition == i) { paint.setColor(selectColor); if (curPosition > lastPosition) { canvas.drawRoundRect(x, 0, x + value * indiWidth, indiHeight, indiHeight / 2, indiHeight / 2, paint); } else { canvas.drawRoundRect(x + (1 - value) * indiWidth, 0, x + indiWidth, indiHeight, indiHeight / 2, indiHeight / 2, paint); } } } if (mode == 1) { paint.setColor(normalColor); canvas.drawRect(x, 0, x + indiWidth, indiHeight, paint); if (curPosition == i) { paint.setColor(selectColor); if (curPosition > lastPosition) { canvas.drawRect(x, 0, x + value * indiWidth, indiHeight, paint); } else { canvas.drawRect(x + (1 - value) * indiWidth, 0, x + indiWidth, indiHeight, paint); } } } } } } }
在Activity中使用
banner.setAdapter(new Banner.BannerAdapter(strings, this) { @Override protected void setView(View inflate, int position) { ImageView img = inflate.findViewById(R.id.img); Glide.with(MainActivity.this).load(strings.get(position)) .apply(new RequestOptions().centerCrop()) .into(img); } @Override protected int getLayout() { return R.layout.img; // return 0; } });
加载全部内容