Android中使用Adapter(适配器)给RecycleView设置数据源
場景
RecyclerView
RecyclerView是Android一個更強大的控件,其不僅可以實現和ListView同樣的效果,還有優化了ListView中的各種不足。其可以實現數據縱向滾動,也可以實現橫向滾動(ListView做不到橫向滾動)。
因為RecyclerView屬于新增的控件,Android將RecyclerView定義在support庫里。若要使用RecyclerView,第一步是要在build.gradle中添加對應的依賴庫。
Adapter適配器
顧名思義,就是把一些數據給弄得適當,適合以便于在View上顯示。可以看作是界面數據綁定的一種理解。它所操縱的數據一般都是一些比較復雜的數據,如數組,鏈表,數據庫,集合等。適配器就像顯示器,把復雜的東西按人可以接受的方式來展現。
數據源是各種各樣的,而ListView所展示數據的格式則是有一定的要求的。數據適配器正是建立了數據源與ListView之間的適配關系,將數據源轉換為ListView能夠顯示的數據格式,從而將數據的來源與數據的顯示進行解耦,降低程序的耦合性。這也體現了Android的適配器模式的使用
RecycleView是對ListView以及GridView的升級,在使用的時候同源更新需要使用Adapter適配器。但是RecycleView使用的適配器并不是之前的BaseAdapter了。RecycleView使用的適配器需要繼承RecyclerView.Adapter<VH extends RecycleView.ViewHolder>
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
關注公眾號
霸道的程序猿
獲取編程相關電子書、教程推送與免費下載。
實現
創建RecyclerView
下面以一個示例入手看看怎樣使用一個Adapter給RecyclerView進行賦值。
首先新建一個項目,然后修改activity_main.xml的頁面布局如下
?
最終要實現的效果是點擊下面的imageView實現錄音,并將錄音文件的路徑顯示在上面的RecyclerView中。
關于錄音的實現不做講解,主要介紹錄音完成后使用Adapter給上面的RecyclerView添加數據源,這里以顯示錄音文件的路徑為例。
布局頁面activity_main.xml的代碼如下
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"xmlns:app="http://schemas.android.com/apk/res-auto"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recycler"android:layout_width="match_parent"android:layout_height="wrap_content"app:layout_constraintBottom_toTopOf="@+id/layout_bottom"app:layout_constraintTop_toTopOf="parent" /><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="101dp"android:id="@+id/layout_bottom"android:background="#F7F7F7"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintStart_toStartOf="parent"><ImageViewandroid:layout_width="66dp"android:layout_height="66dp"android:id="@+id/img_voice"android:background="@mipmap/ic_launcher"android:layout_centerInParent="true"/></RelativeLayout></androidx.constraintlayout.widget.ConstraintLayout>注意上面添加RecyclerView的全路徑以及添加id屬性。
添加依賴
然后添加依賴。打開項目下的build.gradle,添加依賴
implementation 'com.android.support:recyclerview-v7:30.0.0'注意這里的版本要與你上面的compileSdkVersion對應
?
創建item項的布局文件
然后為RecyclerView的item創建統一的布局文件,在layout下-New-XML-Layout XML File,這里命名為layout_chat_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="50dp"android:layout_gravity="center"android:orientation="horizontal"><TextViewandroid:id="@+id/chat_item"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center" /></LinearLayout>你可以在這里任意設計視圖,它將會應用在你RecyclerView中每個項上。
這里為了演示,值簡單添加了一個TextView,記得給這個TextView設置ID
創建Adapter
我們在項目下新建一個包adapter,并在包下新建類ChatAdapter。
這個CharAdapter需要繼承RecycleView.Adapter<>,并且泛型里面的類型是自定義的繼承自RecycleView.ViewHolder的類。
關于ViewHolder
ViewHolder的主要任務:容納View視圖。Adapter連接了后端數據和前端顯示,viewHolder的作用就是提供前端的視圖文件。
這個自定義ViewHolder可以是外部類,但是為了方便,將其作為ChatAdaprer的內部類
需要在自定義的ViewHolder中綁定視圖文件,就好像在MainActivity中綁定activity_main.xml布局文件一樣
這里需要綁定我們在上面新建的每一項的布局視圖,即layout_chat_item.xml,并且獲取到每一項布局視圖的控件。
所以此時的ChatAdapter的代碼如下
public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolder> {class ChatViewHolder extends RecyclerView.ViewHolder{private TextView mText;public ChatViewHolder(View itemView) {super(itemView);mText = (TextView) itemView.findViewById(R.id.chat_item);}} }注意此時還沒有重寫指定的三個方法。
此時我們先創建一個數據實體類ChatBean
package com.badao.audiodemo.bean;import androidx.annotation.NonNull; import java.util.List;public class ChatBean {private String msg;private int code;@NonNullprivate String id = "";private List<ChatItem> data;public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public List<ChatItem> getData() {return data;}public void setData(List<ChatItem> data) {this.data = data;}@NonNullpublic String getId() {return id;}public void setId(@NonNull String id) {this.id = id;}public static class ChatItem {private int id;private String msgNum;private String content;//語音消息服務器地址private String remoteContent;private String sender;private String receiver;private String type;private boolean canReceived;private String sendTime;private String receivedTime;//語音時長private int voiceDuration;private boolean isRead;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getMsgNum() {return msgNum;}public void setMsgNum(String msgNum) {this.msgNum = msgNum;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public String getSender() {return sender;}public void setSender(String sender) {this.sender = sender;}public String getReceiver() {return receiver;}public void setReceiver(String receiver) {this.receiver = receiver;}public String getType() {return type;}public void setType(String type) {this.type = type;}public boolean isCanReceived() {return canReceived;}public void setCanReceived(boolean canReceived) {this.canReceived = canReceived;}public String getSendTime() {return sendTime;}public void setSendTime(String sendTime) {this.sendTime = sendTime;}public String getReceivedTime() {return receivedTime;}public void setReceivedTime(String receivedTime) {this.receivedTime = receivedTime;}public int getVoiceDuration() {return voiceDuration;}public void setVoiceDuration(int voiceDuration) {this.voiceDuration = voiceDuration;}public String getRemoteContent() {return remoteContent;}public void setRemoteContent(String remoteContent) {this.remoteContent = remoteContent;}public boolean isRead() {return isRead;}public void setRead(boolean read) {isRead = read;}}}實體類的內容可以自己定義,這里是包含了語音消息實體的相關屬性。
然后再回到ChatAdapter,此時重寫其三個方法,然后新建上面實體的list作為數據源,并編寫其set方法
??? private List<ChatBean.ChatItem> mEntityList = new ArrayList<>();public void setmEntityList(List<ChatBean.ChatItem> mEntityList) {this.mEntityList = mEntityList;//一定要記得加,否則視圖不會更新!!!notifyDataSetChanged();}重寫onCreateViewHolder方法
返回我們的內部類MyViewHolder ,此處為將我們的item布局文件和adapter綁定。
??? @NonNull@Overridepublic ChatViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_chat_item, parent, false);return new ChatViewHolder(view);}重寫onBindViewHolder方法
對每一項的TextView進行賦值,取出實體的某一屬性進行顯示,position為下標。
??? @Overridepublic void onBindViewHolder(@NonNull ChatViewHolder holder, int position) {holder.mText.setText(mEntityList.get(position).getContent().toString());}重寫getItemCount方法
獲得實體list的長度,即顯示項的個數
??? @Overridepublic int getItemCount() {return mEntityList == null?0:mEntityList.size();}此時完整的ChatAdapter的代碼為:
package com.badao.audiodemo.adapter;import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView;import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView;import com.badao.audiodemo.R; import com.badao.audiodemo.bean.ChatBean;import java.util.ArrayList; import java.util.List;public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolder> {private List<ChatBean.ChatItem> mEntityList = new ArrayList<>();public void setmEntityList(List<ChatBean.ChatItem> mEntityList) {this.mEntityList = mEntityList;//一定要記得加,否則視圖不會更新!!!notifyDataSetChanged();}@NonNull@Overridepublic ChatViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_chat_item, parent, false);return new ChatViewHolder(view);}@Overridepublic void onBindViewHolder(@NonNull ChatViewHolder holder, int position) {holder.mText.setText(mEntityList.get(position).getContent().toString());}@Overridepublic int getItemCount() {return mEntityList == null?0:mEntityList.size();}class ChatViewHolder extends RecyclerView.ViewHolder{private TextView mText;public ChatViewHolder(View itemView) {super(itemView);mText = (TextView) itemView.findViewById(R.id.chat_item);}} }使用Adapter給RecycleView賦值
在MainActivity中先聲明所需對象
public class MainActivity extends AppCompatActivity {private RecyclerView mRecyclerView;private List<ChatBean.ChatItem> chatItemList;private? ChatAdapter chatAdapter;然后在onCreate方法中初始化
??? @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initRecyclerView();}/*** 初始化RecyclerView*/private void initRecyclerView(){mRecyclerView = findViewById(R.id.recycler);chatItemList = new ArrayList<>();chatAdapter = new ChatAdapter();// 定義一個線性布局管理器LinearLayoutManager manager = new LinearLayoutManager(this);// 設置布局管理器mRecyclerView.setLayoutManager(manager);// 設置adaptermRecyclerView.setAdapter(chatAdapter);}然后就是在需要對RecycleView進行賦值的地方,這里為例是在錄音結束后的回調方法中,也是在MainActivity中
??????? @Overridepublic void onFinish(Uri uri, int i) {File file = new File(uri.getPath());ChatBean.ChatItem chatItem = new ChatBean.ChatItem();chatItem.setId((int) System.currentTimeMillis());chatItem.setSendTime(new Date().toString());chatItem.setContent(file.getAbsolutePath());chatItemList.add(chatItem);chatAdapter.setmEntityList(chatItemList);}直接將實體類對象添加到list中并調用chatAdapter的set方法即可,就會自動在recycleView中更新數據
?
?
總結
以上是生活随笔為你收集整理的Android中使用Adapter(适配器)给RecycleView设置数据源的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AndroidStudio中提示:and
- 下一篇: Android中设置RecyclerVi