RecyclerView 的使用

来源:http://www.cnblogs.com/audienl/archive/2016/04/26/5435927.html
-Advertisement-
Play Games

廢話不多說,堅持自己一貫的風格,儘量把代碼寫的最簡單。一上效果圖,二上代碼,註釋都在代碼中。 效果圖是個美女,莫怪,代碼寫著寫著總會意淫一下,,, 一、引入相關包 二、整體佈局 這裡佈局就只有一個RecyclerView。 三、item佈局 這裡也是只有一個TextView。 四、封裝Adapter ...




一直使用ListView,也沒覺得有什麼問題,可能還是自己太菜了。 
官方突然出了個RecyclerView,據說是專門替代ListView的,也沒覺得好用多少,還是因為自己太菜了。 
不管怎麼說,要緊跟時代的潮流,儘管不喜歡,也要去學習,說不定學著學著就愛上了呢~

廢話不多說,堅持自己一貫的風格,儘量把代碼寫的最簡單。一上效果圖,二上代碼,註釋都在代碼中。

 

效果圖是個美女,莫怪,代碼寫著寫著總會意淫一下,,,

一、引入相關包

compile 'com.android.support:design:23.3.0'

二、整體佈局

這裡佈局就只有一個RecyclerView。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

三、item佈局

這裡也是只有一個TextView。

<?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="wrap_content"
              android:layout_marginBottom="1dp"
              android:background="#80000000"
              android:orientation="vertical"
              android:padding="10dp">

    <TextView
        android:id="@+id/tv_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#FFFFFF"
        android:textSize="22sp"
        tools:text="這是一個測試"/>
</LinearLayout>

四、封裝Adapter-不用鳥它,直接使用就行

平時養成了壞習慣,看到不爽的東西,麻煩的東西,總是喜歡把它封裝起來,為我所用,所以封裝之後提供的介面也是按照我的習慣亂來的。 
其中 DATA 為數據實體,比如:String、User什麼的。 
VH 為ViewHolder。 
谷歌官方並沒有給RecyclerView添加setOnItemClickListener介面,這個常用吧,但是沒有,所以這裡封裝了一下。

package com.audienl.recyclerviewdemo.adapters;

import android.content.Context;
import android.support.annotation.LayoutRes;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

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

/**
 * @author AudienL([email protected]) on 2016/4/22
 */
public abstract class SuperRVAdapter<DATA, VH extends RecyclerView.ViewHolder>
        extends RecyclerView.Adapter<VH> {

    protected Context context;
    protected List<DATA> items = new ArrayList<>();

    public SuperRVAdapter(Context context) {
        this.context = context;
    }

    public SuperRVAdapter(Context context, List<DATA> items) {
        this.context = context;
        this.items = items;
    }

    /**
     * 設置數據源
     */
    public void setItems(List<DATA> items) {
        if (items != null) {
            this.items = items;
        }
    }

    /**
     * 添加一個數據集
     */
    public void addItems(List<DATA> items) {
        if (items != null) {
            this.items.addAll(items);
        }
    }

    /**
     * 添加一條數據
     */
    public void addItem(DATA item) {
        if (item != null) {
            this.items.add(item);
        }
    }

    /**
     * 獲取一條數據
     */
    public DATA getItem(int position) {
        return items.get(position);
    }

    /**
     * 清空數據
     */
    public void clear() {
        items.clear();
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    @Override
    public VH onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(getLayoutResId(), parent, false);
        return onCreateViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final VH holder, final int position) {
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onItemClick(v, holder.getAdapterPosition());
                if (mOnItemClickListener != null) {
                    mOnItemClickListener.onItemClick(v, holder.getAdapterPosition());
                }
            }
        });
        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                onItemLongClick(v, holder.getAdapterPosition());
                if (mOnItemLongClickListener != null) {
                    mOnItemLongClickListener.onItemLongClick(v, holder.getAdapterPosition());
                }
                return true;
            }
        });
        onBindViewHolder(holder, items.get(position), position);
    }

    public abstract VH onCreateViewHolder(View view);

    /**
     * @param item 為當前 item 對應的數據
     */
    public abstract void onBindViewHolder(VH holder, DATA item, int position);

    @LayoutRes
    public abstract int getLayoutResId();

    /**
     * 會先調用此方法,再調用 OnItemClickListener 中的 onItemClick。
     */
    protected void onItemClick(View view, int position) {
    }

    /**
     * 會先調用此方法,再調用 setOnItemLongClickListener 中的 onItemLongClick。
     */
    protected void onItemLongClick(View view, int position) {
    }

    // =========================================================
    // Listeners
    // =========================================================

    protected OnItemClickListener mOnItemClickListener;
    protected OnItemLongClickListener mOnItemLongClickListener;

    public void setOnItemClickListener(OnItemClickListener listener) {
        mOnItemClickListener = listener;
    }

    public void setOnItemLongClickListener(OnItemLongClickListener listener) {
        mOnItemLongClickListener = listener;
    }

    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }

    public interface OnItemLongClickListener {
        void onItemLongClick(View view, int position);
    }
}

五、Adapter

這裡直接繼承上面封裝好的Adapter就行。 
onCreateViewHolder(View view)返回的是ViewHolder對象。ViewHolder類是必須有的,而且要繼承RecyclerView.ViewHolder 
onBindViewHolder(ViewHolder holder, String item, int position)就是把數據和view綁定起來,其中item就是item具體的數據了。 
getLayoutResId()返回的就是這個item的佈局了。

package com.audienl.recyclerviewdemo.adapters;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;

import com.audienl.recyclerviewdemo.R;

import butterknife.Bind;
import butterknife.ButterKnife;

/**
 * @author AudienL([email protected]) on 2016/4/22
 */
public class RVAdapter extends SuperRVAdapter<String, RVAdapter.ViewHolder> {

    public RVAdapter(Context context) {
        super(context);
    }

    @Override
    public ViewHolder onCreateViewHolder(View view) {
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, String item, int position) {
        holder.mTvText.setText(item);
    }

    @Override
    public int getLayoutResId() {
        return R.layout.item_recycler_view;
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        @Bind(R.id.tv_text)
        TextView mTvText;

        public ViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }
}

六、Activity

package com.audienl.recyclerviewdemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;

import com.audienl.recyclerviewdemo.adapters.RVAdapter;
import com.audienl.recyclerviewdemo.adapters.SuperRVAdapter;

import butterknife.Bind;
import butterknife.ButterKnife;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    @Bind(R.id.recycler_view)
    RecyclerView mRecyclerView;

    private RVAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        // 數據源
        mAdapter = new RVAdapter(this);
        for (int i = 0; i < 20; i++) {
            mAdapter.addItem("AudienL -> " + i);
        }

        // 設置佈局
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        // 設置Adapter
        mRecyclerView.setAdapter(mAdapter);

        // 設置單擊事件
        mAdapter.setOnItemClickListener(new SuperRVAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                Log.i(TAG, "onItemClick: position=" + position);
            }
        });

        // 設置長按事件
        mAdapter.setOnItemLongClickListener(new SuperRVAdapter.OnItemLongClickListener() {
            @Override
            public void onItemLongClick(View view, int position) {
                Log.i(TAG, "onItemLongClick: position=" + position);
            }
        });
    }
}

 


 

整個使用DEMO大概就是醬紫。哪裡寫錯了留個言我改下。

源代碼: https://github.com/AudienL/RecyclerViewDemo (源代碼會不斷更新,可能和博客的代碼不同步)

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在Android開發過程中,有很多東西都是常常用到的,為了提高效率,將常用的方法做個記錄。 1.在網路編程中,如果還沒建立套接字就使用發送write,會出現異常,封裝後沒問題了(若發送byte[]型自己更改參數類型): public static boolean sendMsg(OutputStre ...
  • 與其他編程語言所不同的是,Swift 並不要求你為自定義類和結構去創建獨立的介面和實現文件。你所要做的是在一個單一文件中定義一個類或者結構體,系統將會自動生成面向其它代碼的外部介面。 註意:通常一個類的實例被稱為對象。然而在Swift 中,類和結構體的關係要比在其他語言中更加的密切,本章中所討論的大 ...
  • 第一種方法:如果使用導航第一個按鈕方法:[self.navigationController pushViewController:secondVC animated:YES];第二個按鈕方法:[self.navigationController popViewControllerAnimated: ...
  • copy與retain的區別: copy是創建一個新對象,retain是創建一個指針,引用對象計數加1。Copy屬性表示兩個對象內容相同,新的對象retain為1 ,與舊有對象的引用計數無關,舊有對象沒有變化。copy減少對象對上下文的依賴。 retain屬性表示兩個對象地址相同(建立一個指針,指針 ...
  • 傳值方式 1 初始化傳值:(順傳) 自定義初始化方法在 UI中,一般在一個界面推送另一個界面的時候,因此要是想用想到既然要用自定義初始化方法,至少要在該方法中去創建該對象.所以這種方式不適合回調. 自定義初始化方法,將需要傳遞的內容作為參數,如需要傳遞多個,則設置多個參數. 在合適的地方進行調用自定 ...
  • 傳值 1 順向傳值 順傳 屬性傳值 運行方式為 A à B 原理: 在B頁面的控制器中,創建需要的屬性,由於控制器是由 A 跳到 B 的,因此可以在 A 中拿到 B 中的屬性,直接賦值.(賦值在控制器跳轉的時候完成) 在 B 中定義一個屬性 在 A 中拿到 B 的非私有屬性 在 A 中直接對 A 拿 ...
  • title: Android學習路線總結,絕對乾貨 tags: Android學習路線,Android學習資料,怎麼學習android grammar_cjkRuby: true 一、前言 不知不覺自己已經做了幾年開發了,由記得剛出來工作的時候感覺自己能牛逼,現在回想起來感覺好無知。懂的越多的時候你 ...
  • 1、今天我們來分析Service中的一個小技巧:前臺服務(Forground Service) 【問題】:我們都知道服務是運行在後臺的,如果系統出現記憶體不足的情況,那麼此時,系統就可能回收後代的服務,那麼我們如何保證服務可以一直運行? 【解決】:在服務中,有一個前臺服務的概念,調用startForg ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...