自定义轮播图HeadView

https://github.com/helloworld107/CainiaoMarket
说到轮播图我们都不会陌生,常规的思想是通过listview或者recycerview的判断不同类型来去写轮播图布局并且做出判断,这样有一个缺点就是会增加适配器的代码量和复杂程度,根据高内度,低耦合的思想自然会把轮播图分开,于是listview有了addHeadView,recycerview虽然原生没有但是通过修改也可以达到添加头和尾的功能。下面重点说一下轮播图的实现。
其实轮播图就是一个布局,只不过这个布局一般是动态的可以操作的,所以只要一个类能返回布局并且进行操作即可,并不是四大组件,也不需要自定义控件,就是一个单独的类,下面分析源码
布局很简单,就是一个viewpager,linearlayout用来放置坐标点,如果需要显示文字内容,还可在添加一个半透明的textview
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="160dp">

    <android.support.v4.view.ViewPager
        android:id="@+id/item_home_picture"
        android:layout_width="match_parent"
        android:layout_height="160dp">
    </android.support.v4.view.ViewPager>

    <LinearLayout
        android:id="@+id/item_home_picture_page"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="3dp"
        android:layout_marginRight="10dp"
        android:orientation="horizontal"
        >
    </LinearLayout>
</RelativeLayout>

public class HeadView {

    @InjectView(R.id.item_home_picture)
    ViewPager mItemHomePicture;
    @InjectView(R.id.item_home_picture_page)
    LinearLayout mItemHomePicturePage;
    private List<HeadPicBean> mDatas;
    private Context mContext;
    private int length = 0;
    private View mInflate;


    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (mItemHomePicture != null) {
                int currentItem = mItemHomePicture.getCurrentItem();
                currentItem++;
                mItemHomePicture.setCurrentItem(currentItem);
            }
 轮播图无线循环的技巧之一,也可以通过写一个线程达到目的
            mHandler.removeMessages(0);消除消息这句话一定要执行,放置过多的资源消耗导致oom
            mHandler.sendEmptyMessageDelayed(0, 5000);

        }
    };
//这句话是listview最终需要的结果,既程序的出口
    public View getInflate() {
        return mInflate;
    }

    public HeadView(List<HeadPicBean> datas, Context context) {
        mDatas = datas;//数据得有吧
        mContext = context;
        //原点长度
        length = CommonUtils.dip2px(5, mContext);屏幕适配方法之一,其实就是根据像素,屏幕密度的关系做了一个简单计算
        ;
        initView();//初始化我们的view
        if (mDatas != null) {
            refreshHoldView();//开始轮播吧
        }
    }

    public View initView() {

        mInflate = View.inflate(mContext, R.layout.item_home_picture, null);
        ButterKnife.inject(this, mInflate);
        return mInflate;

    }

    public void refreshHoldView() {

        mItemHomePicture.setAdapter(new PictureAdapter());
        //添加右侧下面的导航标题
        for (int i = 0; i < mDatas.size(); i++) {

            View point = new View(mContext);
            point.setBackgroundResource(R.drawable.white_point);
            //这个params修饰的还是point自己,为了适配,我们还会进行dp转px
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(length, length);
            params.leftMargin = length;
            params.bottomMargin = length;
            mItemHomePicturePage.addView(point, params);

            //默认第一个亮
            if (i == 0) {
                point.setBackgroundResource(R.drawable.red_point);
            }
        }
        //处理点的变化
        mItemHomePicture.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                position = position % mDatas.size();
                //首先全黑,然后再选择对的亮
                for (int i = 0; i < mDatas.size(); i++) {
                    mItemHomePicturePage.getChildAt(i).setBackgroundResource(R.drawable.white_point);
                    if (i == position) {
                        mItemHomePicturePage.getChildAt(i).setBackgroundResource(R.drawable.red_point);
                    }
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        //设置一个中间坐标是为了可以向左滑动
一定要注意为了左右滑动这里的值没必要取integer.max这样非常大的值,因为这样的值再取余数是一个非常复杂的运算,分分钟钟anr,放到子线程都不一定会解决,还有实际用户也不会往左边滑动太多,所以适合就是最好
        int diff = 100 % mDatas.size();
        int index = 100;
        mItemHomePicture.setCurrentItem(index - diff);

        //如果用户点到图片不应该移动吧
        mItemHomePicture.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        mHandler.removeMessages(0);
                        break;
                    case MotionEvent.ACTION_UP:
                        mHandler.sendEmptyMessageDelayed(0,5000);
                        break;
                    case MotionEvent.ACTION_MOVE:
                        break;
                    default:
                        break;
                }
                return false;
            }
        });
        mHandler.sendEmptyMessageDelayed(0,5000);
    }

    class PictureAdapter extends PagerAdapter {

        @Override
        public int getCount() {

            if (mDatas != null) {
                return 1000;
            }
            return 0;

        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {

            ImageView imageView = new ImageView(mContext);
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            //默认位置肯定是从0开始的,取余是防止超出界限引发空指针,如果想左右滑动,就需要先把位置调整到中间
            position = position % mDatas.size();
            Glide.with(mContext).load(mDatas.get(position).getImgUrl()).into(imageView);
            container.addView(imageView);
            return imageView;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }
    }

    public Handler getHandler() {
        return mHandler;
    }
}
之后就可以把轮播图通过listview.addHeadView(new headviwe(数据).getInflate)去用啦,是不是很简单


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值