动态轮播图,支持gif动态轮播

     上一篇写过一个轮播图,但上篇有一点遐思, 要是动图的话, 会有那么一点卡顿, 这对app来说那是不能忍的, 这篇介绍一下另一个轮播View,这个呢比较实用, 但是没有滑动动画的效果, 可谓是有利也有弊吧。 当然如果你既想要滑动动画效果又想支持gif图, 那么就要研究一下了, 我是够用了。 如果你有好的方法 或者 图片加载框架 或者一些其他的途径请@我

这篇介绍一下另一个轮播View,这个呢比较实用, 但是没有滑动动画的效果,下面就来看一看

新建一个自定义的可滚动的viewpager

/**
 * 自定义的可滚动的viewpager
 */
@SuppressLint({"HandlerLeak", "ViewConstructor"})
public class CarouselDiagramViewPager<T> extends ViewPager {

}

这里这个泛型倒是无所谓的  只是一个数据类型,使用的时候可以用实体类直接代替

/**
     * 1、要想重新刷新数据,首先拿到集合之前要清空之前的集合数据  刷新数据
     * 2、拿到之后根据集合的大小去初始化视图下面的标记,在初始化viewpager
     * 3、添加视图,刷新视图 view.addView();
     */
    public CarouselDiagramViewPager(Context context) {
        super(context);
        this.mContext = context;
        this.mDatas = new ArrayList<>();
        mAdapter = new CarouselPagerAdapter<>(mContext);
        this.setAdapter(mAdapter);
        initView();
    }

    /**
     * @param data 这里泛型可以用做实体类, 可以在具体列表适配器里面修改实体类的具体类型
     */
    public void addData(List<T> data) {
        if (data == null || data.size() == 0) return;
        mDatas.clear();
        mDatas.addAll(data);
        mAdapter.addData(mDatas);     // 添加数据之前要先清空集合
        initSelected();               // 重新初始化下面标点
        initData();
    }

    // 初始化视图下边的标点
    public void initView() {
        mLayoutScrollView = View.inflate(mContext, R.layout.layout_roll_viewpager, null);
        mViewpagerContainer = (LinearLayout) mLayoutScrollView.findViewById(R.id.ll_viewpager_container);
        mLayoutPoint = (LinearLayout) mLayoutScrollView.findViewById(R.id.ll_dots);
    }

    // 初始化下面标点
    public void initSelected() {
        initPoint(mLayoutPoint);
        mViewpagerContainer.removeAllViews();
        mViewpagerContainer.addView(this);
        mCurrentPosition = mDatas.size() * 1000;
        this.setCurrentItem(mCurrentPosition);
        startScroll();
    }

    // 返回初始化之后的视图
    public View getContentView() {
        return mLayoutScrollView;
    }

一般的轮播图都是在首页的, 也有在其他页面的, 这种页面大多数还是会有下拉刷新的功能,我是直接动态添加这个轮播图,也方便下拉刷新数据。

 

下面这个就是 layout_roll_viewpager 布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <!-- 放置轮播图片位置 -->
    <LinearLayout
        android:id="@+id/ll_viewpager_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:layout_alignParentBottom="true"
        android:background="#00000000"
        android:gravity="center"
        android:orientation="vertical" >

        <!-- 放置图片标题的位置 -->
        <TextView
            android:id="@+id/top_news_title"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="8dp"
            android:layout_weight="1"
            android:singleLine="true"
            android:text="图片标题"
            android:visibility="gone"
            android:textColor="@android:color/darker_gray" />

        <!-- 放置图片中选中点的位置 -->

        <LinearLayout
            android:id="@+id/ll_dots"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:orientation="horizontal" />

    </LinearLayout>

</RelativeLayout>

这个布局就是轮播的容器了, 上面是放置图片的地方, 下面是指示器 我这个是用 点 来标记, 也可以在下方或者其他的地方放置这个轮播图的标题,这个看需求了。

 

初始化指示器的点之后就是ViewPager的 也就是实现滚动的方法

/**
     * 初始化指示器的点
     */
    private void initPoint(LinearLayout point) {
        point.removeAllViews();
        mListPoint = new ArrayList<>();
        for (int i = 0; i < mDatas.size(); i++) {
            View view = new View(mContext);
            view.setBackgroundResource(i == 0 ? R.drawable.dot_focus : R.drawable.dot_normal);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(Utils.dip2px(mContext, 6),
                    Utils.dip2px(mContext, 6));
            if (i == (mDatas.size() - 1)) {
                params.setMargins(Utils.dip2px(mContext, 4), 0, 0, 0);
            } else {
                params.setMargins(Utils.dip2px(mContext, 4), 0, Utils.dip2px(mContext, 4), 0);
            }
            view.setLayoutParams(params);
            point.addView(view);
            mListPoint.add(view);
        }
    }

    // 初始化viewPager
    private void initData() {
        mRunnableTask = new RunnableTask();
        this.addOnPageChangeListener(new OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                if (mDatas == null || mDatas.size() == 0) return;
                mCurrentPosition = position;
                position = position % mDatas.size();
                for (int i = 0; i < mDatas.size(); i++) {
                    if (position == i) {
                        CarouselDiagramViewPager.this.mListPoint.get(i).setBackgroundResource(R.drawable.dot_focus);
                    } else {
                        CarouselDiagramViewPager.this.mListPoint.get(i).setBackgroundResource(R.drawable.dot_normal);
                    }
                }
            }

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

这些之后还要重写一下触摸事件

@Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                this.getParent().requestDisallowInterceptTouchEvent(true);
                downX = (int) ev.getX();
                downY = (int) ev.getY();
                stopScroll();
                break;
            case MotionEvent.ACTION_MOVE:
                int moveX = (int) ev.getX();
                int moveY = (int) ev.getY();
                if (Math.abs(moveX - downX) > Math.abs(moveY - downY)) {
                    this.getParent().requestDisallowInterceptTouchEvent(true);
                } else {
                    this.getParent().requestDisallowInterceptTouchEvent(false);
                }
                break;
            case MotionEvent.ACTION_UP:
                startScroll();
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    protected void onDetachedFromWindow() {
        stopScroll();
        super.onDetachedFromWindow();
    }

到这这个自定义可滚动的View就完成了,剩下的在PagerAdapter 

public class CarouselPagerAdapter<T> extends PagerAdapter {

    private Context mContext;
    private List<T> mData;
    private OnItemViewPagerClickListener mOnItemClickListener;

    public CarouselPagerAdapter(Context context){
        mContext = context;
        mData = new ArrayList<>();
    }

    public void setOnItemViewPagerClickListener(OnItemViewPagerClickListener onItemClick){
        this.mOnItemClickListener = onItemClick;
    }

    // 添加数据 在添加数据之前要先清空集合
    public void addData(List<T> data) {
        clear();
        mData.addAll(data);
        notifyDataSetChanged();
    }

    public void clear() {
        if (mData != null){
            mData.clear();
        }
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return mData.size() * 2000;
    }

    @Override
    public Object instantiateItem(ViewGroup container, final int position) {
        if (mData == null || mData.size() == 0) return null;
        final int newPosition = position % mData.size();
        View view = View.inflate(mContext, R.layout.item_carousel_poster, null);
        GifImageView imageView = view.findViewById(R.id.iv);
        final String url = (String) mData.get(newPosition);
        // 截取字符串网址后三位 (判断是否等于gif图) 如果等于转换成字节设置
        if (url.substring(url.length() - 3).equals("gif")) {
            try {
                byte[] bytes = new GifDataAsyncTask().execute(url).get();
                if (bytes != null) {
                    imageView.setBytes(bytes);
                    imageView.startAnimation(); //开始动画 (没有动画会不显示图片 或者 图片静态不会动)
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        } else {
            Picasso.with(mContext).load(url).into(imageView);
        }
        container.addView(view);
        view.setOnTouchListener(new View.OnTouchListener() {
            private int downX;
            private long downTime;
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        downX = (int) event.getX();
                        downTime = System.currentTimeMillis();
                        break;
                    case MotionEvent.ACTION_UP:
                        int upX = (int) event.getX();
                        long upTime = System.currentTimeMillis();
                        if (downX == upX && upTime - downTime < 500) {
                            if (mOnItemClickListener != null) {
                                mOnItemClickListener.onItemClick(url, newPosition);
                            }
                        }
                        break;
                    case MotionEvent.ACTION_CANCEL:
                        break;
                }
                return true;
            }
        });
        return view;
    }

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

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

使用很简单

​
mViewPager = new CarouselDiagramViewPager<>(this);
// mLinearLayout是放置这个可滚动的容器
mLinearLayout.addView(mViewPager.getContentView());

// 添加数据
mViewPager.addData(data);
// 点击事件
mViewPager.setOnItemViewPagerClickListener(new OnItemViewPagerClickListener() {
            @Override
            public <T> void onItemClick(T data, int position) {
                Toast.makeText(MainActivity.this, "点击第" + position+ "条", Toast.LENGTH_SHORT).show();
            }
        });

​

体验的直接可下载demo

地址:https://github.com/xiaobinAndroid421726260/Android_SnowBanner2019_11_5Demo.git

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值