自定义轮播图HeadView

来源:互联网 发布:有趣的标语 知乎 编辑:程序博客网 时间:2024/06/16 09:30
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
原创粉丝点击