I am trying to make a nested RecyclerView
message system that looks like this:
https://i.stack.imgur.com/Vk4Xb.png
How I want to implement this is to indent each child (depth * 16dp
). Additionally, I need to be able to make it so that if a user clicks a message, it collapses/expands its children messages.
The messages come in the form of a JSON response that looks like this:
[
{
"id":1,
"parent_id":0,
"depth":0,
"text":"This is a top-level message (depth of 0)",
"children":[
{
"id":2,
"parent_id":1,
"depth":1,
"text":"This is a child message (depth of 1)",
"children":[
{
"id":3,
"parent_id":2,
"depth":2,
"text":"This is a child message (depth of 2)",
"children":[
]
}
]
},
{
"id":4,
"parent_id":1,
"depth":1,
"text":"This is a child message (depth of 1)",
"children":[
]
}
]
},
{
"id":5,
"parent_id":0,
"depth":0,
"text":"This is a top-level message (depth of 0)",
"children":[
{
"id":6,
"parent_id":5,
"depth":1,
"text":"This is a child message (depth of 1)",
"children":[
]
}
]
}
]
The JSON is pretty self-explanatory. Each message has a children
property that can contain more messages.
My current code outputs the following result:
https://i.stack.imgur.com/lKQW1.png
As you can see, it's not showing any children messages. How can I modify my code to:
- Show the children messages and indent them properly
- Create a click event so that if a user clicks a message, it hides/shows the children messages
Here is my MainActivity.java
:
public class MainActivity extends AppCompatActivity {
private List<Message> messages;
private RecyclerView recyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private MessageAdapter messageAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
// Set the adapter
messageAdapter = new MessageAdapter(MainActivity.this, messages);
recyclerView.setAdapter(messageAdapter);
}
}
And here is my MessageAdapter.java
:
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.ViewHolder> {
private Context context;
private List<Message> messages;
public MessageAdapter(Context context, List<Message> messages) {
this.context = context;
this.messages = messages;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public Message message;
public RelativeLayout messageContainer;
public TextView messageText;
public ViewHolder(View v) {
super(v);
messageContainer = (RelativeLayout) v.findViewById(R.id.messageContainer);
messageText = (TextView) v.findViewById(R.id.messageText);
}
public void setMessage(Message message) {
this.message = message;
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.message_layout, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final Message message = messages.get(position);
holder.setMessage(message);
holder.message.setText(message.getText());
}
@Override
public int getItemCount() {
return messages.size();
}
}
Here is my message_layout.xml
:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/messageContainer">
<TextView
android:id="@+id/messageText"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
And lastly, here is my Message.java
model class:
public class Message implements Serializable {
@SerializedName("id")
@Expose
private Integer id;
@SerializedName("parent_id")
@Expose
private Integer parentId;
@SerializedName("depth")
@Expose
private Integer depth;
@SerializedName("text")
@Expose
private String text;
@SerializedName("children")
@Expose
private List<Message> children = null;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getParentId() {
return parentId;
}
public void setParentId(Integer parentId) {
this.parentId = parentId;
}
public Integer getDepth() {
return depth;
}
public void setDepth(Integer depth) {
this.depth = depth;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public List<Message> getChildren() {
return children;
}
public void setChildren(List<Message> children) {
this.children = children;
}
}