1. 程式人生 > >(再次更新)打造RecyclerView萬能介面卡,上拉重新整理,下拉載入

(再次更新)打造RecyclerView萬能介面卡,上拉重新整理,下拉載入

入行幾個月了,一直想自己封裝一些類,剛好遇到了這個問題,現在跟大家分享。
注意點
1 泛型擦除
2 需要防止型別轉換異常
github地址:https://github.com/zw21544182/MyBaseDemo
(裡面還有部分FileUtils常用相關方法),歡迎start 一起交流進步
關於RecyclerView.Adapter 一般的套路是這個樣子的

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {
    @Override
    public
ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //建立ViewHolder return null; } @Override public void onBindViewHolder(ViewHolder holder, int position) { //繫結資料 } @Override public int getItemCount() { //獲取資料行數 return 0; } public
class ViewHolder extends RecyclerView.ViewHolder { public ViewHolder(View itemView) { //繫結Itme 中的View super(itemView); } } }

現在我想寫一個Adapter的基類
最初的想法是指定一個泛型,像這樣

public class MyRecyclerViewAdapter<T> extends RecyclerView.Adapter<MyRecyclerViewAdapter
.ViewHolder> {
List<T> data; Context context; int layoutId; public MyRecyclerViewAdapter(List<T> data, Context context, int layoutId) { this.data = new ArrayList<>(); data.addAll(data); this.context = context; this.layoutId = layoutId; } //新增一些 setData clearData等方法 @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //建立ViewHolder View view = LayoutInflater.from(this.context).inflate(this.layoutId, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder holder, int position) { //繫結資料 } @Override public int getItemCount() { //獲取資料行數 return data.size(); } public class ViewHolder extends RecyclerView.ViewHolder { public ViewHolder(View itemView) { //繫結Itme 中的View super(itemView); } } }

自我感覺這樣很完美,但是編譯通不過。報沒有實現子類onBindViewHolder的錯,額,好吧。就這樣,尷尬了一會,在網上查了查資料。後來想到為什麼不直接泛型擦除呢?
最後就有了現在這個BaseRecyclerAdapter

/**
 * 建立時間: 2017/11/29
 * 建立人: Administrator
 * 功能描述:RecyclerView基類(需要注意型別轉換問題)
 */
public abstract class BaseRecyclerViewAdapter extends RecyclerView.Adapter<BaseRecyclerViewAdapter.BaseViewHolder> {
    protected ArrayList data;
    protected Context context;
    protected List<Integer> layoutIds;//佈局集合
    protected boolean isMore = true;//上拉重新整理時,是否有更多資料

    public BaseRecyclerViewAdapter(List data, Context context, List<Integer> layoutIds) {
        this.data = new ArrayList<>();
        this.layoutIds = new ArrayList<>();
        this.data.addAll(data);
        this.layoutIds.addAll(layoutIds);
        this.context = context;
    }

    public void setData(List data) {
        this.data.clear();
        this.data.addAll(data);
        notifyDataSetChanged();
    }

    public void clearAll() {
        this.data.clear();
        notifyDataSetChanged();
    }

    public Object getDataByPos(int index) {
        if (data.size() <= index) {
            return null;
        }
        return data.get(index);
    }

    public void addData(Object t) {
        data.add(t);
        notifyDataSetChanged();
    }

    public void addDatas(List data) {
        this.data.addAll(data);
        notifyDataSetChanged();
    }
#重要 設定viewType
    @Override
    public int getItemViewType(int position) {
        if (position + 1 == getItemCount()) {
            return -1;//最後行時設為-1顯示footLayout
        } else {
            return position;//其他設為位置
        }

    }

    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int pos) {
        if (data.size() == 0) {//當data資料為0時
            View view = LayoutInflater.from(context).inflate(R.layout.zwbase_no_data, parent, false);
            //顯示暫無資料佈局
            return new BaseViewHolder(view);
        }
        if (pos == -1) {//pos為-1表示最後一行 
            View view = LayoutInflater.from(context).inflate(R.layout.zwbase_footlayout, parent, false);
            //顯示底部佈局
            return new FootViewHolder(view);
        }
        int layout = getLayoutIdByPos(pos);
        View view = LayoutInflater.from(context).inflate(layout, parent, false);
        BaseViewHolder baseViewHolder = new BaseViewHolder(view);
        clickView(baseViewHolder, data.get(pos), pos);
        return baseViewHolder;
    }

    protected int getLayoutIdByPos(int pos) {
        int res = 0;
        if (pos < layoutIds.size()) {//layoutIds是存放佈局的集合
            res = layoutIds.get(pos);
        } else {
            res = layoutIds.get(pos % layoutIds.size());
        }
        return res;
    }


    /**
     * 在oncreateViewHolder方法中設定點選事件
     * 避免重複呼叫
     * @param baseViewHolder itme控制元件
     * @param o              itme    實體類
     * @param pos            位置
     */
    protected abstract void clickView(BaseViewHolder baseViewHolder, Object o, int pos);

    protected abstract void setItmeData(BaseViewHolder baseViewHolder, Object itmeModule, int position) throws ClassCastException;

    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {
        if (data.size() == 0) {
            ImageView nodataImage = (ImageView) holder.getViewById(R.id.zwbase_imageview);
            TextView nodataText = (TextView) holder.getViewById(R.id.zwbase_tvNoData);
            setNodataInfo(nodataImage, nodataText);
            return;
        }
        if (holder instanceof FootViewHolder) {
            //判斷為底部佈局時
            if (isMore) {//再次判斷是否還有更多資料,載入相應的佈局
                holder.getViewById(R.id.loadmore).setVisibility(View.VISIBLE);
                holder.getViewById(R.id.nodata).setVisibility(View.GONE);
            } else {
                holder.getViewById(R.id.loadmore).setVisibility(View.GONE);
                holder.getViewById(R.id.nodata).setVisibility(View.VISIBLE);
            }
            return;
        }
        try {
            setItmeData(holder, data.get(position), position);//設定顯示資料
        } catch (ClassCastException e) {
            e.printStackTrace();
        }
    }

    protected void setNodataInfo(ImageView nodataImage, TextView nodataText) {
    }


    @Override
    public int getItemCount() {
        return data == null ? 0 : data.size() + 1;//資料為0或為空時返回0,否則data.size()+1
    }

    public void setMore(boolean more) {
        //暴露方法給Activity
        this.isMore = more;
    }

    protected class FootViewHolder extends BaseViewHolder {
        public FootViewHolder(View itemView) {
            super(itemView);
        }
    }

    public class BaseViewHolder extends RecyclerView.ViewHolder {
        //該類下部分方法可以自行新增
        View rootView;

        public BaseViewHolder(View itemView) {
            super(itemView);
            rootView = itemView;
        }

        public void setText(int viewId, int resourceId) {
            ((TextView) getViewById(viewId)).setText(resourceId);
        }

        public void setClickListent(int viewId, View.OnClickListener onClickListener) {
            getViewById(viewId).setOnClickListener(onClickListener);
        }

        public void setText(int viewId, String content) {
            ((TextView) getViewById(viewId)).setText(content);
        }

        public void setCheckChangeListen(int viewId, CompoundButton.OnCheckedChangeListener onCheckedChangeListener) {
            ((CheckBox) getViewById(viewId)).setOnCheckedChangeListener(onCheckedChangeListener);
        }

        public void setImageSource(int imageViewId, int sourceId) {
            ImageView imageView = (ImageView) getViewById(imageViewId);
            imageView.setImageResource(sourceId);
        }

        public View getViewById(int viewId) {
            return rootView.findViewById(viewId);
        }
    }
}

在打造我們自己的介面卡時,我們可以繼承BaseRecyclerViewAdaPter

public class MyAdapter extends BaseRecyclerViewAdapter {

    public MyAdapter(List data, Context context, List<Integer> layoutIds) {
        super(data, context, layoutIds);
    }

    @Override
    protected void clickView(BaseViewHolder baseViewHolder, Object o, int pos) {

    }

    @Override
    protected void setItmeData(BaseViewHolder baseViewHolder, Object itmeModule, int position) throws ClassCastException {
        int layoutNum = (position % layoutIds.size());

        switch (layoutNum) {
            case 0:
                baseViewHolder.setText(R.id.tvText, (String) itmeModule);
                break;
            case 1:
                baseViewHolder.setImageSource(R.id.ivImage, R.mipmap.image);
                break;
        }
    }
}

在activity中傳入相關的佈局Id號即可

  data = new ArrayList<>();
        layoutIds = new ArrayList<>();
        layoutIds.add(R.layout.layout_rvitme);
        layoutIds.add(R.layout.layout_image);
//需要注意的是layoutIds傳入的佈局Id的順序和個數要與Adapter中的setItmeData對應
        for (int i = 0; i < 100; i++) {
            data.add("sssss " + i);
        }
        baseRecyclerViewAdapter = new MyAdapter(data, this, layoutIds);
        myRview.setLayoutManager(new LinearLayoutManager(this));
        myRview.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        myRview.setAdapter(baseRecyclerViewAdapter);

最後, 花了一些時間,封裝成了可重新整理的view 下拉重新整理用的官方+介面回撥,上拉載入也是 可以去github上看看,一起交流學習

相關推薦

(再次更新)打造RecyclerView萬能介面卡重新整理載入

入行幾個月了,一直想自己封裝一些類,剛好遇到了這個問題,現在跟大家分享。 注意點 1 泛型擦除 2 需要防止型別轉換異常 github地址:https://github.com/zw21544182/MyBaseDemo (裡面還有部分FileUtil

分頁 重新整理載入

一、自定義listview package com.fragment.home; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; impor

Android中recyclerview+pullToRefresh實現重新整理載入

一. 依賴 implementation 'com.jwenfeng.pulltorefresh:library:1.0.3' 要把minSdkVersion 改為16以上 二.佈局 <LinearLayout xmlns:android="http:/

RecyclerView重新整理載入

1.佈局(用SwipeRefreshLayout實現下拉重新整理) <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipeRefreshLayout"

基於React Native官方元件FlatList增加可定製化“重新整理”、“載入更多”元件API的新列表元件react-native-refresh-loadmore-flatlist

react-native-refresh-loadmore-flatlist 基於React Native官方元件FlatList,增加可定製化“下拉重新整理”、“下拉載入更多”元件API的新列表元件,具體實現功能如下: 自定義下拉重新整理元件API 自定義上拉Lo

微信小程式重新整理載入2種方法實現

微信小程式上拉重新整理和下拉載入2種方法實現,onPullDownRefresh,scroll-view使用 一、XXX.json開啟下拉重新整理 {    "enablePullDownRefresh": true }   二、XXX.js onP

prlibrary重新整理載入

import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.ListVi

【微信小程式】重新整理載入

上拉重新整理和下拉載入有兩種方式可以實現: 1.使用scroll-view元件進行操作,使用自帶的scrolltoupper和scrolltolower事件可以實現。適合頁面區域性的上拉下拉。 附上

React-native 三方框架實現重新整理載入網路請求以及跳轉先詳情頁面

首先 第一步 需要匯入三方的類庫 和跳轉詳情頁面 yarn add react-native-refresh-list-view //導包 import RefreshListView, { RefreshState } from “react-nati

mui做的重新整理載入和日期選擇器

var pageCount = 1;//頁碼 var date_inputs = document.getElementsByClassName('select_date'); var today = new Date(); var thisyear = today.getF

重新整理重新整理的實現

先來兩張效果圖           關於下拉重新整理,Google提供了一個佈局SwipRefreshLayout,它裡面可以包涵一個滑動控制元件,然後你可以設定它的重新整理事件就OK了,非常簡單用。但是上拉重新整理就有點麻煩了。網上很多方法都是給recyclervie

Swiper實現重新整理載入更多(學習筆記④)

簡單粗暴的放碼 一個簡單的效果 分頁器效果中加下拉重新整理和上拉載入功能 HTML結構: <div class="a">標題</div> <div class="tab"> <a class="active" href="j

【Android-PullToRefresh】 重新整理載入 使用詳解

轉載自:http://blog.csdn.net/lmj623565791/article/details/38238749,本文出自:【張鴻洋的部落格】 1、ListView下拉重新整理快速入門 pull-to-refresh對ListView進行了

Android(無需javabean)的RecyclerView萬能介面卡解耦從這裡做起

先介紹下為什麼這麼做,因為RecyclerView需要一個javabean,同時呢,對於整個系統中的一個物件,也需要建造一個javabean。但是很明顯,RecyclerView中的那個bean顯然是整個系統中那個物件javabean的子集。所以我覺得不應該專門為Recyc

RecyclerView重新整理載入

Activity介面方法 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_mai

Xamarin.Android 使用 SimpleAdapter 打造 ListView 萬能介面卡

第一步:建立 layout1.axml 來展示列表詳細內容 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

功能強大的RecyclerView實現 (單/多子項佈局載入載入重新整理左劃刪除)

       先看效果,可以像普通recyclerView那樣只加載一種列表子項,也可以同時載入不同的列表子項,已經寫好了常用必備的功能:正常的適配渲染,上拉載入,下拉重新整理,左劃刪除。 核心是XRefreshView+MultiTypeAdapter兩者組合使用,搭

RecyclerView 萬能介面卡的抽取

//這裡我們寫的複雜的RecyclerView對條目的抽取,我們只設置了三個型別,頭佈局(輪播圖),身體佈局,腳佈局(上拉重新整理)的複雜條目的抽取框架 import android.support.v7.widget.RecyclerView; import androi

使用MUI框架模擬手機端的刷新加載操作。

項目應用 pan true .net 沒有 拖動 test css選擇器 query 套用mui官方文檔的一句話:“開發者只需關心業務邏輯,實現加載更多數據即可”。真的是不錯的框架。 想更多的了解這個框架:http://dev.dcloud.net.cn/mui/ 那麽如何

Webstorm/Phpstorm中設置連接FTP並快速進行文件比較傳下載同步等操作

webstorm pwd 服務 誤操作 一份 分享 mod compare connect Phpstorm除了能直接打開localhost文件之外,還可以連接FTP,除了完成正常的數據傳遞任務之外,還可以進行本地文件與服務端文件的異同比較,同一文件自動匹配目錄上傳,下載,