概要
做一個(gè)自動(dòng)滑動(dòng)的列表,用于展示聊天記錄或者通知欄信息等,還是使用主流的RecyclerView來做。網(wǎng)上有很多案例,但當(dāng)手動(dòng)滑動(dòng)時(shí)會(huì)一直無限循環(huán),數(shù)據(jù)重復(fù)的出現(xiàn),如果想要自動(dòng)滑動(dòng)時(shí)能無限循環(huán),手動(dòng)滑動(dòng)時(shí)又能滑到底呢?本案例就解決這種手動(dòng)滑動(dòng)和自動(dòng)滑動(dòng)無縫銜接的問題。
思路
1、重寫RecyclerView,通過scrollBy和postDelayed進(jìn)行定時(shí)移動(dòng)到達(dá)自動(dòng)滑動(dòng)目的
2、RecyclerView添加addOnScrollListener,進(jìn)行手指按下滑動(dòng)和抬起監(jiān)聽,用于判斷是手動(dòng)滑動(dòng)還是自動(dòng)滑動(dòng)。
3、修改adapter的itemCount
4、接下來上代碼
實(shí)現(xiàn)方案
1、重寫 RecyclerView:
public class SocllRecyclerView extends RecyclerView {
private Autoaaview autoview;
private boolean running;
private boolean canrun;
private static final int Timea = 40;//控制滾動(dòng)的速度,值越大速度越慢
public SocllRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
autoview = new Autoaaview(this);
}
public SocllRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
private class Autoaaview implements Runnable{
WeakReference<SocllRecyclerView> myScrViewWeakReference;
public Autoaaview(SocllRecyclerView myScrView) {
myScrViewWeakReference = new WeakReference<>(myScrView);
}
@Override
public void run() {
SocllRecyclerView myScrView = myScrViewWeakReference.get();
if (myScrView.canrun&&myScrView.running){
myScrView.scrollBy(2,2);
myScrView.postDelayed(myScrView.autoview,Timea);
}
}
}
//開始滾動(dòng)
public void start(){
if (running)
stop();
running = true;
canrun = true;
postDelayed(autoview,Timea);
}
//停止?jié)L動(dòng)
public void stop() {
running = false;
removeCallbacks(autoview);
}
@Override
public boolean onTouchEvent(MotionEvent e) {
return super.onTouchEvent(e);
}
}
2、適配器?MyscrviewAdapter
public class MyscrviewAdapter extends RecyclerView.Adapter<ViewHolder> {
Context context;
List<NoticeBean.RecordsBean> mies;
private int itemCount = Integer.MAX_VALUE;
public MyscrviewAdapter(Context context, List<NoticeBean.RecordsBean> mies) {
this.context = context;
this.mies = mies;
}
public void updateAll(List<NoticeBean.RecordsBean> list) {
mies.clear();
mies.addAll(list);
notifyDataSetChanged();
}
/**
* 設(shè)置狀態(tài),用于設(shè)置ItemCount的數(shù)量
* state:1 表示正在手指滑動(dòng),itemCount設(shè)置為實(shí)際數(shù)量;
* 其他的表示結(jié)束手動(dòng)滑動(dòng),itemCount設(shè)置為最大值Integer.MAX_VALUE
* @param state
*/
public void setItemCount(int state) {
this.itemCount = state == 1 ? mies.size() : Integer.MAX_VALUE;
notifyDataSetChanged();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View inflate = LayoutInflater.from(context).inflate(R.layout.item_home_news, parent, false);
ViewHolder baseViewHolder = new ViewHolder(inflate);
return baseViewHolder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
holder.setText(R.id.tvNewsTitle, mies.get(position % mies.size()).getTitle());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != mItemClickListener) {
mItemClickListener.onItemClick(mies.get(position % mies.size()), position);
}
}
});
}
@Override
public int getItemCount() {
return mies.size() > 4 ? itemCount : mies.size();
}
//使用接口回調(diào)點(diǎn)擊事件
private ItemClickListener mItemClickListener;
public void setOnItemClickListener(ItemClickListener itemClickListener) {
this.mItemClickListener = itemClickListener;
}
public interface ItemClickListener {
void onItemClick(Object obj, int position);
}
}
ViewHolder封裝類
public class ViewHolder extends RecyclerView.ViewHolder {
//用于緩存已找的界面
private SparseArray<View> mView;
public ViewHolder(View itemView) {
super(itemView);
mView=new SparseArray<>();
}
public <T extends View> T getView(int viewId){
//對(duì)已有的view做緩存
View view=mView.get(viewId);
//使用緩存的方式減少findViewById的次數(shù)
if(view==null){
view=itemView.findViewById(viewId);
mView.put(viewId,view);
}
return (T) view;
}
//通用的功能進(jìn)行封裝 設(shè)置文本 設(shè)置條目點(diǎn)擊事件 設(shè)置圖片
public ViewHolder setText(int viewId , CharSequence text){
TextView view = getView(viewId);
view.setText(text);
//希望可以鏈?zhǔn)秸{(diào)用
return this;
}
//通用的功能進(jìn)行封裝 設(shè)置文本 設(shè)置條目點(diǎn)擊事件 設(shè)置圖片
public ViewHolder setText(int viewId , String text){
TextView view = getView(viewId);
view.setText(text);
//希望可以鏈?zhǔn)秸{(diào)用
return this;
}
public ViewHolder setSelected(int viewId ,boolean selected){
TextView view = getView(viewId);
view.setSelected(selected);
//希望可以鏈?zhǔn)秸{(diào)用
return this;
}
public ViewHolder setSelected2(int viewId,boolean selected){
View view = getView(viewId);
view.setSelected(selected);
return this;
}
public ViewHolder setVisible(int viewId,boolean visible){
View view = getView(viewId);
view.setVisibility(visible ? View.VISIBLE : View.GONE);
return this;
}
public ViewHolder setVisible(int viewId,boolean visible,boolean isLocation){
View view = getView(viewId);
if (isLocation){
view.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
}else{
view.setVisibility(visible ? View.VISIBLE : View.GONE);
}
return this;
}
/**
*設(shè)置本地圖片
* @param viewId
* @param resId
* @return
*/
public ViewHolder setImageResource(int viewId,int resId){
ImageView iv=getView(viewId);
iv.setImageResource(resId);
return this;
}
public ViewHolder setTextSelected(int viewId, boolean bool) {
TextView tv = getView(viewId);
tv.setSelected(bool);
return this;
}
/**
*設(shè)置本地圖片
* @param viewId
* @param resId
* @return
*/
public ViewHolder setImageDrawable(Context mContext, int viewId, int resId){
ImageView iv=getView(viewId);
iv.setImageDrawable(mContext.getResources().getDrawable(resId));
return this;
}
/**
* 加載圖片資源路徑
* @param viewId
* @param imageLoader
* @return
*/
public ViewHolder setImagePath(int viewId,HolderImageLoader imageLoader,int res){
ImageView iv=getView(viewId);
imageLoader.loadImage(iv,imageLoader.getPath(),res);
return this;
}
public ViewHolder setImage(Context mContext, int viewId, String url, int res) {
ImageView view = getView(viewId);
GlideLoadImageUtils.loadRectangleImg(mContext, view, url,res);
return this;
}
public ViewHolder setCircleImage(Context mContext, int viewId, String url, int res) {
ImageView view = getView(viewId);
GlideLoadImageUtils.loadCircleImg(mContext, view, url,res);
return this;
}
public ViewHolder setTextColor(Context mContext, int viewId, int color) {
TextView tv = (TextView)this.getView(viewId);
tv.setTextColor(mContext.getResources().getColor(color));
return this;
}
public ViewHolder setTextSize(Context mContext, int viewId, float res) {
TextView tv = (TextView)this.getView(viewId);
tv.setTextSize(Utils.dp2px(mContext,res));
return this;
}
@SuppressLint("NewApi")
public ViewHolder setBackground(Context mContext, int viewId, int bg) {
TextView tv = (TextView)this.getView(viewId);
tv.setBackground(mContext.getResources().getDrawable(bg));
return this;
}
/**
* 關(guān)于事件的
*/
public ViewHolder setOnClickListener(int viewId, View.OnClickListener listener) {
View view = getView(viewId);
view.setOnClickListener(listener);
return this;
}
public abstract static class HolderImageLoader{
public String mPath;
public Context mContext;
public HolderImageLoader(Context mContext, String path){
this.mPath=path;
this.mContext = mContext;
}
/**
* 需要去復(fù)寫這個(gè)方法加載圖片
* @param iv
* @param path
*/
public abstract void loadImage(ImageView iv, String path, int res);
public String getPath(){
return mPath;
}
}
}
3、activity中使用
? ? ?RecyclerView滑動(dòng)監(jiān)聽,注釋都說的很詳細(xì)
/**
* 控制通知公告數(shù)據(jù)滾動(dòng)
* 手指滑動(dòng)時(shí) 停止自動(dòng)滾動(dòng)
* 手指抬起時(shí),3秒后自動(dòng)開始滾動(dòng)
*/
private void initRlvNews() {
scroHandler = new Handler();//定義handler
runnable = () -> { //runnable方法,處理延時(shí)后的操作
newsAdapter.setItemCount(0);//0表示手指已經(jīng)抬起來了
rlvNews.start(); //開始滑動(dòng)
};
rlvNews.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (null != newsAdapter) {
if (newState == 1) {//newState的值:1 手指按下拖拽滾動(dòng),2自動(dòng)滾動(dòng)(一般指慣性滾動(dòng)),0 禁止沒有滾動(dòng)
rlvNews.stop();//停止自動(dòng)滾動(dòng)
newsAdapter.setItemCount(newState);
} else {
scroHandler.removeCallbacks(runnable);//清除runnable重新開始
//這里設(shè)置3秒是預(yù)估了手指滑動(dòng)抬起再滑動(dòng)的時(shí)間,提升體驗(yàn)
scroHandler.postDelayed(runnable, 3000);
}
}
}
});
}
4、布局文件:
??需要給固定高度
<com.anyi.credit.bank.view.SocllRecyclerView
android:id="@+id/rlvNews"
android:layout_width="match_parent"
android:layout_height="144dp"/>
5、數(shù)據(jù)綁定
?????????rlvNews.setLayoutManager()//可設(shè)置水平滾動(dòng)或豎直滾動(dòng)布局
????????MyscrviewAdapter adpter=new?MyscrviewAdapter(this,list)
????????rlvNews.setAdapter(adpter)
? ? ? ? //關(guān)鍵,條件自定義,如當(dāng)列表數(shù)據(jù)大于4條時(shí)開始滑動(dòng)
? ? ? ? if(list.size()>4){
????????????????rlvNews.start(); //開始滑動(dòng)文章來源:http://www.zghlxwxcb.cn/news/detail-816609.html
????????}文章來源地址http://www.zghlxwxcb.cn/news/detail-816609.html
結(jié)束------------
到了這里,關(guān)于Android 自動(dòng)滾動(dòng)的RecyclerView,手動(dòng)滑動(dòng)和自動(dòng)滑動(dòng)無縫銜接,手動(dòng)滑動(dòng)時(shí)數(shù)據(jù)不重復(fù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!