Android 在Recyclerview的一个文本视图中显示相同键的值
我有下面的JSON,我正在GSON中解析并改进它。我想在一个文本视图中显示相同Android 在Recyclerview的一个文本视图中显示相同键的值,android,android-recyclerview,pojo,Android,Android Recyclerview,Pojo,我有下面的JSON,我正在GSON中解析并改进它。我想在一个文本视图中显示相同id的值。现在发生的事情是,所有的值都被添加到数组中,并显示在单独的文本视图中。我想在一个文本视图中显示具有相同id的所有值。例如,id:240ab值应在一个文本视图中。目前,所有ab值都在单独的文本视图中 这是数据当前的显示方式: 我希望数据是这样的: JSON:: { "abc": { "1": { "1": {
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适配器的完整代码
和
2ViewHolder
类,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"));
}