How to Use an Adapter to Populate a RecyclerView in Android
This article walks through the complete process of adding a RecyclerView to an Android project, including the required support library dependency, creating the layout and item XML files, implementing a custom Adapter with ViewHolder, overriding the essential methods, and updating the view with a dynamic data source such as recorded audio file paths.
Overview
RecyclerView is a more powerful Android UI component than ListView, supporting both vertical and horizontal scrolling and addressing many ListView shortcomings. It resides in the Android support library, so the appropriate dependency must be added to build.gradle.
Adding the Dependency
implementation 'com.android.support:recyclerview-v7:30.0.0'Ensure the version matches the project's compileSdkVersion.
Layout Files
The main activity layout ( activity_main.xml) contains a RecyclerView and a bottom RelativeLayout with an ImageView for triggering audio recording.
<?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.RecyclerView
android: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" />
<RelativeLayout
android:id="@+id/layout_bottom"
android:layout_width="match_parent"
android:layout_height="101dp"
android:background="#F7F7F7"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent">
<ImageView
android:id="@+id/img_voice"
android:layout_width="66dp"
android:layout_height="66dp"
android:background="@mipmap/ic_launcher"
android:layout_centerInParent="true" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>The item layout ( layout_chat_item.xml) defines a simple horizontal LinearLayout with a single TextView to display each chat entry.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/chat_item"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center" />
</LinearLayout>Data Model
A ChatBean class encapsulates the audio‑message data, including fields such as id, content, sendTime, and others. The nested static class ChatItem holds the individual record attributes.
public class ChatBean {
private String msg;
private int code;
@NonNull private String id = "";
private List<ChatItem> data;
// getters and setters omitted for brevity
public static class ChatItem {
private int id;
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;
// getters and setters omitted for brevity
}
}Adapter Implementation
The custom ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolder>. It holds a List<ChatBean.ChatItem> as its data source and provides a setmEntityList method that updates the list and calls notifyDataSetChanged() to refresh the UI.
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
@Override
public 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);
}
@Override
public void onBindViewHolder(@NonNull ChatViewHolder holder, int position) {
holder.mText.setText(mEntityList.get(position).getContent().toString());
}
@Override
public 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);
}
}
}Initializing RecyclerView in Activity
In MainActivity, the RecyclerView is obtained via findViewById, a LinearLayoutManager is set, and the ChatAdapter is attached.
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private List<ChatBean.ChatItem> chatItemList;
private ChatAdapter chatAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initRecyclerView();
}
private void initRecyclerView() {
mRecyclerView = findViewById(R.id.recycler);
chatItemList = new ArrayList<>();
chatAdapter = new ChatAdapter();
LinearLayoutManager manager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(manager);
mRecyclerView.setAdapter(chatAdapter);
}
}Updating the Data Source
When an audio recording finishes, a new ChatBean.ChatItem is created, populated with the file path and timestamp, added to chatItemList, and the adapter is notified via setmEntityList. The RecyclerView then automatically displays the new entry.
@Override
public 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);
}Result
Running the app shows a RecyclerView that updates in real time with the paths of recorded audio files, demonstrating how an Adapter bridges complex data structures to the UI component.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
The Dominant Programmer
Resources and tutorials for programmers' advanced learning journey. Advanced tracks in Java, Python, and C#. Blog: https://blog.csdn.net/badao_liumang_qizhi
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
