我正在尝试创建一个看起来像这样的嵌套RecyclerView
消息系统:
http://i.imgur.com/Oodhv44.png
我想如何实现这个是缩进每个孩子(depth * 16dp
)。此外,我需要能够创建它,以便在用户单击消息时,它会折叠/展开其子消息。
消息以JSON响应的形式出现,如下所示:
[
{
"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":[
]
}
]
}
]
JSON非常明显。每条消息都有一个children
属性,可以包含更多消息。
我当前的代码输出以下结果:
http://i.imgur.com/anI2pyM.png
正如您所看到的,它没有显示任何儿童消息。如何将代码修改为:
这是我的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);
}
}
这是我的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();
}
}
这是我的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>
最后,这是我的Message.java
模型类:
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;
}
}
答案 0 :(得分:0)
在setMessage
的{{1}}中,您只需将填充应用于ViewHolder
即可。
RelativeLayout
编辑:
实际上,最好在适配器的构造函数中计算填充,这样你只需要计算一次,但这只是一个小细节。
编辑2:
对于第1点:您需要将子项展平,以便它们位于适配器中的一个长连续列表中。只要您按顺序保存它们,它们就会按照RecyclerView的顺序显示。因此,您需要以递归方式关闭每条消息并将子项添加到适配器列表中。
你可以在模型中做一个简单的方法来像这样展平它们:
public class ViewHolder extends RecyclerView.ViewHolder {
private final padding;
public Message message;
public RelativeLayout messageContainer;
public TextView messageText;
public ViewHolder(View v) {
super(v);
// Get the padding offset in pixels.
Resources r = v.getContext().getResources();
padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, r.getDisplayMetrics());
messageContainer = (RelativeLayout) v.findViewById(R.id.messageContainer);
messageText = (TextView) v.findViewById(R.id.messageText);
}
public void setMessage(Message message) {
this.message = message;
// Set the padding of the relativelayout.
final depth = this.message.getDepth();
messageContainer.setPadding(depth * 16, 0, 0, 0); // left, top, right, bottom
}
}
对于第2点:您需要set up a click listener来监听项目点击次数。然后,您需要确定单击时要删除的项目数。这个逻辑比较复杂,所以它不仅仅需要对适配器进行简单的修改。但基本上,在你的模型中,创建一个名为&#34; getTotalNumberOfChildren&#34;这将计算整个树中有多少个节点。像这样:
public class Message implements Serializable {
public List<Message> flattenChildren() {
ArrayList<Message> childs = new ArrayList();
if(children != null) {
for (Message m : children) {
// First add the child then request the flattened children of that child.
childs.add(m);
childs.addAll(m.flattenChildren());
}
}
return childs;
}
}
然后,只要用户点击某条消息,就可以删除该索引中的消息数。如果消息已经关闭,请重新添加。