Android自定义轮播图效果

本文实例为大家分享了Android自定义轮播图效果的具体代码,供大家参考,具体内容如下
概述
【Android自定义轮播图效果】1、写一个布局,其中有ViewPager,TextView,LinearLayout.

  • ViewPager:用来承载图片
  • TextView:用来展示文字描述
  • LinearLayout:用来展示指示器
2、自定义ConstraintLayout, 在该控件中处理页面切换逻辑等.
分析
1、获取自定义属性以及设置一些属性
public BannerY(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr); initView(context); initXmlParams(context, attrs, defStyleAttr); fixParams(); initListener(); initLists(); initImageLoader(); }/** * 初始化ImageLoader */private void initImageLoader() {ImageLoader.getInstance().init(ImageLoaderConfiguration.createDefault(mContext)); }/** * 将布局填充进BannerY,获取VP,TextView,LinearLayout控件 * * @param context */private void initView(Context context) {mContext = context; LayoutInflater.from(context).inflate(R.layout.layout_banner, this); mVp = (ViewPager) findViewById(R.id.vp); mTvDesc = (TextView) findViewById(R.id.tv_desc); mLLPoint = (LinearLayout) findViewById(R.id.ll_point); }/** * 获取自定义属性 * * @param context * @param attrs * @param defStyleAttr */private void initXmlParams(Context context, AttributeSet attrs, int defStyleAttr) {TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.BannerY, defStyleAttr, 0); mPointSize = typedArray.getDimensionPixelSize(R.styleable.BannerY_point_size, 8); mPointBG = typedArray.getResourceId(R.styleable.BannerY_point_bg, R.drawable.point_selector); mInterval = typedArray.getInteger(R.styleable.BannerY_banner_interval, 2000); mTvBottomMargin = typedArray.getDimensionPixelSize(R.styleable.BannerY_desc_bottom_margin, 8); mPointBottomMargin = typedArray.getDimensionPixelSize(R.styleable.BannerY_point_bottom_margin, 8); mDescColor = typedArray.getColor(R.styleable.BannerY_desc_color, Color.BLACK); mDescSize = typedArray.getDimensionPixelSize(R.styleable.BannerY_desc_size, 14); mScaleType = typedArray.getInt(R.styleable.BannerY_banner_scaletype, -1); typedArray.recycle(); }/** * 通过自定义属性调整指示器与文字描述位置 */private void fixParams() {//描述控件LayoutParams mTvDescLayoutParams = (LayoutParams) mTvDesc.getLayoutParams(); mTvDescLayoutParams.bottomMargin = (int) mTvBottomMargin; mTvDesc.setLayoutParams(mTvDescLayoutParams); mTvDesc.setTextColor(mDescColor); mTvDesc.getPaint().setTextSize(mDescSize); //指示器LayoutParams mLLPointLayoutParams = (LayoutParams) mLLPoint.getLayoutParams(); mLLPointLayoutParams.bottomMargin = (int) mPointBottomMargin; mLLPoint.setLayoutParams(mLLPointLayoutParams); }/** * 创建数据源集合以及创建Handler对象 */@SuppressLint("HandlerLeak")private void initLists() {mImageViewList = new ArrayList<>(); mDescList = new ArrayList<>(); mHandler = new Handler(Looper.getMainLooper()) {@Overridepublic void handleMessage(@NonNull Message msg) {super.handleMessage(msg); // 获取ViewPager当前展示图片的索引值int currentItem = mVp.getCurrentItem(); // 切换到下一个图片mVp.setCurrentItem(currentItem + 1); // 间隔一定时间发送一个消息,间隔时长由自定义属性值控制.mHandler.sendEmptyMessageDelayed(1, mInterval); }}; }/** * 为ViewPager设置滑动监听 */private void initListener() {mVp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}@Overridepublic void onPageSelected(int position) {// ViewPager总共设置有Integer.MAX_VALUE个视图// position取模,转换为mImageViewList对应的索引.int realPosition = position % mImageViewList.size(); if (mDescList.size() == mImageViewList.size()) {// 文字描述集合与图片集合长度相等,那么就为文字描述TextView展示对应的文字内容.String desc = mDescList.get(realPosition); mTvDesc.setText(desc); } else {if (BuildConfig.DEBUG) {Log.d(TAG, "文字集合和图片集合长度不相等"); }}// 上一个页面对应的指示器设置为没有选中mLLPoint.getChildAt(prePosition).setEnabled(false); // 从装有指示器的LinearLayout中获得当前视图对应的指示器,然后设置指示器当前是选中,从而改变指示器颜色.mLLPoint.getChildAt(realPosition).setEnabled(true); prePosition = realPosition; }@Overridepublic void onPageScrollStateChanged(int state) {if (state == ViewPager.SCROLL_STATE_DRAGGING) {//正在滑动// 手动触碰ViewPager,使之正在处于滑动状态,Handler就停止发送消息.isDragging = true; mHandler.removeCallbacksAndMessages(null); }if (state == ViewPager.SCROLL_STATE_IDLE && isDragging) {//空闲状态// ViewPager手动滑动停止之后,重新开启Handler发送消息.mHandler.removeCallbacksAndMessages(null); mHandler.sendEmptyMessageDelayed(1, mInterval); }}}); }

2、设置图片源集合
/** * 设置图片源 * @param imagesRes * @param */public void setImagesRes(ArrayList imagesRes) {if (judgeLenght(imagesRes)) {mImageViewList.clear(); // 初始化图片列表initImageList(imagesRes); // 创建AdaptermBannerAdapter = new BannerAdapter(mImageViewList); mVp.setAdapter(mBannerAdapter); // 设置ViewPager当前视图为中间位置, 因为ViewPager视图个数为Integer.MAX_VALUE(在ViewPagerAdapter中设置的).int position = Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % mImageViewList.size(); // 设置当前ViewPager展示哪个视图mVp.setCurrentItem(position); // 开启消息循环mHandler.sendEmptyMessageDelayed(1, mInterval); if (mDescList.size() == mImageViewList.size()) {// 设置文字描述展示mTvDesc.setText(mDescList.get(prePosition)); }}}/** * 初始化图片列表 */private void initImageList(ArrayList imagesRes) {Class imageResClass = imagesRes.get(0).getClass(); for (int i = 0; i < imagesRes.size(); i++) {// 创建ImageViewImageView imageView = createImageView(imagesRes, i, imageResClass); // 为ImageView设置点击事件setImageViewListener(imageView); // 将ImageView添加进集合中mImageViewList.add(imageView); //添加指示器addPoint(i); }}/** * 根据参数创建ImageView对象 * * @param imagesRes * @param i * @param imageResClass * @return */private ImageView createImageView(ArrayList imagesRes, int i, Class imageResClass) {ImageView imageView = new ImageView(mContext); ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); imageView.setLayoutParams(layoutParams); ImageView.ScaleType scaleType = sScaleTypeArray[mScaleType]; imageView.setScaleType(scaleType); if (imageResClass.equals(String.class)) {// 假如图片数据源集合是url,网址图片String url = (String) imagesRes.get(i); // 使用ImageLoader将图片展示到ImageView中ImageLoader.getInstance().displayImage(url, imageView); } else if (imageResClass.equals(Integer.class)) {// 假如图片数据源集合是图片资源IDInteger resId = (Integer) imagesRes.get(i); imageView.setImageResource(resId); }return imageView; }/** * 为ImageView对象设置点击事件和触摸事件 * * @param imageView */@SuppressLint("ClickableViewAccessibility")private void setImageViewListener(ImageView imageView) {imageView.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:// 当手指在ImageView下按下,那么停止handler发送切换图片的消息mHandler.removeCallbacksAndMessages(null); break; case MotionEvent.ACTION_UP:// 当手指抬起,正常发送切换图片消息.mHandler.removeCallbacksAndMessages(null); mHandler.sendEmptyMessageDelayed(1, mInterval); break; }return false; }}); imageView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (mIClickBanner != null) {// 当点击ImageView时,通过getTage()获取图片当前对应的视图索引值.// 该值是在ViewPagerAdapter中的instantiateItem()中设置的.int positon = (int) v.getTag(); int i = positon % mImageViewList.size(); mIClickBanner.click(i); } else {if (BuildConfig.DEBUG) {Log.e(TAG, "图片回调方法为不存在"); }}}}); }

3、BannerY的Adapter
public class BannerAdapter extends PagerAdapter {private final static String TAG = BannerAdapter.class.getName(); ArrayList mImageViewList; /*** @param mImageViewList ImageView 控件列表,该列表中中的IamgeView都设置了图片资源还有点击事件等.*/public BannerAdapter(ArrayList mImageViewList) {this.mImageViewList = mImageViewList; }@Overridepublic int getCount() {// 设置ViewPager的视图个数,Integer.MAX_VALUE是一个非常大的数字, 不管轮询多久都很难到尽头.return Integer.MAX_VALUE; }@SuppressLint("ClickableViewAccessibility")@NonNull@Overridepublic Object instantiateItem(@NonNull ViewGroup container, final int position) {// position这个数字很大, 取模之后就能够对应mImageViewList集合中的索引值了.final int realPosition = position % mImageViewList.size(); ImageView imageView = mImageViewList.get(realPosition); // 将索引值与ImageView绑定,当被点击的时候可以取出该索引值.imageView.setTag(position); ViewParent viewParent = imageView.getParent(); if (viewParent != null) {// 这里是防止ViewPager重复添加图片.((ViewGroup) viewParent).removeView(imageView); }// 将图片添加进ViewPager中container.addView(imageView); return imageView; }@Overridepublic boolean isViewFromObject(@NonNull View view, @NonNull Object object) {return view == object; }@Overridepublic void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {}}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    推荐阅读