将视图动态添加到RecyclerView的项目

use*_*798 18 android android-recyclerview

我想添加额外TextViewRecyclerView.Adapter基于发送到的ModalObject的项目RecyclerView.Adapter

示例:

我有一个带isAddText变量的模态对象.In onCreateViewHolder将创建Holder对象并将其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;
}
Run Code Online (Sandbox Code Playgroud)

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. 
}
Run Code Online (Sandbox Code Playgroud)

mac*_*usz 23

问题

通常,您需要执行itemView.addView(view,layoutParams)以编程方式将另一个视图添加到您的布局中,但ViewHolders的内容是,它们将被RecyclerView重用以绑定适配器中的不同项,因此您无法执行当另一个项目再次绑定到此viewHolder实例时,将显示您要添加的新TextView.

我可以想到一些方法可以实现你的目标:


1.切换视图的可见性

第一种方法是将此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
}
Run Code Online (Sandbox Code Playgroud)

2.实现不同的ViewHolders

第二种方式更优雅,它涉及创建不同的ViewHolder类型.首先,您需要为RecyclerView显示的两种类型的视图创建int常量.在适配器中放置以下代码:

private static final int VIEW_ORDINARY = 0;
private static final int VIEW_WITH_EXTRA_TEXT_VIEW = 1;
Run Code Online (Sandbox Code Playgroud)

然后实现适配器的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

下一步是根据返回的类型创建不同的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,您需要定义SolventViewHolderWithExtraTextView:

class SolventViewHolderWithExtraTextView extends SolventViewHolder {
    TextView extraTextView;

    public SolventViewHolderWithExtraTextView(View itemView) {
        super(itemView);
        this.extraTextView = (TextView) findViewById(R.id.extra_text_view);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在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");
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,您可以为需要另一个TextView的项目使用另一种类型的ViewHolder,它将在该类别中重复使用.这是做你想做的事情的首选方式.


3.动态添加/删除视图

另一个答案(如果你问我,这是非常难看的解决方案)是动态添加和删除视图,例如:

@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;
}
Run Code Online (Sandbox Code Playgroud)

这真的很难看,因为要将视图添加到itemView,您需要将其强制转换为ViewGroup(它不一定是这样),因此请确保它始终是ViewGroup或其子类.此外,您需要提供适当的layoutParams以将extraTextView添加到itemView.

  • 如果我要添加未知数量的视图怎么办? (4认同)

grg*_*sll 5

您还可以设置itemView.setHasTransientState(true)在哪种情况下视图不会被回收,直到setHasTransientState设置为false