欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Recycleview實(shí)現(xiàn)無限自動輪播

 更新時(shí)間:2020年07月23日 09:29:17   作者:weixin_43607099  
這篇文章主要為大家詳細(xì)介紹了Recycleview實(shí)現(xiàn)無限自動輪播,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

概述

RecycleView實(shí)現(xiàn)特定數(shù)據(jù)無限重復(fù)滑動在我看來不外乎有兩種方法

1.修改adpter的復(fù)用機(jī)制,無限復(fù)用數(shù)據(jù)
2.在adpter中返回?cái)?shù)據(jù)長度返回Integer的最大值

由于第一種雖然能實(shí)現(xiàn)數(shù)據(jù)的無限重復(fù)但是數(shù)據(jù)位還是沒有任何變化,所以在自動跳轉(zhuǎn)至最后的時(shí)候無法在向下一位輪播,所以在這里我使用第二種方式實(shí)現(xiàn)自動輪播

簡單講述修改adpter的復(fù)用機(jī)制

我們拿LinearLayoutManager線性的為例子,我們只需要重新LinearLayoutManager在繪制的時(shí)候做一些手手腳就可以實(shí)現(xiàn)

package com.li.liproject.recycle;

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

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;

/**
 * @author 版本:1.0
 * 創(chuàng)建日期:2020/4/14 14
 * 描述:
 */
public class ScrollSpeedLinearLayoutManger extends LinearLayoutManager {
 public ScrollSpeedLinearLayoutManger(Context context) {
  super(context);
 }

 public ScrollSpeedLinearLayoutManger(Context context, int orientation, boolean reverseLayout) {
  super(context, orientation, reverseLayout);
 }

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

 @Override
 public RecyclerView.LayoutParams generateDefaultLayoutParams() {
  return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
 }

 // 1 在RecyclerView初始化時(shí),會被調(diào)用兩次。
// 2 在調(diào)用adapter.notifyDataSetChanged()時(shí),會被調(diào)用。
// 3 在調(diào)用setAdapter替換Adapter時(shí),會被調(diào)用。
// 4 在RecyclerView執(zhí)行動畫時(shí),它也會被調(diào)用。
 @Override
 public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
  Log.d("TAG","onLayoutChildren ");
  if (getItemCount() == 0){
   detachAndScrapAttachedViews(recycler);
   return;
  }
  //state.isPreLayout()是支持動畫的
  if (getItemCount() == 0 && state.isPreLayout()){
   return;
  }
  //將當(dāng)前Recycler中的view全部移除并放到報(bào)廢緩存里,之后優(yōu)先重用緩存里的view
  detachAndScrapAttachedViews(recycler);

  int actualHeight = 0;
  for (int i = 0 ;i < getItemCount() ; i++){
   View scrap = recycler.getViewForPosition(i);
   addView(scrap);
   measureChildWithMargins(scrap,0,0);
   int width = getDecoratedMeasuredWidth(scrap);
   int height = getDecoratedMeasuredHeight(scrap);
   layoutDecorated(scrap,0,actualHeight,width,actualHeight+height);
   actualHeight+=height;
   //超出界面的就不畫了,也不add了
   if (actualHeight > getHeight()){
    break;
   }
  }
 }

 @Override
 public boolean canScrollVertically() {
  return true;
 }


 @Override
 public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
  Log.d("feifeifei","getChildCount() " + getChildCount() + " recycler.getScrapList().size() " + recycler.getScrapList().size());

  //界面向下滾動的時(shí)候,dy為正,向上滾動的時(shí)候dy為負(fù)

  //填充
  fill(dy,recycler,state);
  //滾動
  offsetChildrenVertical(dy*-1);

  //回收已經(jīng)離開界面的
  recycleOut(dy,recycler,state);

  return dy;
 }

 private void fill(int dy, RecyclerView.Recycler recycler, RecyclerView.State state){
  //向下滾動
  if (dy > 0){
   //先在底部填充
   View lastView = getChildAt(getChildCount() -1);
   int lastPos = getPosition(lastView);
   if (lastView.getBottom() - dy < getHeight()){
    View scrap;
    if (lastPos == getItemCount() -1){
     scrap = recycler.getViewForPosition(0);
    }else {
     scrap = recycler.getViewForPosition(lastPos+1);
    }
    addView(scrap);
    measureChildWithMargins(scrap,0,0);
    int width = getDecoratedMeasuredWidth(scrap);
    int height = getDecoratedMeasuredHeight(scrap);
    layoutDecorated(scrap,0,lastView.getBottom(),width,lastView.getBottom()+height);
   }
  }else {
   //向上滾動
   //現(xiàn)在頂部填充
   View firstView = getChildAt(0);
   int layoutPostion = getPosition(firstView);

   if (firstView.getTop() >= 0 ){
    View scrap ;
    if (layoutPostion == 0){
     scrap = recycler.getViewForPosition(getItemCount()-1);
    }else {
     scrap = recycler.getViewForPosition(layoutPostion -1);
    }
    addView(scrap,0);
    measureChildWithMargins(scrap,0,0);
    int width = getDecoratedMeasuredWidth(scrap);
    int height = getDecoratedMeasuredHeight(scrap);
    layoutDecorated(scrap,0,firstView.getTop() - height,width,firstView.getTop());
   }
  }
 }

 private void recycleOut(int dy, RecyclerView.Recycler recycler, RecyclerView.State state){
  for (int i = 0 ; i <getChildCount() ;i++){
   View view = getChildAt(i);
   if (dy >0){
    if (view.getBottom()-dy <0){
     Log.d("feifeifei","recycleOut " + i);
     removeAndRecycleView(view,recycler);
    }
   }else {
    if (view.getTop()-dy > getHeight()){
     Log.d("feifeifei","recycleOut " + i);
     removeAndRecycleView(view,recycler);
    }
   }
  }
 }

 @Override
 public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
  RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
  smoothScroller.setTargetPosition(position);
  startSmoothScroll(smoothScroller);
 }

 private class CenterSmoothScroller extends LinearSmoothScroller {
  public CenterSmoothScroller(Context context) {
   super(context);
  }
  protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
   return 0.2f;
  }
 }
}

大概就是這么寫的網(wǎng)格的需要自己重新寫因?yàn)橛?jì)算會有區(qū)別,這里簡單的講述一下

正題

Adpter適配器的實(shí)現(xiàn)

寫法沒什么區(qū)別唯一的getItemCount 和onBindViewHolder要做一下處理大概如下

public class AdAuditorAdapter extends RecyclerView.Adapter<AdAuditorAdapter.MyViewHolder> {
 private Context mContext;
 private List<String> mData;

 public AdAuditorAdapter(Context mContext, List<String> mData) {
  this.mContext = mContext;
  this.mData = mData;
 }

 @NonNull
 @Override
 public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
  MyViewHolder holder = new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_adauditor, viewGroup, false));
  return holder;
 }

 @Override
 public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, @SuppressLint("RecyclerView") int i) {
  Log.e("HHHHHHHHH", "onBindViewHolder: -->"+i );
  //取余否則會出現(xiàn)索引越界
  myViewHolder.tv_1.setText(mData.get(i%mData.size()));
  myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    listener.onClick(v, i%mData.size(), 3);
   }
  });

 }


 @Override
 public int getItemCount() {
 //返回adpter最大值
  return Integer.MAX_VALUE;
 }

 public void update(List<String> list) {
  this.mData = list;
  notifyDataSetChanged();
 }

 class MyViewHolder extends RecyclerView.ViewHolder {
  TextView tv_1;


  public MyViewHolder(@NonNull View itemView) {
   super(itemView);

   tv_1 = itemView.findViewById(R.id.tv_1); //ID

  }
 }

 public MyClickListener getListener() {
  return listener;
 }

 public void setMyClickListener(MyClickListener listener) {
  this.listener = listener;
 }

 MyClickListener listener;

 public interface MyClickListener {
  void onClick(View view, int position, int type);
 }

 public List<String> getData() {
  return mData;
 }
}

activity的實(shí)現(xiàn)

1基本實(shí)現(xiàn)

1.1 添加假數(shù)據(jù)寫好點(diǎn)擊事件
1.2 用handler延遲發(fā)消息 mRecyclerView.smoothScrollToPosition(position);移動到指定位置
1.3 點(diǎn)擊停止移動

2效果優(yōu)化

2.1 添加勻速阻尼效果
2.2 實(shí)現(xiàn)無限輪播考慮數(shù)值超過Integer最大值情況
2.3 點(diǎn)擊正在輪播時(shí)的recycleview會停止輪播,再次點(diǎn)擊才會執(zhí)行點(diǎn)擊事件(優(yōu)化為點(diǎn)擊停止并執(zhí)行點(diǎn)擊事件)
阻尼效果就是減少滑動速率

我們這么做

package com.li.liproject.recycle;

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

import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;

/**
 * @author 版本:1.0
 * 創(chuàng)建日期:2020/4/14 14
 * 描述:
 */
public class ScrollSpeedGridLayoutManager1 extends GridLayoutManager {


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

 public ScrollSpeedGridLayoutManager1(Context context, int spanCount) {
  super(context, spanCount);
 }

 public ScrollSpeedGridLayoutManager1(Context context, int spanCount, int orientation, boolean reverseLayout) {
  super(context, spanCount, orientation, reverseLayout);
 }


 @Override
 public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
  RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
  smoothScroller.setTargetPosition(position);
  startSmoothScroll(smoothScroller);
 }

 private class CenterSmoothScroller extends LinearSmoothScroller {
  public CenterSmoothScroller(Context context) {
   super(context);
  }
  protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
   return 10f;//滑動速率問題
  }
 }
}

activity全部代碼

package com.li.liproject.recycle;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.li.liproject.MainActivity;
import com.li.liproject.R;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 版本:1.0
 * 創(chuàng)建日期:2020/4/14 14
 * 描述:
 */
public class RecycleViewActivity extends AppCompatActivity {
 static RecyclerView rv_1;
 private static int HANDLER_MSG = 0x0011;
 private static int HANDLER_LONG_MSG = 0x0021;
 static int position = 0;
 static int addNum = 3;
 @SuppressLint("HandlerLeak")
 private static Handler handler = new Handler() {
  @Override
  public void handleMessage(@NonNull Message msg) {
   if (msg.what == HANDLER_MSG) {
   // 9宮格效果實(shí)現(xiàn)速率相同
    if (addNum==3){
     position = position + addNum;
     addNum = 6;
    }else {
     position = position + addNum;
     addNum = 3;
    }
    Log.e("TAG", "handleMessage: -->" + position);
    smoothMoveToPosition(rv_1, position >= 0 ? position : 0);
    if (position==Integer.MAX_VALUE/2){
     //點(diǎn)擊或超過2分之Integer.MAX_VALU重置adpter
     LongAutoMove();
    }else {
     AutoMove();
    }

   }else if (msg.what==HANDLER_LONG_MSG){
    position = 0;
    addNum = 3;
    Log.e("TAG", "handleMessage: -->" + position);
    smoothMoveToPosition(rv_1, 0);
    AutoMove();

   }
  }


 };

 private static AdAuditorAdapter adAuditorAdapter;
 static List<String> strings;
 @Override
 protected void onCreate(@Nullable Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_recycle);
  rv_1 = findViewById(R.id.rv_1);
  strings = new ArrayList<>();
  for (int i = 0; i < 50; i++) {
   strings.add(i + "");
  }
  adAuditorAdapter = new AdAuditorAdapter(this, strings);
  adAuditorAdapter.setMyClickListener(new AdAuditorAdapter.MyClickListener() {
   @Override
   public void onClick(View view, int position, int type) {
    Toast.makeText(RecycleViewActivity.this, adAuditorAdapter.getData().get(position), Toast.LENGTH_SHORT).show();
    StopMove();
   }
  });
  GridLayoutManager layoutManager = new ScrollSpeedGridLayoutManager1(this,3,GridLayoutManager.HORIZONTAL, false);
  rv_1.setLayoutManager(layoutManager);
  rv_1.setAdapter(adAuditorAdapter);
  rv_1.addOnScrollListener(new RecyclerView.OnScrollListener() {
   @Override
   public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
    super.onScrollStateChanged(recyclerView, newState);
//    if (mShouldScroll && RecyclerView.SCROLL_STATE_IDLE == newState) {
//     mShouldScroll = false;
//     smoothMoveToPosition(recyclerView, mToPosition);
//    }
    Log.e("TAG", "onScrollStateChanged11111111: -->" + newState);
    if (newState == 1) {
//     RecyclerView.ViewHolder holder = recyclerView.getChildViewHolder(recyclerView.getRootView());
     recyclerView.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
       Toast.makeText(RecycleViewActivity.this, adAuditorAdapter.getData().get(position)+"........", Toast.LENGTH_SHORT).show();
      }
     });
     StopMove();
     LongAutoMove();
    }
   }

//   @Override
//   public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
//    super.onScrolled(recyclerView, dx, dy);
//    Log.e("TAG", "onScrolled: dx=" +dx +" dy="+dy );
//   }
  });
  rv_1.setOnTouchListener(new View.OnTouchListener() {
   @Override
   public boolean onTouch(View v, MotionEvent event) {
    if (event.getAction()==MotionEvent.ACTION_DOWN){
     //監(jiān)測點(diǎn)擊位置找到view實(shí)現(xiàn)點(diǎn)擊事件
     View childView = rv_1.findChildViewUnder(event.getX(), event.getY());
     Log.e("GGGGGGGGGGGGGGGGG", "onTouch: -->"+rv_1.getChildLayoutPosition(childView));
     adAuditorAdapter.getListener().onClick(v, rv_1.getChildLayoutPosition(childView),1);
    }
    return false;
   }
  });
  AutoMove();
 }


 private static void AutoMove() {
  handler.removeMessages(HANDLER_MSG);
  handler.sendEmptyMessageDelayed(HANDLER_MSG, 2000);
 }

 private static void LongAutoMove() {
  if (handler.hasMessages(HANDLER_MSG)) {
   handler.removeMessages(HANDLER_LONG_MSG);
  }
  handler.sendEmptyMessageDelayed(HANDLER_LONG_MSG, 5000);
 }

 public static void StopMove() {
  if (handler.hasMessages(HANDLER_MSG)) {
   handler.removeMessages(HANDLER_MSG);
  }
 }


 //目標(biāo)項(xiàng)是否在最后一個(gè)可見項(xiàng)之后
 private static boolean mShouldScroll;
 //記錄目標(biāo)項(xiàng)位置
 private static int mToPosition;

 /**
  * 滑動到指定位置
  */
 private static void smoothMoveToPosition(RecyclerView mRecyclerView, final int position) {
  if (position==0){
   mRecyclerView.setAdapter(adAuditorAdapter);
  }
   mRecyclerView.smoothScrollToPosition(position);
   mToPosition = position;
   mShouldScroll = true;
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();
  if (handler!=null){
   handler.removeCallbacksAndMessages(null);
   handler= null;
  }
  if (adAuditorAdapter!=null) {
   adAuditorAdapter= null;
  }
 }
}

自動輪播效果基本實(shí)現(xiàn)

這里的Demo只寫了大概的效果還有很多的東西需要優(yōu)化一下,才能拿到項(xiàng)目中使用

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論