在 Recyclerview 的一个 TextView 中显示相同键的值
Show values of same key in one TextView in Recyclerview
我在 GSON 和 Retrofit 中解析了以下 JSON。我想在一个 TextView 中显示相同 id
的值。现在发生的是所有值都添加到数组中,并且它们显示在单独的 TextView 中。我想在一个 TextView 中显示所有具有相同 id
的值。例如。 id: 240
ab
值应该在一个 TextView 中。目前,所有 ab
值都在单独的 TextView 中。
这是数据当前的显示方式:
这就是我想要的数据:
JSON::
{
"abc": {
"1": {
"1": {
"ab": "some content",
"id": "240",
"key": "value"
},
"2": {
"ab": "some content",
"id": "240",
"key": "value"
},
"3": {
"ab": "some content",
"id": "240",
"key": "value"
}
},
"2": {
"1": {
"ab": "more content",
"id": "241",
"key": "value"
},
"2": {
"ab": "more content 1",
"id": "241",
"key": "value"
},
"3": {
"ab": "more content 2",
"id": "241",
"key": "value"
}
}
}
}
POJOContent::
public class POJOContent {
@SerializedName("ab")
public String content;
@SerializedName("id")
public String id;
@SerializedName("key")
public String key;
@Override
public String toString() {
return content;
}
//getters and setters
}
MyContentWrapper::
public class MyContentWrapper {
public Map<Integer, MyMap> abc;
}
我的地图::
public class MyMap extends HashMap<Integer, POJOContent> {
@Override
public POJOContent put(Integer key, POJOContent value) {
if(null==value.getContent() || value.getContent().isBlank()) {
return null;
}
// Added only if content = "ab" is not blank.
return super.put(key, value);
}
}
回调:
Callback<MyContentWrapper> myCallback = new Callback<MyContentWrapper>() {
@Override
public void onResponse(Call<MyContentWrapper> call, Response<MyContentWrapper> response) {
if (response.isSuccessful()) {
Log.d("Callback", " Message: " + response.raw());
Log.d("Callback", " Message: " + response.body().abc.values());
MyContentWrapper contentWrapper = response.body();
List<POJOContent> pojo = new ArrayList<>();
for (Map.Entry<Integer, MyMap> entry : contentWrapper.abc.entrySet()) {
Integer key = entry.getKey();
MyMap map = entry.getValue();
if (!map.isEmpty()){
Log.d("Callback", " Key: " + key);
Log.d("Callback", " Value: " + map.values());
pojo.addAll(map.values());
}
}
MyContentViewAdapter adapter = new MyContentViewAdapter(pojo);
recyclerView.setAdapter(adapter);
} else {
Log.d("Callback", "Code: " + response.code() + " Message: " + response.message());
}
}
@Override
public void onFailure(Call<MyContentWrapper> call, Throwable t) {
t.printStackTrace();
}
};
回收适配器::
public class MyContentViewAdapter extends RecyclerView.Adapter<MyContentViewAdapter.ViewHolder> {
private List<POJOContent> data;
private MyClickListener clickListener;
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView text;
private LinearLayout itemLayout;
public ViewHolder(View v) {
super(v);
text = (TextView) v.findViewById(R.id.text_content);
}
}
public MyContentViewAdapter(List<POJOContent> data) {
this.data = data;
Log.d("Recyclerview Data", data.toString());
}
@Override
public MyContentViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_content_card, parent, false);
return new MyContentViewAdapter.ViewHolder(v);
}
@Override
public void onBindViewHolder(MyContentViewAdapter.ViewHolder holder, int position) {
POJOContent pojo = data.get(position);
Log.d("Recyclerview", pojo.getContent());
holder.text.setText(pojo.getContent());
holder.itemView.setTag(pojo.getContent());
}
public void setOnItemClickListener(MyClickListener clickListener) {
this.clickListener = clickListener;
}
@Override
public int getItemCount() {
return data.size();
}
}
根据我对问题描述的理解,你是这样构造数组的
[
"some content"+"some content"+"some content", // id = 240
"more content"+"more content 1"+"more content 2" // id = 241
]
并且您想在 TextView 列表中显示这 2 个值
但是你构建的数组将是,
[
"some content",
"some content",
"some content",
"more content",
"more content 1",
"more content 2"
]
因此每个条目都显示在单独的 TextView 中
要进一步调试,请在
之后检查pojo列表的值
pojo.addAll(map.values())
// may be if you want to group entries with comma delimiter, use
// pojo.addAll(TextUtils.join(", ", map.values()))
编辑:
我在 ViewHolder
中添加了嵌套 RecyclerView
,因此内容和值字段将动态显示。我正在添加 2 Adapter
的完整代码和
2 ViewHolder
类、2 xml 布局和屏幕截图
我很确定它也会 运行 非常顺利地处理非常大的列表。
ID(240,241) 下的所有内容都是另一个 recyclerView。
想法是 list 的大小,为了适配器填充自身,应该和不同 id 的数量一样多,所以只有那么多 Viewholders
膨胀。
List<List<POJOContent>> listOfPojoLists = new ArrayList<>();
for (Map.Entry<Integer, MyMap> entry : contentWrapper.abc.entrySet()) {
Integer key = entry.getKey();
MyMap map = entry.getValue();
if (!map.isEmpty()){
Log.d("Callback", " Key: " + key);
Log.d("Callback", " Value: " + map.values());
listOfPojoLists.add(new ArrayList<>(map.values()));
}
}
MyContentViewAdapter adapter = new MyContentViewAdapter(listOfPojoLists);
recyclerView.setAdapter(adapter);
MyContentViewAdapter.java
public class MyContentViewAdapter extends RecyclerView.Adapter<MyContentViewAdapter.ViewHolder> {
private List<List<POJOContent>> data;
private MyClickListener clickListener;
MyContentViewAdapter(List<List<POJOContent>> data) {
this.data = data;
}
@Override
public MyContentViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.fragment_content_card, parent, false);
return new MyContentViewAdapter.ViewHolder(v);
}
@Override
public void onBindViewHolder(MyContentViewAdapter.ViewHolder holder, int position) {
holder.bind(data.get(position));
}
public void setOnItemClickListener(MyClickListener clickListener) {
this.clickListener = clickListener;
}
@Override
public int getItemCount() {
return data.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView textId;
private InnerListAdapter innerAdapter;
// inside constructor we are initializing inner recyclerView and inner Adapter.
// there will only be 3 - 5 instances of them ever created(using this
// particular viewHolder layouts), no more.
// might be slightly more if u use layouts with lower height
ViewHolder(View v) {
super(v);
textId = v.findViewById(R.id.tv_Id);
RecyclerView innerRecycler = v.findViewById(R.id.rv_inner_list);
// I added DividerItemDecoration so it would be clear that there are actually different viewHolders
// displayed by recyclerView
innerRecycler.addItemDecoration(new DividerItemDecoration(v.getContext(), DividerItemDecoration.VERTICAL));
innerAdapter = new InnerListAdapter();
innerRecycler.setAdapter(innerAdapter);
}
/* We just submit new list for our inner adapter
so it will handle rebinding values to its viewHolders */
void bind(List<POJOContent> pojoList){
textId.setText(pojoList.get(0).id);
innerAdapter.setNewItems(pojoList);
}
}
}
InnerListAdapter.java
public class InnerListAdapter extends RecyclerView.Adapter<InnerListAdapter.InnerViewHolder> {
private List<POJOContent> items = new ArrayList<>();
@NonNull
@Override
public InnerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new InnerViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_inner_list, parent, false));
}
@Override
public void onBindViewHolder(@NonNull InnerViewHolder holder, int position) {
holder.bind(items.get(position));
}
@Override
public int getItemCount() {
return items.size();
}
void setNewItems(List<POJOContent> newItems){
items.clear();
items.addAll(newItems);
notifyDataSetChanged();
}
class InnerViewHolder extends RecyclerView.ViewHolder{
TextView tv_value;
TextView tv_content;
InnerViewHolder(@NonNull View itemView) {
super(itemView);
tv_value = itemView.findViewById(R.id.tv_value);
tv_content = itemView.findViewById(R.id.tv_content);
}
void bind(POJOContent pojoContent){
tv_value.setText(pojoContent.getKey());
tv_content.setText(pojoContent.getContent());
}
}
}
fragment_content_card.xml 主 recyclerView viewholder 的布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="8dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_Id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:textSize="32sp"
android:textColor="@color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="ID" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_inner_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_Id" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
item_inner_list.xml 内部 recylerVoews viewholder 的布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:textColor="@color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="value" />
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:textColor="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_value"
tools:text="content" />
</androidx.constraintlayout.widget.ConstraintLayout>
根据您的问题,您有不同的问题需要解决:
1 - 更好地定义您拥有的数据。您目前有 POJOContent
,但您想要显示类似 POJOContentGroup
的内容,因此在进入视图部分之前,您需要预处理数据并将其从 MyContentWrapper
映射到 List<POJOContentGroup>
.
data class POJOContentGroup(val id: String, val contentList: List<POJOContent>)
(为简洁起见,这是在 Kotlin 中)
2 - 有了之前的定义,现在您有一个简单的任务:显示 POJOContentGroup
的列表。基于此创建您的回收站视图,类似于您最初所做的,不同之处在于项目布局将是 id
的 TextView
和 [=] 的 RecyclerView
19=],这是你目前拥有的那个。
嗨,来晚了,但我会说创建一个 class ListItem
class ListItem {
private var item: HashMap<Int, POJOContent>? = null
}
并将 POJOContent 中的 toString 覆盖为 return 您希望在文本视图中显示的值,如
@Override
public String toString() {
return value + "\n" + content;
}
然后在你的适配器中使用 List
然后在绑定
//take care of null checks and you can use System.getProperty("line.separator"); in place of line saperator also don't forgate to set maxLine property of your text view to eome higher value
void bind(ListItem item){
Array<POJOContent> contents = item.values().toArray()
tv_value.setText(contents[0].getKey());
tv_content.setText(contents.toString().replace("[","").replace("]","").replace(",","\n"));
}
为具有内容和键列表的 RV 列表项创建另一个 pojo class
public class POJOListItem {
public String id;
public List<String> contents = new ArrayList<>();
public List<String> keys = new ArrayList<>();
}
然后验证并将 MyContentWrapper
对象映射到 List<POJOListItem>
,检查列表是否包含 id,如果它具有相同的 id,则将它们添加到 contents
和 keys
列出或创建一个新项目并添加它。根据列表大小在视图持有者内的容器布局中动态添加项目。
查看这个小型演示项目https://github.com/toxic-charger/SO-63045236
测试了 50000 多个项目没有性能问题
我认为 nested-expandable-recyclerview 应该是实现您目标的正确选择,这也会增加您的 用户体验 。默认情况下可以使用 JSON.
的子数据打开嵌套回收器
我在 GSON 和 Retrofit 中解析了以下 JSON。我想在一个 TextView 中显示相同 id
的值。现在发生的是所有值都添加到数组中,并且它们显示在单独的 TextView 中。我想在一个 TextView 中显示所有具有相同 id
的值。例如。 id: 240
ab
值应该在一个 TextView 中。目前,所有 ab
值都在单独的 TextView 中。
这是数据当前的显示方式:
这就是我想要的数据:
JSON::
{
"abc": {
"1": {
"1": {
"ab": "some content",
"id": "240",
"key": "value"
},
"2": {
"ab": "some content",
"id": "240",
"key": "value"
},
"3": {
"ab": "some content",
"id": "240",
"key": "value"
}
},
"2": {
"1": {
"ab": "more content",
"id": "241",
"key": "value"
},
"2": {
"ab": "more content 1",
"id": "241",
"key": "value"
},
"3": {
"ab": "more content 2",
"id": "241",
"key": "value"
}
}
}
}
POJOContent::
public class POJOContent {
@SerializedName("ab")
public String content;
@SerializedName("id")
public String id;
@SerializedName("key")
public String key;
@Override
public String toString() {
return content;
}
//getters and setters
}
MyContentWrapper::
public class MyContentWrapper {
public Map<Integer, MyMap> abc;
}
我的地图::
public class MyMap extends HashMap<Integer, POJOContent> {
@Override
public POJOContent put(Integer key, POJOContent value) {
if(null==value.getContent() || value.getContent().isBlank()) {
return null;
}
// Added only if content = "ab" is not blank.
return super.put(key, value);
}
}
回调:
Callback<MyContentWrapper> myCallback = new Callback<MyContentWrapper>() {
@Override
public void onResponse(Call<MyContentWrapper> call, Response<MyContentWrapper> response) {
if (response.isSuccessful()) {
Log.d("Callback", " Message: " + response.raw());
Log.d("Callback", " Message: " + response.body().abc.values());
MyContentWrapper contentWrapper = response.body();
List<POJOContent> pojo = new ArrayList<>();
for (Map.Entry<Integer, MyMap> entry : contentWrapper.abc.entrySet()) {
Integer key = entry.getKey();
MyMap map = entry.getValue();
if (!map.isEmpty()){
Log.d("Callback", " Key: " + key);
Log.d("Callback", " Value: " + map.values());
pojo.addAll(map.values());
}
}
MyContentViewAdapter adapter = new MyContentViewAdapter(pojo);
recyclerView.setAdapter(adapter);
} else {
Log.d("Callback", "Code: " + response.code() + " Message: " + response.message());
}
}
@Override
public void onFailure(Call<MyContentWrapper> call, Throwable t) {
t.printStackTrace();
}
};
回收适配器::
public class MyContentViewAdapter extends RecyclerView.Adapter<MyContentViewAdapter.ViewHolder> {
private List<POJOContent> data;
private MyClickListener clickListener;
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView text;
private LinearLayout itemLayout;
public ViewHolder(View v) {
super(v);
text = (TextView) v.findViewById(R.id.text_content);
}
}
public MyContentViewAdapter(List<POJOContent> data) {
this.data = data;
Log.d("Recyclerview Data", data.toString());
}
@Override
public MyContentViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_content_card, parent, false);
return new MyContentViewAdapter.ViewHolder(v);
}
@Override
public void onBindViewHolder(MyContentViewAdapter.ViewHolder holder, int position) {
POJOContent pojo = data.get(position);
Log.d("Recyclerview", pojo.getContent());
holder.text.setText(pojo.getContent());
holder.itemView.setTag(pojo.getContent());
}
public void setOnItemClickListener(MyClickListener clickListener) {
this.clickListener = clickListener;
}
@Override
public int getItemCount() {
return data.size();
}
}
根据我对问题描述的理解,你是这样构造数组的
[
"some content"+"some content"+"some content", // id = 240
"more content"+"more content 1"+"more content 2" // id = 241
]
并且您想在 TextView 列表中显示这 2 个值
但是你构建的数组将是,
[
"some content",
"some content",
"some content",
"more content",
"more content 1",
"more content 2"
]
因此每个条目都显示在单独的 TextView 中
要进一步调试,请在
之后检查pojo列表的值pojo.addAll(map.values())
// may be if you want to group entries with comma delimiter, use
// pojo.addAll(TextUtils.join(", ", map.values()))
编辑:
我在 ViewHolder
中添加了嵌套 RecyclerView
,因此内容和值字段将动态显示。我正在添加 2 Adapter
的完整代码和
2 ViewHolder
类、2 xml 布局和屏幕截图
我很确定它也会 运行 非常顺利地处理非常大的列表。
ID(240,241) 下的所有内容都是另一个 recyclerView。
想法是 list 的大小,为了适配器填充自身,应该和不同 id 的数量一样多,所以只有那么多 Viewholders
膨胀。
List<List<POJOContent>> listOfPojoLists = new ArrayList<>();
for (Map.Entry<Integer, MyMap> entry : contentWrapper.abc.entrySet()) {
Integer key = entry.getKey();
MyMap map = entry.getValue();
if (!map.isEmpty()){
Log.d("Callback", " Key: " + key);
Log.d("Callback", " Value: " + map.values());
listOfPojoLists.add(new ArrayList<>(map.values()));
}
}
MyContentViewAdapter adapter = new MyContentViewAdapter(listOfPojoLists);
recyclerView.setAdapter(adapter);
MyContentViewAdapter.java
public class MyContentViewAdapter extends RecyclerView.Adapter<MyContentViewAdapter.ViewHolder> {
private List<List<POJOContent>> data;
private MyClickListener clickListener;
MyContentViewAdapter(List<List<POJOContent>> data) {
this.data = data;
}
@Override
public MyContentViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.fragment_content_card, parent, false);
return new MyContentViewAdapter.ViewHolder(v);
}
@Override
public void onBindViewHolder(MyContentViewAdapter.ViewHolder holder, int position) {
holder.bind(data.get(position));
}
public void setOnItemClickListener(MyClickListener clickListener) {
this.clickListener = clickListener;
}
@Override
public int getItemCount() {
return data.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView textId;
private InnerListAdapter innerAdapter;
// inside constructor we are initializing inner recyclerView and inner Adapter.
// there will only be 3 - 5 instances of them ever created(using this
// particular viewHolder layouts), no more.
// might be slightly more if u use layouts with lower height
ViewHolder(View v) {
super(v);
textId = v.findViewById(R.id.tv_Id);
RecyclerView innerRecycler = v.findViewById(R.id.rv_inner_list);
// I added DividerItemDecoration so it would be clear that there are actually different viewHolders
// displayed by recyclerView
innerRecycler.addItemDecoration(new DividerItemDecoration(v.getContext(), DividerItemDecoration.VERTICAL));
innerAdapter = new InnerListAdapter();
innerRecycler.setAdapter(innerAdapter);
}
/* We just submit new list for our inner adapter
so it will handle rebinding values to its viewHolders */
void bind(List<POJOContent> pojoList){
textId.setText(pojoList.get(0).id);
innerAdapter.setNewItems(pojoList);
}
}
}
InnerListAdapter.java
public class InnerListAdapter extends RecyclerView.Adapter<InnerListAdapter.InnerViewHolder> {
private List<POJOContent> items = new ArrayList<>();
@NonNull
@Override
public InnerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new InnerViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_inner_list, parent, false));
}
@Override
public void onBindViewHolder(@NonNull InnerViewHolder holder, int position) {
holder.bind(items.get(position));
}
@Override
public int getItemCount() {
return items.size();
}
void setNewItems(List<POJOContent> newItems){
items.clear();
items.addAll(newItems);
notifyDataSetChanged();
}
class InnerViewHolder extends RecyclerView.ViewHolder{
TextView tv_value;
TextView tv_content;
InnerViewHolder(@NonNull View itemView) {
super(itemView);
tv_value = itemView.findViewById(R.id.tv_value);
tv_content = itemView.findViewById(R.id.tv_content);
}
void bind(POJOContent pojoContent){
tv_value.setText(pojoContent.getKey());
tv_content.setText(pojoContent.getContent());
}
}
}
fragment_content_card.xml 主 recyclerView viewholder 的布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="8dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_Id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:textSize="32sp"
android:textColor="@color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="ID" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_inner_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_Id" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
item_inner_list.xml 内部 recylerVoews viewholder 的布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:textColor="@color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="value" />
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:textColor="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_value"
tools:text="content" />
</androidx.constraintlayout.widget.ConstraintLayout>
根据您的问题,您有不同的问题需要解决:
1 - 更好地定义您拥有的数据。您目前有 POJOContent
,但您想要显示类似 POJOContentGroup
的内容,因此在进入视图部分之前,您需要预处理数据并将其从 MyContentWrapper
映射到 List<POJOContentGroup>
.
data class POJOContentGroup(val id: String, val contentList: List<POJOContent>)
(为简洁起见,这是在 Kotlin 中)
2 - 有了之前的定义,现在您有一个简单的任务:显示 POJOContentGroup
的列表。基于此创建您的回收站视图,类似于您最初所做的,不同之处在于项目布局将是 id
的 TextView
和 [=] 的 RecyclerView
19=],这是你目前拥有的那个。
嗨,来晚了,但我会说创建一个 class ListItem
class ListItem {
private var item: HashMap<Int, POJOContent>? = null
}
并将 POJOContent 中的 toString 覆盖为 return 您希望在文本视图中显示的值,如
@Override
public String toString() {
return value + "\n" + content;
}
然后在你的适配器中使用 List 然后在绑定
//take care of null checks and you can use System.getProperty("line.separator"); in place of line saperator also don't forgate to set maxLine property of your text view to eome higher value
void bind(ListItem item){
Array<POJOContent> contents = item.values().toArray()
tv_value.setText(contents[0].getKey());
tv_content.setText(contents.toString().replace("[","").replace("]","").replace(",","\n"));
}
为具有内容和键列表的 RV 列表项创建另一个 pojo class
public class POJOListItem {
public String id;
public List<String> contents = new ArrayList<>();
public List<String> keys = new ArrayList<>();
}
然后验证并将 MyContentWrapper
对象映射到 List<POJOListItem>
,检查列表是否包含 id,如果它具有相同的 id,则将它们添加到 contents
和 keys
列出或创建一个新项目并添加它。根据列表大小在视图持有者内的容器布局中动态添加项目。
查看这个小型演示项目https://github.com/toxic-charger/SO-63045236
测试了 50000 多个项目没有性能问题
我认为 nested-expandable-recyclerview 应该是实现您目标的正确选择,这也会增加您的 用户体验 。默认情况下可以使用 JSON.
的子数据打开嵌套回收器