您现在的位置是:首页 > 正文

使用RxJava打造无限轮播图

2024-01-30 22:36:36阅读 0

最近项目使用到无限录播图,打造无限轮播图有2种方式,其中一种是在adpater中返回Ingeger.MaxValue,让viewPager无限轮播起来以前都是使用handler来发消息,此次打造轮播图使用全新到方法,通过在需要轮播到列表的头部添加最后一张图片,列表的尾部添加第一张图片来达到无限循环,使用RxJava的interval来实现不断的循环播放,图片按下停止轮播,抬起继续轮播,切到其它页面停止轮播,实现了图片的点击事件,具体效果图如下:

效果图:


HomeFragment.java

package com.cool.patrol.home;

import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;

import com.cool.patrol.R;
import com.cool.patrol.common.base.BasePatrolFragment;
import com.cool.patrol.home.adapter.HomeCarouseAdapter;
import com.cool.patrol.home.bean.CarouselBean.DataBean.PictureUrlBean;
import com.cool.patrol.home.bean.PatrolBeanNet;
import com.cool.patrol.home.contract.HomeContract;
import com.cool.patrol.home.presenter.HomePresenterImpl;
import com.cool.patrol.utils.LogUtils;
import com.cool.sleepgodlibrary.utils.UIUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.ButterKnife;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.subscriptions.CompositeSubscription;

/**
 * Created by cool on 2017/3/17.
 */

public class HomeFragment extends BasePatrolFragment implements HomeContract.HomeView, ViewPager.OnPageChangeListener, View.OnTouchListener {

    @BindView(R.id.vp_carouse)
    ViewPager mCarouseViewPager;

    @BindView((R.id.ll_point_container))
    LinearLayout mPointContainerLinearLayout;

    private HomePresenterImpl mHomePresenter;
    private List<String> mOriginalImages = new ArrayList<>();//轮播图图片url集合
    private List<String> mNeedCarouseImages = new ArrayList<>();//实现无限轮播处理后的轮播图片url集合
    private HomeCarouseAdapter mHomeCarouseAdapter;
    private CompositeSubscription msubscription;//管理所有的订阅
    private int mCurrentItem = 1;
    private boolean mIsTouch = false;
    private List<View> mPointViews = new ArrayList<>();//游标点的view集合

    @Override
    public int setLayoutResID() {
        return R.layout.fragment_home;
    }

    @Override
    protected void initView() {
        ButterKnife.bind(this, mView);
        mHomePresenter = new HomePresenterImpl(this);
        this.msubscription = new CompositeSubscription();
        initViewPager();
    }

    @Override
    public void initData() {
        mHomePresenter.getCarouselImage();
    }

    @Override
    public void onResume() {
        super.onResume();

    }

    private void initViewPager() {
        mHomeCarouseAdapter = new HomeCarouseAdapter(mContext, mNeedCarouseImages);
        mCarouseViewPager.setAdapter(mHomeCarouseAdapter);
    }

    @Override
    public void initListener() {
        mCarouseViewPager.addOnPageChangeListener(this);
        mCarouseViewPager.setOnTouchListener(this);
    }

    
    /事件回调

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

    }

    @Override
    public void onPageSelected(int position) {
        for (int i = 0; i < mPointViews.size(); i++) {
            View pointView = mPointViews.get(i);
            if (position == i + 1) {
                pointView.setBackground(getResources().getDrawable(R.drawable.shape_point_select));
            } else {
                pointView.setBackground(getResources().getDrawable(R.drawable.shape_point_normal));
            }
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {
       
        switch (state) {
            case ViewPager.SCROLL_STATE_IDLE:
             
                if (mCarouseViewPager.getCurrentItem() == 0) {
                    mCarouseViewPager.setCurrentItem(mOriginalImages.size(), false);
                } else if (mCarouseViewPager.getCurrentItem() == mOriginalImages.size() + 1) {
                    mCarouseViewPager.setCurrentItem(1, false);
                }
                mCurrentItem = mCarouseViewPager.getCurrentItem();
                mIsTouch = false;
                break;
            case ViewPager.SCROLL_STATE_DRAGGING:
                mIsTouch = true;
                break;
        }
    }

    int flag;
    long downTime;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mIsTouch = true;
                flag = 0;
                downTime = System.currentTimeMillis();
                break;
            case MotionEvent.ACTION_MOVE:
                flag = 1;
                break;
            case MotionEvent.ACTION_UP:
                mIsTouch = false;
                long dTime = System.currentTimeMillis() - downTime;
                if (dTime < 500 && flag == 0) {
                    onViewPagerItemClick();
                }
                break;
        }
        return false;
    }


    /**
     * ViewPager Item点击事件
     */
    private void onViewPagerItemClick() {
        if (mNeedCarouseImages != null && mNeedCarouseImages.size() > 0)
            showToast(mNeedCarouseImages.get(mCurrentItem));
    }
    

    
    /HomeView的方法//
    @Override
    public void refreshViewPager(final List<PictureUrlBean> pictureUrl) {
        Observable.from(pictureUrl)
                .doOnSubscribe(new Action0() {
                    @Override
                    public void call() {
                        mOriginalImages.clear();//每次接受数据前先清空数据
                        mNeedCarouseImages.clear();
                    }
                })
                .flatMap(new Func1<PictureUrlBean, Observable<String>>() {
                    @Override
                    public Observable<String> call(PictureUrlBean pictureUrlBean) {
                        return Observable.just(pictureUrlBean.pictureurl);
                    }
                })
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        mNeedCarouseImages.addAll(mOriginalImages);
                        mNeedCarouseImages.add(0, mOriginalImages.get(mOriginalImages.size() - 1));
                        mNeedCarouseImages.add(mNeedCarouseImages.size(), mOriginalImages.get(0));
                        mHomeCarouseAdapter.notifyDataSetChanged();
                        mCarouseViewPager.setCurrentItem(mCurrentItem, false);
                        addPointerIndicator();//添加小圆点
                        startCarouse();
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String url) {
                        mOriginalImages.add(url);
                    }
                });
    }

    @Override
    public void loadDataSuccess(PatrolBeanNet.PatrolBean patrolBean) {

    }

    @Override
    public void loadDataFail(String msg) {
        showToast(msg);
    }
    

    
    /自己的方法//

    /**
     * 添加小圆点到容器中
     */
    private void addPointerIndicator() {
        mPointContainerLinearLayout.removeAllViews();
        mPointViews.clear();
        for (int i = 0; i < mOriginalImages.size(); i++) {
            View pointView = new View(mContext);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(UIUtils.dp2px(mContext, 10), UIUtils.dp2px(mContext, 10));
            if (i == 0 && mCurrentItem == 1) {
                pointView.setBackground(getResources().getDrawable(R.drawable.shape_point_select));
            }else if(i == mCurrentItem -1){
                pointView.setBackground(getResources().getDrawable(R.drawable.shape_point_select));
                layoutParams.leftMargin = UIUtils.dp2px(mContext, 5);
            } else {
                pointView.setBackground(getResources().getDrawable(R.drawable.shape_point_normal));
                layoutParams.leftMargin = UIUtils.dp2px(mContext, 5);
            }
            mPointViews.add(pointView);
            mPointContainerLinearLayout.addView(pointView, layoutParams);
        }
    }


    /**
     * 开始轮播
     */
    private void startCarouse() {
        Subscription subscribe = Observable.interval(4, 4, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                        if (!mIsTouch) {
                            mCurrentItem++;
//                            LogUtils.e(aLong.toString() + " mCurrentItem: " + mCurrentItem);
                            mCarouseViewPager.setCurrentItem(mCurrentItem);
                        }
                    }
                });
        msubscription.add(subscribe);
    }

    

    @Override
    public void onPause() {
        super.onPause();
        //在activity结束生命周期的时候取消订阅,解除对context的引用
        if (msubscription != null) {
            this.msubscription.unsubscribe();
        }
    }
}


fragment_home.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="200dp">

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

        </android.support.v4.view.ViewPager>

        <LinearLayout
            android:id="@+id/ll_point_container"
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:layout_alignParentBottom="true"
            android:gravity="center"
            android:orientation="horizontal">

        </LinearLayout>
    </RelativeLayout>
</LinearLayout>



shape_point_normal.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@color/transparent_black"/>
    <size android:width="10dp" android:height="10dp"/>
</shape>


shape_point_select.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@color/white"/>
    <size android:width="10dp" android:height="10dp"/>
</shape>


HomeCarouseAdapter.java

package com.cool.patrol.home.adapter;

import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.cool.patrol.R;

import java.util.List;

/**
 * Created by cool on 2017/3/27.
 */

public class HomeCarouseAdapter extends PagerAdapter {
    private Context mContext;
    private List<String> mImages;
    private boolean isShowLocalDefaultImg = false;

    public HomeCarouseAdapter(Context context, List<String> images) {
        this.mContext = context;
        this.mImages = images;
    }

    @Override
    public int getCount() {
        if(mImages != null && mImages.size() >0){
            isShowLocalDefaultImg = false;
            return mImages.size();
        }
        isShowLocalDefaultImg = true;
        return 1;
    }

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

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.item_carouse, null);
        ImageView mCarouseImageView = (ImageView) view.findViewById(R.id.iv_carouse);
        if(isShowLocalDefaultImg){
            mCarouseImageView.setImageResource(R.drawable.carouse_default);
        }else {
            String url = mImages.get(position);
            Glide.with(mContext).load(url).into(mCarouseImageView);
        }
        ViewParent parent = view.getParent();
        if(parent != null){
            ViewGroup viewGroup = (ViewGroup) parent;
            viewGroup.removeView(view);
        }
        container.addView(view);
        return view;
    }

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


item_carouse.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/iv_carouse"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:src="@drawable/meinv"
        android:scaleType="centerCrop"/>
</LinearLayout>


网站文章