栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android recyclerview 无限循环居中并自动向下滚动

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android recyclerview 无限循环居中并自动向下滚动

Android recyclerview 无限循环居中并自动向下滚动

描述:这是一个基于recyclerview实现的 Android 无限循环滚动Demo,可自定义item。

项目代码在最后面!!!!跳转到最后 控件效果如下:

此控件为Android 无限循环居中并可以自动向下滚动。

实现功能:
  • 上下滚动无限循环(跳转回之前相似的postion)
  • 自动滚动
  • 利用flex可进行流式内容布局
设计核心:

主要的设计核心是依赖于recyclerview进行设计的,主要通过重写layoutmanager,Adapter,RecyclerView等来实现

核心代码:

CycleFlexManager .java
根据数量进行高度调整

package com.ui.design.view.automeasurelinear.linearmanager;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.recyclerview.widget.RecyclerView;

import com.google.android.flexbox.FlexboxLayoutManager;


public class CycleFlexManager extends FlexboxLayoutManager {
    private RecyclerView mRecyclerView;
    private int mItemViewHeight = 0;

    public CycleFlexManager(Context context, RecyclerView recyclerView) {
        super(context);

        this.mRecyclerView = recyclerView;
    }

    public CycleFlexManager(Context context, int flexDirection) {
        super(context, flexDirection);
    }

    public CycleFlexManager(Context context, int flexDirection, int flexWrap) {
        super(context, flexDirection, flexWrap);
    }

    public CycleFlexManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    
    @Override
    public void onAttachedToWindow(RecyclerView view) {
        super.onAttachedToWindow(view);
    }


    
    @Override
    public void onScrollStateChanged(int state) {
        super.onScrollStateChanged(state);
        if (state == 0) {

            int topposition = findFirstVisibleItemPosition();
            int lastpostion = findLastCompletelyVisibleItemPosition();
            Log.e("TEST", "findFirstVisibleItemPosition" + topposition);
            Log.e("TEST", "findLastVisibleItemPosition" + lastpostion);

            if (lastpostion > getItemCount() - 5) {//有些View可能转载比较多item 用顶部的postion来指示
                int prepostion = lastpostion - getItemCount() / 2;
                Log.e("TEST", "childconut" + prepostion);
                // View view=findViewByPosition(lastpostion);
                scrollToPosition(prepostion + 1); //找到可视图里第一个postion并让他向前移动一半
            }
            if (topposition == 0) {
                int prepostion = topposition + getItemCount() / 2;
                Log.e("TEST", "childconut" + prepostion);
                scrollToPosition(prepostion-1);
            }
        }
    }

    public int getmItemViewHeight() {
        if (mItemViewHeight==0){
            View view=findViewByPosition(0);
            if (view!=null){
                measureChildWithMargins(view, 0, 0);
                mItemViewHeight = view.getMeasuredHeight();
            }
        }
        return mItemViewHeight;
    }
}

AutoPollRecyclerView .java
自动滚动

package com.ui.design.view.automeasurelinear.recyclerview;


import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;


import com.ui.design.view.automeasurelinear.linearmanager.CycleFlexManager;

import java.lang.ref.WeakReference;


public class AutoPollRecyclerView extends RecyclerView {

    private static final long TIME_AUTO_POLL = 16;
    AutoPollTask autoPollTask;
    private boolean running; //表示是否正在自动轮询
    private boolean canRun;//表示是否可以自动轮询

    public AutoPollRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        autoPollTask = new AutoPollTask(this);
    }

    static class AutoPollTask implements Runnable {
        private final WeakReference mReference;

        //使用弱引用持有外部类引用->防止内存泄漏
        public AutoPollTask(AutoPollRecyclerView reference) {
            this.mReference = new WeakReference<>(reference);
        }

        @Override
        public void run() {
            AutoPollRecyclerView recyclerView = mReference.get();
            if (recyclerView.running && recyclerView.canRun) {
                recyclerView.scrollBy(2, 2);
                if (!recyclerView.canScrollVertically(5)){
                    if (recyclerView.getLayoutManager() instanceof CycleFlexManager){
                            ((CycleFlexManager)recyclerView.getLayoutManager()).onScrollStateChanged(0);//向无限循环manager释放不滚动信号 进行位置迁移
                    }
                }
                recyclerView.postDelayed(recyclerView.autoPollTask, TIME_AUTO_POLL);
            }
        }
    }

    //开启:如果正在运行,先停止->再开启
    public void start() {
        if (running)
            stop();
        canRun = true;
        running = true;
        postDelayed(autoPollTask, TIME_AUTO_POLL);
    }

    public void stop() {
        running = false;
        removeCallbacks(autoPollTask);
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (running)
                    stop();
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_OUTSIDE:
                if (canRun)
                    start();
                break;
        }
        return super.onTouchEvent(e);
    }

    private int cycleNum=4;

    public int getCycleNum() {
        return cycleNum;
    }

    public void setCycleNum(int cycleNum) {
        this.cycleNum = cycleNum;
    }


}

AutoMeasureAdapter.java 在Adapter中将size增加 不然无法实现无限循环滚动

package com.ui.design.view.automeasurelinear.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.alibaba.android.arouter.launcher.ARouter;
import com.ui.design.R;
import com.ui.design.main.bean.SelectorBean;
import com.ui.design.view.pickviewselect.view.PickerLayoutManager;

import java.util.List;


public class AutoMeasureAdapter extends RecyclerView.Adapter {

    private final List mList;
    private final Context mContext;
    private int mCycleNum=8;//长度重复次数 默认为8

    public AutoMeasureAdapter(Context context, List stringList){
        this.mContext=context;
        this.mList=stringList;
    }
    @NonNull
    @Override
    public SViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new SViewHolder(LayoutInflater.from(mContext).inflate(R.layout.automeasure_adapter_item, parent,false));
    }

    @Override

    public void onBindViewHolder(@NonNull SViewHolder holder, int position) {

        if (mList == null || mList.size() == 0) {
            return;
        }
        holder.cardname.setText(mList.get(position % mList.size()));

    }

    @Override
    public int getItemCount() {
        if (mList == null||mList.size()==0) {
            return 0;
        }
        return  mList.size() * mCycleNum;//直接乘
    }

    static class SViewHolder extends RecyclerView.ViewHolder{

        private final TextView cardname;
        public SViewHolder(@NonNull View itemView) {
            super(itemView);
            cardname=(TextView) itemView.findViewById(R.id.card_name);
        }
    }


    public int getmCycleNum() {
        return mCycleNum;
    }

    public void setmCycleNum(int mCycleNum) {
        if (mCycleNum%2==1){
            mCycleNum++;//保证mCycleNum为2的倍数
        }
        this.mCycleNum = mCycleNum;
    }
}

使用示例:

AutomeasureActivity.java

package com.ui.design.view.automeasurelinear;

import androidx.recyclerview.widget.RecyclerView;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.google.android.flexbox.FlexDirection;
import com.google.android.flexbox.JustifyContent;
import com.ui.design.R;
import com.ui.design.main.base.baseActivity;
import com.ui.design.main.constants.Constants;
import com.ui.design.utils.RandomValue;
import com.ui.design.view.automeasurelinear.adapter.AutoMeasureAdapter;
import com.ui.design.view.automeasurelinear.linearmanager.CycleFlexManager;
import com.ui.design.view.automeasurelinear.recyclerview.AutoPollRecyclerView;

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

@Route(path = Constants.AutomeasureActivity)
public class AutomeasureActivity extends baseActivity {

    private List stringList;
    @Override
    protected int initLayout() {
        return R.layout.activity_automeasure;
    }

    @Override
    protected void initView() {

        stringList=new ArrayList<>();

        for (int i=0;i<50;i++){
            stringList.add(RandomValue.getRandomContent());
        }

        AutoPollRecyclerView recyclerView=findViewById(R.id.auto_center);

        CycleFlexManager layoutManager = new CycleFlexManager(this,recyclerView);
        layoutManager.setFlexDirection(FlexDirection.ROW);//可设置排列
        layoutManager.setJustifyContent(JustifyContent.CENTER);//可设置是否居中
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.start();
        AutoMeasureAdapter autoMeasureAdapter = new AutoMeasureAdapter(this,stringList);
        recyclerView.setAdapter(autoMeasureAdapter);

    }

    @Override
    protected void initData() {

    }
}

activity_automeasure.xml




    

    

项目代码仓库

如果直接复制可能会出现代码缺陷,完整代码请去仓库下载
如果觉得还行,耽误您几秒钟的时间去我的仓库点点star,万一以后用到了呢?

UIDesign 开源项目

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/684604.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号