Android 在Recyclerview的一个文本视图中显示相同键的值

Android 在Recyclerview的一个文本视图中显示相同键的值,android,android-recyclerview,pojo,Android,Android Recyclerview,Pojo,我有下面的JSON,我正在GSON中解析并改进它。我想在一个文本视图中显示相同id的值。现在发生的事情是,所有的值都被添加到数组中,并显示在单独的文本视图中。我想在一个文本视图中显示具有相同id的所有值。例如,id:240ab值应在一个文本视图中。目前,所有ab值都在单独的文本视图中 这是数据当前的显示方式: 我希望数据是这样的: JSON:: { "abc": { "1": { "1": {

我有下面的JSON,我正在GSON中解析并改进它。我想在一个文本视图中显示相同
id
的值。现在发生的事情是,所有的值都被添加到数组中,并显示在单独的文本视图中。我想在一个文本视图中显示具有相同
id
的所有值。例如,
id:240
ab
值应在一个文本视图中。目前,所有
ab
值都在单独的文本视图中

这是数据当前的显示方式:

我希望数据是这样的:

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"
      }
    }
  }
}

内容::

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

}
myContentRapper::

public class MyContentWrapper {
    public Map<Integer, MyMap> abc;
}
公共类mycontentrapper{
公共地图abc;
}
MyMap::

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);
    }
}
公共类MyMap扩展了HashMap{
@凌驾
公共POJOContent put(整型键,POJOContent值){
if(null==value.getContent()| | value.getContent().isBlank()){
返回null;
}
//仅当content=“ab”不为空时添加。
返回super.put(键、值);
}
}
回拨:

    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();
                }
            };
Callback myCallback=new Callback(){
@凌驾
公共void onResponse(调用、响应){
if(response.issusccessful()){
Log.d(“回调”,“消息:+response.raw());
Log.d(“回调”,“消息:”+response.body().abc.values());
myContentRapper contentWrapper=response.body();
List pojo=new ArrayList();
for(Map.Entry:contentWrapper.abc.entrySet()){
整数key=entry.getKey();
MyMap map=entry.getValue();
如果(!map.isEmpty()){
Log.d(“回调”,“键:+Key”);
Log.d(“回调”,“值:+map.values());
addAll(map.values());
}
}
MyContentViewAdapter适配器=新的MyContentViewAdapter(pojo);
recyclerView.setAdapter(适配器);
}否则{
Log.d(“回调”,“代码:+response.Code()+”消息:+response.Message());
}
}
@凌驾
失败时公共无效(调用调用,可丢弃的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();
    }

}
公共类MyContentViewAdapter扩展了RecyclerView.Adapter{
私人名单数据;
私有MyClickListener clickListener;
公共类ViewHolder扩展了RecyclerView.ViewHolder{
公共文本查看文本;
私人线路布局项目布局;
公共视图持有者(视图v){
超级(五);
text=(TextView)v.findViewById(R.id.text\u内容);
}
}
公共内容视图(列表数据){
这个数据=数据;
Log.d(“Recyclerview数据”,Data.toString());
}
@凌驾
public MyContentViewAdapter.ViewHolder onCreateViewHolder(视图组父级,int-viewType){
观点五;
v=LayoutInflater.from(parent.getContext()).flate(R.layout.fragment\u content\u card,parent,false);
返回新的MyContentViewAdapter.ViewHolder(v);
}
@凌驾
BindViewHolder上的public void(MyContentViewAdapter.ViewHolder,int位置){
POJOContent pojo=data.get(位置);
Log.d(“Recyclerview”,pojo.getContent());
holder.text.setText(pojo.getContent());
holder.itemView.setTag(pojo.getContent());
}
public void setOnItemClickListener(MyClickListener clickListener){
this.clickListener=clickListener;
}
@凌驾
public int getItemCount(){
返回data.size();
}
}

根据我对问题描述的理解,您正在尝试这样构造数组

[
"some content"+"some content"+"some content", // id = 240
"more content"+"more content 1"+"more content 2" // id = 241
]
您希望在TextView列表中显示这两个值

但是你构建的数组是

[
"some content",
"some content",
"some content",
"more content",
"more content 1",
"more content 2"
]
因此,每个条目都显示在单独的文本视图中

要进一步调试,请在调试后检查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
适配器的完整代码
和 2
ViewHolder
类,2个xml布局和屏幕截图

我很确定它也会在非常大的列表中运行得非常顺利。

ID(240241)下的所有内容都是另一个recyclerView

其思想是,列表的大小对于要填充自身的适配器来说,应该与不同ID的数量一样多,这样只有那么多的
视图持有者
被膨胀

 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);
List-listofpoPolists=new-ArrayList();
for(Map.Entry:contentWrapper.abc.entrySet()){
整数key=entry.getKey();
MyMap map=entry.getValue();
如果(!map.isEmpty()){
Log.d(“回调”,“键:+Key”);
Log.d(“回调”,“值:+map.values());
添加(新的ArrayList(map.values());
}
}
MyContentViewAdapter适配器=新的MyContentViewAdapter(项目列表);
recyclerView.setAdapter(适配器);

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);
    }
}
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());
    }
}
公共类MyContentViewAdapter扩展了RecyclerView.Adapter{
私人名单数据;
私有MyClickListener clickListener;
MyContentViewAdapter(列表数据){
这个数据=数据;
}
@凌驾
public MyContentViewAdapter.ViewHolder onCreateViewHolder(视图组父级,int-viewType){
视图v=LayoutInflater.from(parent.getContext())
.充气(R.layout.fr
    <?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>
    <?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>
class ListItem {
    private var item: HashMap<Int, POJOContent>? = null
}
@Override
public String toString() {
    return value + "\n" + content;
}
//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"));
}