我有一个应用程序,可以将图片发送到我们的服务器,并接收有关服务器已识别内容的信息。有时服务器什么也没识别(不是很有趣的情况),有时一件事,有时不止一件事。
所以我必须在列表(RecyclerView)中显示的数据是一张照片(加上时间戳),然后是服务器识别出的一个或多个“事物”。
我的数据结构如下:
List<List<Thing>> masterList;
所以我有一个RecyclerView,其中包含2种可能的项目-单件物品-在其中显示图片,时间和事物信息,或者多件物品在其中显示图片,时间戳和事物列表
这是更高级别的适配器
public class ResultsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<List<Thing>> resultList;
private Context context;
public ResultsAdapter(List<List<Thing>> resultList) {
this.resultList = resultList;
}
@Override
@NonNull
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
RecyclerView.ViewHolder holder;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case 0: // regular single thing card
{
View itemView = inflater.inflate(R.layout.thing_item, parent, false);
holder = new ResultsHolder(itemView, listener);
break;
}
default: // multi thing card
{
View itemView = inflater.inflate(R.layout.compound_item, parent, false);
holder = new MultiThingResultsHolder(itemView, listener);
break;
}
}
return holder;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
Resources res = context.getResources();
switch (viewHolder.getItemViewType()) {
case 0: // regular single thing card
{
ResultsHolder holder = (ResultsHolder) viewHolder;
holder.time.setText(resultList.get(position).get(0).getTime());
if (resultList.get(position).get(0).getImage() != null) {
File thumbnailFile = new File(context.getFilesDir(), resultList.get(position).get(0).getImage());
holder.thumbnail.setImageURI(Uri.fromFile(thumbnailFile));
}
holder.amount.setText(res.getString(R.string.format_blahs, resultList.get(position).get(0).getAmount()));
.
.
.
.
break;
}
case 2: // multi thing card
{
MultiResultsHolder holder = (MultiResultsHolder) viewHolder;
holder.time.setText(resultList.get(position).get(0).getTime());
if (resultList.get(position).get(0).getImage() != null) {
File thumbnailFile = new File(context.getFilesDir(), resultList.get(position).get(0).getImage());
holder.thumbnail.setImageURI(Uri.fromFile(thumbnailFile));
}
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
holder.list.setLayoutManager(layoutManager);
List<Thing> subThingList = resultList.get(position);
MultiResultsAdapter adapter = new MultiResultsAdapter(subThingList, subListener, position);
holder.list.setAdapter(adapter);
break;
}
}
}
@Override
public int getItemViewType(int position) {
if (resultList.get(position).size() == 1) {
// this is a simple item
return 0;
}
// if we got here it's a multithing item
return 1;
}
@Override
public int getItemCount() {
return resultList.size();
}
public class ResultsHolder extends RecyclerView.ViewHolder {
private ImageView deleteX;
public TextView time;
private ImageView thumbnail;
private TextView amount;
.
.
.
.
private ResultsHolder(View view) {
super(view);
deleteX = view.findViewById(R.id.delete_button);
deleteX.setOnClickListener(this);
time = view.findViewById(R.id.tv_time);
thumbnail = view.findViewById(R.id.thumbnail);
amount = view.findViewById(R.id.tv_amount);
.
.
.
.
}
}
private class MultiResultsHolder extends RecyclerView.ViewHolder {
private ImageView thumbnail;
public TextView time;
public RecyclerView list;
private MultiResultsHolder(View view) {
super(view);
time = view.findViewById(R.id.tv_time);
list = view.findViewById(R.id.list); // <-- the inner Recycler
thumbnail = view.findViewById(R.id.thumbnail);
}
}
}
所以我有一个内部适配器,它可以在简单的List<Thing>
public class MultiResultsAdapter extends RecyclerView.Adapter<MultiResultsAdapter.MultiResultsHolder> {
private List<Thing> thingList;
private Context context;
public MultiResultsAdapter(List<Thing> thingList) {
this.thingList = thingList;
}
@NonNull
@Override
public MultiResultsHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
context = parent.getContext();
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_sub_item, parent, false);
return new MultiResultsHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull MultiResultsHolder holder, int position) {
Resources res = context.getResources();
holder.amount.setText(res.getString(R.string.format_blah, thingList.get(position).getAmount()));
.
.
.
.
}
@Override
public int getItemCount() {
return thingList.size();
}
public class MultiResultsHolder extends RecyclerView.ViewHolder {
private ImageView deleteX;
private TextView amount;
private TextView fatAmount;
.
.
.
.
private MultiResultsHolder(View view) {
super(view);
deleteX = view.findViewById(R.id.delete_button);
deleteX.setOnClickListener(this);
amount = view.findViewById(R.id.tv_amount);
.
.
.
}
}
}
所以-运行时,单件物品显示得很好。 “内部”代码显示在顶部,该项目的顶部(是一张图片和一个时间戳,并且为列表的其余部分留出了足够的大小(但是其中有很多项目),但其余部分为空白。正在调用第二个适配器,我可以看到onBindViewHolder
正在为所有子项插入正确的值,但是它们没有显示出来!
只有一个很大的项目,大部分都是空白。
前后的单个项目都很好,一般的滚动都很好。
我看到一个SO答案,建议我对内部RecyclerView使用CustomLinearLayoutManager,例如here。它没有帮助,但是我看到了一个有趣的异常-在尝试测量项目的高度时,对recycler.getViewForPosition(0)
的调用给出了一个超出范围的异常,因为某种程度上RecycleView.Recycler不知道其中有任何项目我认为这可能是一个线索,但我不知道如何使用它来提供帮助
那里有什么主意吗?
答案 0 :(得分:0)
哇-另一个笨拙的-原来我没有将复合项目的“线性”布局设置为“方向:垂直”,这就是让我搞砸的-很好。这可以解决