我想根据发送到TextView
RecyclerView.Adapter
添加到RecyclerView.Adapter
的项目中
示例:
我有一个带有isAddText
变量的模态对象。在onCreateViewHolder
中,我们会创建持有者对象,并将itemView
作为参数发送。
@Override
public SolventViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.solvent_list, null);
SolventViewHolders rcv = new SolventViewHolders(layoutView);
return rcv;
}
SolventViewHolders.java
public SolventViewHolders(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
textView = (TextView) itemView.findViewById(R.id.country_name);
imageView = (ImageView) itemView.findViewById(R.id.country_photo);
// Now i need add a view to the itemView parent based on ModalObject isAddView property and how to do that.
}
答案 0 :(得分:23)
通常,您需要执行itemView.addView(view,layoutParams)以编程方式将另一个视图添加到您的布局中,但ViewHolders的内容是,它们将被RecyclerView重用以绑定适配器中的不同项目,因此您可以&这样做,或者当另一个项目再次绑定到此viewHolder实例时,将显示您要添加的新TextView。
我可以想到一些可以实现目标的方法:
第一种方法是将此textView添加到您的布局中,默认情况下通过GONE可见,并在绑定您需要此TextView的项目时将其设置为VISIBLE,例如:
@Override
public void onBindViewHolder(AbstractViewHolder holder, int position) {
holder.extraTextView.setVisibility(View.GONE);
if(shouldShowExtraTextView) {
holder.extraTextView.setVisibility(View.VISIBLE);
holder.extraTextView.setText(/* your text */);
}
// proceed to bind item to holder
}
第二种方式更优雅,它涉及创建不同的ViewHolder类型。首先,您需要为RecyclerView显示的两种类型的视图创建int常量。在适配器中放置以下代码:
private static final int VIEW_ORDINARY = 0;
private static final int VIEW_WITH_EXTRA_TEXT_VIEW = 1;
然后实现适配器的getItemViewType(int position)方法:
@Override
public int getItemViewType(int position) {
if(position == /* position of item that needs extra text view */) {
return VIEW_WITH_EXTRA_TEXT_VIEW;
} else {
return VIEW_ORDINARY;
}
}
下一步是根据返回的类型创建不同的Holder:
@Override
public SolventViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == VIEW_WITH_EXTRA_TEXT_VIEW) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.solvent_list_with_extra_text_view, parent, false);
return new SolventViewHolderWithExtraTextView(itemView);
} else {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.solvent_list, parent, false);
return new SolventViewHolder(itemView);
}
}
当然你需要定义SolventViewHolderWithExtraTextView:
class SolventViewHolderWithExtraTextView extends SolventViewHolder {
TextView extraTextView;
public SolventViewHolderWithExtraTextView(View itemView) {
super(itemView);
this.extraTextView = (TextView) findViewById(R.id.extra_text_view);
}
}
然后在onBindViewHolder():
@Override
public void onBindViewHolder(SolventViewHolder holder, int position) {
// you can use inheritance to handle binding logic or check the item view type again:
// bind ordinary view
if(getItemViewType(position)) {
// bind the extra textView
((SolventViewHolderWithExtraTextView)holder).extraTextView.setText("I hope this works");
}
}
这样您就可以为需要另一个TextView的项目使用另一种类型的ViewHolder,它将在该类别中重复使用。这是做你想做的事情的首选方式。
另一个答案(如果你问我,这是非常难看的解决方案)是动态添加和删除视图,例如:
@Override
public void onBindViewHolder(AbstractViewHolder holder, int position) {
if(shouldDisplayExtraTextView) {
if(!holder.displaysExtraTextView() {
holder.addExtraTextView();
}
holder.extraTextView.setText("This solution is really ugly");
} else {
if(holder.displaysExtraTextView() {
holder.removeExtraTextView();
}
}
}
class SolventViewHolders extends RecyclerView.ViewHolder {
TextView extraTextView;
boolean viewAdded = false;
public SolventViewHolders(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
textView = (TextView) itemView.findViewById(R.id.country_name);
imageView = (ImageView) itemView.findViewById(R.id.country_photo);
// Now i need add a view to the itemView parent based on ModalObject isAddView property and how to do that.
extraTextView = new TextView();
}
public void addExtraTextView() {
((ViewGroup)itemView).addView(extraTextView, layoutParams);
viewAdded = true;
}
public void removeExtraTextView() {
((ViewGroup)itemView).removeView(extraTextView);
viewAdded = false;
}
public boolean displaysExtraTextView() {
return viewAdded;
}
这非常难看,因为要向itemView添加视图,您需要将其强制转换为ViewGroup(它不必这样),因此请确保它始终是ViewGroup或其子类。此外,您需要提供正确的layoutParams以将extraTextView添加到itemView。
答案 1 :(得分:3)
您还可以设置itemView.setHasTransientState(true)
,在setHasTransientState
设置为false
之前,视图不会被回收。
答案 2 :(得分:1)
在@ grgrssll的答案的帮助下,我能够解决我的问题。在我的情况下,我需要在每行内部使用N个TextView。
在我的 onBindViewHolder
中@Override
public void onBindViewHolder(@NonNull final HistoryViewHolder vh, int position) {
...
//Generating N-number of TextViews depending on size of itemsMap
for (Map.Entry<String, Model> entry : itemsMap.entrySet()) {
SelectedModel s = entry.getValue();
// Set setHasTransientState to true
vh.itemDetailsContainer.setHasTransientState(true);
// Dynamically adding the views
vh.itemDetailsContainer.addView(getItemTextView(context, s.getItemName()));
...
}
//Set setHasTranssientState to false after loop
vh.itemDetailsContainer.setHasTransientState(false);
...
}