中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

RecyclerView的刷新分頁

發布時間:2020-10-21 12:44:13 來源:網絡 閱讀:643 作者:零點小筑 欄目:移動開發

在開發中常常使用到刷新分頁,這里實現一個 RecyclerView 的簡單的刷新分頁操作,測試效果見文末,實現過程參考如下:

實現思路

  1. 加載更多數據使用到 RecyclerView 加載多種布局,根據 ViewType 判斷加載數據 Item 還是加載 FooterItem ;
  2. 通過線程模擬加載數據;
  3. 為 RecyclerView 添加 addOnScrollListener 事件來監聽用戶的滑動操作;
  4. 根據用戶滑動狀態以及具體情況開始加載數據
  5. 通知數據更新;

如何獲得 firstVisibleItemPosition

為了能夠在數據加載中動態判斷什么時候加載數據,需要知道屏幕上顯示的第一個可見的 Item 的位置,當然了這里使用的是布局管理器是 LinearLayoutManager ,這樣查找屏幕上第一個可見的 Item 就顯得容易多了,下面介紹一些 LinearLayoutManager 的四個方法:

findFirstVisibleItemPosition()

獲得屏幕上第一個可見 Item 的 position,只要該 Item 有一部分可見,那么返回的 position 就是該Item 的 position。

findFirstCompletelyVisibleItemPosition()

獲得屏幕上第一個完整可見的 Item 的 position,只要該 Item 有一部分不可見,那么返回的 position 就是該 Item 對應的下一個能顯示完整的 Item 的position。

findLastVisibleItemPosition()

獲得屏幕上最后一個可見 Item 的 position,只要該 Item 有一部分可見,那么返回的 position 就是該Item 的 position。

findLastCompletelyVisibleItemPosition()

獲得屏幕上最后一個完整可見的 Item 的 position,只要該 Item 有一部分不可見,那么返回的 position 就是該 Item 對應的上一個能顯示完整的 Item 的position。

準備數據

    /**
     * 初始化數據
     * @return
     */
    public void  initData(){
        for (int i=0;i<30;i++){
            arrayList.add("第"+i+"條數據");
        }
    }

    /**
     * 線程模擬加載數據
     */
    class LoadDataThread extends Thread{
        @Override
        public void run() {
            initData();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //通知主線程更新數據
            Message message = handler.obtainMessage();
            message.what = UPDATE_DATA;
            message.obj = arrayList;
            handler.sendMessage(message);
        }
    }

代碼參考

主布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.manu.mrecyclerview.MainActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>
</LinearLayout>
Item布局
/**item.xml**/
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="5dp">
    <TextView
        android:id="@+id/tv_recycle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="data"
        android:background="#cac3c3"
        android:padding="10dp"
        android:textSize="20sp"/>
</LinearLayout>

/**item_footer.xml**/
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal">
    <ProgressBar
        
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/progressBar" />
    <TextView
        android:text="正在努力加載中,請稍后..."
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView" />
</LinearLayout>
Adapter

這里使用了 RecyclerView 根據不同的 ViewType 加載多種布局的用法,使用時根據不同的布局創建不同的 ViewHolder , 然后根據不同的 Viewholder 為對應的 Item 添加數據,注意 getItemViewType() 方法的用法,Adapter 代碼參考如下:

/**
 * Created by jzman on 2017/6/04
 * RecycleView的Adapter
 */
public class RvAdapter1 extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements
        View.OnClickListener{
    private static final int ITEM_FOOTER = 0x1;
    private static final int ITEM_DATA = 0x2;
    private Context mContext;
    private RecyclerView recyclerView;
    private ArrayList<String> mList;

    public RvAdapter1() {}

    public RvAdapter1(Context mContext, ArrayList<String> mList) {
        this.mContext = mContext;
        this.mList = mList;
    }

    public void setmList(ArrayList<String> mList) {
        this.mList = mList;
    }

    /**
     * 用于創建ViewHolder
     * @param parent
     * @param viewTypez
     * @return
     */
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view ;
        RecyclerView.ViewHolder vh = null;
        switch (viewType){
            case ITEM_DATA:
                view = LayoutInflater.from(mContext).inflate(R.layout.item,null);
                view.setOnClickListener(this);
                vh = new DataViewHolder(view);
                //使用代碼設置寬高(xml布局設置無效時)
                view.setLayoutParams(new ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT));
                break;
            case ITEM_FOOTER:
                view = LayoutInflater.from(mContext).inflate(R.layout.item_footer,null);
                //使用代碼設置寬高(xml布局設置無效時)
                vh = new FooterViewHolder(view);
                view.setLayoutParams(new ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT));
                break;
        }
        return vh;
    }

    /**
     * 獲取Item的View類型
     * @param position
     * @return
     */
    @Override
    public int getItemViewType(int position) {
        //根據 Item 的 position 返回不同的 Viewtype
        if (position == (getItemCount())-1){
            return ITEM_FOOTER;
        }else{
            return ITEM_DATA;
        }
    }

    /**
     * 綁定數據
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof DataViewHolder){
            DataViewHolder dataViewHolder = (DataViewHolder) holder;
            dataViewHolder.tv_data.setText(mList.get(position));
        }else if (holder instanceof FooterViewHolder){

        }
    }

    /**
     * 選項總數
     * @return
     */
    @Override
    public int getItemCount() {
        return mList.size()+1;
    }

    @Override
    public void onClick(View view) {
        //根據RecyclerView獲得當前View的位置
        int position = recyclerView.getChildAdapterPosition(view);
        //程序執行到此,會去執行具體實現的onItemClick()方法
        if (onItemClickListener!=null){
            onItemClickListener.onItemClick(recyclerView,view,position,mList.get(position));
        }
    }

    /**
     * 創建ViewHolder
     */
    public static class DataViewHolder extends RecyclerView.ViewHolder{
        TextView tv_data;
        public DataViewHolder(View itemView) {
            super(itemView);
            tv_data = (TextView) itemView.findViewById(R.id.tv_recycle);
        }
    }

    /**
     * 創建footer的ViewHolder
     */
    public static class FooterViewHolder extends RecyclerView.ViewHolder{
        public FooterViewHolder(View itemView) {
            super(itemView);
        }
    }

    private OnItemClickListener onItemClickListener;
    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemClickListener = onItemClickListener;
    }

    /**
     * 定義RecyclerView選項單擊事件的回調接口
     */
    public interface OnItemClickListener{
        //參數(父組件,當前單擊的View,單擊的View的位置,數據)
        void onItemClick(RecyclerView parent,View view, int position, String data);
    }
    /**
     *   將RecycleView附加到Adapter上
     */
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        this.recyclerView= recyclerView;
    }
    /**
     *   將RecycleView從Adapter解除
     */
    @Override
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);
        this.recyclerView = null;
    }
}
MainActivity

這里主要注意 rv.addOnScrollListener(new OnScrollListener() ...里面的具體實現,MainActivity 代碼參考如下:

/**
 * Created by jzman on 2017/6/04 0013.
 */
public class MainActivity extends AppCompatActivity {
    private static final int UPDATE_DATA = 0x3;

    private RecyclerView rv;
    RvAdapter1 adapter;

    private ArrayList<String> arrayList = new ArrayList<>();
    //加載更多數據時最后一項的索引
    private int lastLoadDataItemPosition;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        rv = (RecyclerView) findViewById(R.id.rv);

        //設置布局管理器
        rv.setLayoutManager(new LinearLayoutManager(this));//線性
//        rv.setLayoutManager(new GridLayoutManager(this,4));//網格
//        rv.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL));//瀑布
        initData();
        adapter = new RvAdapter1(this,arrayList);
        adapter.setOnItemClickListener(new RvAdapter1.OnItemClickListener() {
            @Override
            public void onItemClick(RecyclerView parent, View view, int position, String data) {
                Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
            }
        });

        rv.addOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                if (newState == SCROLL_STATE_IDLE &&
                        lastLoadDataItemPosition == adapter.getItemCount()){
                    new LoadDataThread().start();
                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

                LayoutManager layoutManager = recyclerView.getLayoutManager();
                if (layoutManager instanceof LinearLayoutManager){
                    LinearLayoutManager manager = (LinearLayoutManager) layoutManager;
                    int firstVisibleItem = manager.findFirstVisibleItemPosition();
                    int l = manager.findLastCompletelyVisibleItemPosition();
                    lastLoadDataItemPosition = firstVisibleItem+(l-firstVisibleItem)+1;
                }
            }
        });

        rv.setAdapter(adapter);
    }

    /**
     * 初始化數據
     * @return
     */
    public void  initData(){
        for (int i=0;i<25;i++){
            arrayList.add("第"+i+"條數據");
        }
    }

    /**
     * 線程模擬加載數據
     */
    class LoadDataThread extends Thread{
        @Override
        public void run() {
            initData();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Message message = handler.obtainMessage();
            message.what = UPDATE_DATA;
            message.obj = arrayList;
            handler.sendMessage(message);
        }
    }

    private Handler handler = new Handler(){

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case UPDATE_DATA:
                    arrayList = (ArrayList<String>) msg.obj;
                    adapter.setmList(arrayList);
                    adapter.notifyDataSetChanged();
                    break;
            }
        }
    };
}

測試效果

RecyclerView的刷新分頁

可關注微信公眾號:jzman-blog 獲取最新文章更新,一起交流學習!

RecyclerView的刷新分頁

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

隆安县| 阿尔山市| 合作市| 儋州市| 化州市| 黎平县| 武鸣县| 南城县| 津南区| 林周县| 潮安县| 崇文区| 秭归县| 彩票| 汉川市| 浪卡子县| 南安市| 红原县| 湾仔区| 漳浦县| 江山市| 新田县| 垫江县| 柯坪县| 融水| 西城区| 古交市| 搜索| 青铜峡市| 禄丰县| 海口市| 丰顺县| 兴国县| 平阴县| 静安区| 正镶白旗| 山阴县| 行唐县| 桐梓县| 安化县| 青阳县|