recyclerview轮播

/** 传智轮播方式 */
private CountDownTimer mCountDownTimer;
private boolean mFlagInterceptPlay = false;
private int mFingerUpTime;

private List<BannerBean> mDatas = new ArrayList<>();
private ArrayList<ImageView> mIcons = new ArrayList<>();
private int previousSelectedPosition = 0;

@SuppressLint("ClickableViewAccessibility") private void itcast() {
    /** 初始化数据 */
    mDatas.add(new BannerBean(R.drawable.start_indicator_1, "我的大刀早已饥渴难耐了"));
    mDatas.add(new BannerBean(R.drawable.start_indicator_2, "敌军还有30秒到达战场"));
    mDatas.add(new BannerBean(R.drawable.start_indicator_3, "你也想来一发嘛"));
    mDatas.add(new BannerBean(R.drawable.start_indicator_4, "人在塔在"));


    /** ViewPager事件-->触摸时禁止滚动 */
    mBinding.vpAd.setOnTouchListener((view, motionEvent) -> {
        switch(motionEvent.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mFlagInterceptPlay = true;
                break;

            case MotionEvent.ACTION_UP:
                mFlagInterceptPlay = false;
                mFingerUpTime = (int) System.currentTimeMillis();
                break;
        }
        return false;
    });
    /* 滚动时更新轮播图、title、指示器状态 */
    mBinding.vpAd.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }

        @Override public void onPageSelected(int position) {
            int newPosition = position % mIcons.size();
            mBinding.tvAdTitle.setText(mDatas.get(newPosition).getTitle());
            mBinding.llPoints.getChildAt(previousSelectedPosition).setBackgroundResource(R.drawable.shape_package_indicator_normal);
            mBinding.llPoints.getChildAt(newPosition).setBackgroundResource(R.drawable.shape_package_indicator_fouse);
            previousSelectedPosition = newPosition;
        }

        @Override public void onPageScrollStateChanged(int state) { }
    });


    /** 初始化所有banner图及对应指示器 */
    ImageView iv_icon;
    View v_point;
    LinearLayout.LayoutParams layoutParams;
    for(int i = 0; i < mDatas.size(); i++) {
        iv_icon = new ImageView(this);
        iv_icon.setBackgroundResource(mDatas.get(i).getIcon());
        mIcons.add(iv_icon);

        v_point = new View(this);
        layoutParams = new LinearLayout.LayoutParams(15, 15);
        if(0 != i) layoutParams.leftMargin = 10;
        v_point.setBackgroundResource(R.drawable.shape_package_indicator_normal);
        mBinding.llPoints.addView(v_point, layoutParams);
    }


    /** adapter */
    mBinding.llPoints.getChildAt(0).setBackgroundResource(R.drawable.shape_package_indicator_fouse);
    mBinding.tvAdTitle.setText(mDatas.get(0).getTitle());
    mBinding.vpAd.setAdapter(new PagerAdapter() {
        @Override public int getCount() {
            return Integer.MAX_VALUE;
        }

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

        @Override public Object instantiateItem(ViewGroup container, int position) {
            int newPosition = position % mIcons.size();
            ImageView iv = mIcons.get(newPosition);
            container.addView(iv);
            return iv;
        }

        @Override public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }
    });
    mBinding.vpAd.setCurrentItem(Integer.MAX_VALUE / 2);


    /** 开启轮播 */
    mCountDownTimer = new CountDownTimer(Integer.MAX_VALUE, 3_000) {
        @Override public void onTick(long millisUntilFinished) {
            if(! mFlagInterceptPlay && (int) System.currentTimeMillis() - mFingerUpTime > 3_000)
                mBinding.vpAd.setCurrentItem(mBinding.vpAd.getCurrentItem() + 1);
        }

        @Override public void onFinish() { }
    };
    mCountDownTimer.start();
}


@Override protected void onDestroy() {
    super.onDestroy();
    if(null != mCountDownTimer) {
        mCountDownTimer.cancel();
        mCountDownTimer = null;
    }
}
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.bumptech.glide.Glide;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.PagerSnapHelper;
import androidx.recyclerview.widget.RecyclerView;

/**
 * Created by catfaceWYH --> tel|wechat|qq 130 128 92925
 */
public class RVBannerView extends FrameLayout {

    /**
     * 当手指触及轮播页则暂停轮播
     */
    @Override public boolean dispatchTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                playerCtrl(false);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                playerCtrl(true);
                break;
        }
        return super.dispatchTouchEvent(event);
    }


    /**
     * 1. 在Handler中重复给自己发送消息即可轮播
     */
    private final int MSG_AUTO_PLAY = -0x99;
    private final int AUTO_PLAY_DURATION = 4_000;   // 每张轮播页显示时长
    private int mCurrentIndex;
    @SuppressLint("HandlerLeak") private Handler mHandler = new Handler() {
        @Override public void handleMessage(Message msg) {
            if (msg.what == MSG_AUTO_PLAY) {
                mRV.smoothScrollToPosition(++mCurrentIndex);
                playerCtrl(true);
            }
        }
    };


    /* 老三样1. RV 2. 适配器 3. 源数据 */
    private RecyclerView mRV;
    private RVBannerAdapter mAdapter;
    private List<String> mDatas = new ArrayList<>();


    public RVBannerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    /**
     * 1. 初始化RecyclerView对象
     * 2. PagerSnapHelper可使RecyclerView滚动后居中对齐
     * 3. 通过LinearLayoutManager设置横向操作
     * 4. 通过滚动监听当前精确的index[防止手势滚动后index位置异常]
     * 5. 将RecyclerView添加进当前布局
     */
    private void init() {
        mRV = new RecyclerView(getContext());
        new PagerSnapHelper().attachToRecyclerView(mRV);
        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
        layoutManager.setOrientation(RecyclerView.HORIZONTAL);
        mRV.setLayoutManager(layoutManager);
        mRV.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                mCurrentIndex = layoutManager.findFirstVisibleItemPosition();
            }
        });
        addView(mRV, new LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
    }


    /**
     * 1. 设置源数据
     * 2. 初始化适配器
     * 3. 将初始轮播页定位至一个较大的数值[为源数据整数倍即可]
     * 4. 发送消息通知Handler开始轮播
     */
    public void play(List<String> datas, OnItemClickListener listener) {
        mDatas = datas;
        mAdapter = new RVBannerAdapter(mDatas, listener);
        mRV.setAdapter(mAdapter);
        mCurrentIndex = datas.size() * 10_000;
        mRV.scrollToPosition(mCurrentIndex);
        playerCtrl(true);
    }

    private void playerCtrl(boolean isStartPlay) {
        if (isStartPlay) {
            mHandler.sendEmptyMessageDelayed(MSG_AUTO_PLAY, AUTO_PLAY_DURATION);
        } else {
            mHandler.removeMessages(MSG_AUTO_PLAY);
        }
    }


    /**
     * 1. 声明轮播页的点击和长按事件接口
     * 2. 轮播页适配器[注意使用余数确定当前页面对应的源数据index]
     */
    public interface OnItemClickListener {
        void onItemClick(int position);

        void onItemLongClick(int position);
    }

    private class RVBannerAdapter extends RecyclerView.Adapter<RVBannerAdapter.ViewHolder> {
        private List<String> mDatas;
        private OnItemClickListener mListener;

        RVBannerAdapter(List<String> datas, OnItemClickListener listener) {
            mListener = listener;
            mDatas = datas;
        }

        @NonNull @Override public RVBannerAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            return new RVBannerAdapter.ViewHolder(new ImageView(parent.getContext()));
        }

        @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
            int realPosition = position % mDatas.size();

            // 可按需替换使用你项目规定的图片加载框架
            Glide.with(getContext()).load(mDatas.get(realPosition)).into(holder.iv);

            if (null != mListener) {
                holder.iv.setOnClickListener(v -> mListener.onItemClick(realPosition));
                holder.iv.setOnLongClickListener(v -> {
                    mListener.onItemLongClick(realPosition);
                    return true;
                });
            }
        }

        @Override public int getItemCount() {
            return Integer.MAX_VALUE;
        }

        class ViewHolder extends RecyclerView.ViewHolder {
            private ImageView iv;

            ViewHolder(@NonNull View itemView) {
                super(itemView);
                iv = (ImageView) itemView;
                RecyclerView.LayoutParams params = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                iv.setLayoutParams(params);
                iv.setScaleType(ImageView.ScaleType.FIT_XY);
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值