2015-09-01 8 views
12

Я хочу, чтобы добавить дополнительный TextView к пункту RecyclerView.Adapter на основе ModalObject отправляется на RecyclerView.AdapterДобавить вид динамически к пункту RecyclerView

Пример:

Я имел модальность объект с переменной isAddText. В 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; 
} 

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

Вы можете добавить textview в макет, и в зависимости от вашего состояния сделать его видимым/невидимым. – vishalk

+0

Я не хочу так ... потому что он содержит больше просмотров и зависимостей. – user3607798

ответ

16

Проблема

Обычно, вам нужно будет выполнить itemView.addView (вид, layoutParams), чтобы добавить еще один вид на программно макете, но вещь с ViewHolders, они будут повторно использоваться RecyclerView для привязки разных элементов от адаптера, поэтому вы не можете этого сделать или этот новый TextView, который вы хотите добавить, появится, когда другой элемент снова привязан к этому экземпляру viewHolder.

Я могу придумать несколько способов, вы можете достичь своей цели:


1. Переключатель видимости вида по

Первый способ, чтобы добавить этот TextView в макете и иметь его видимость на GONE по умолчанию, и установить его на VISIBLE при связывании, что один элемент вам нужен этот TextView для, например:

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

2. Внедрение различных ViewHolders

Второй способ более изящный, он предполагает создание различного типа ViewHolder. Сначала вам нужно создать int-константы для двух типов представлений, которые будут показаны RecyclerView. Место в адаптере следующий код:

private static final int VIEW_ORDINARY = 0; 
private static final int VIEW_WITH_EXTRA_TEXT_VIEW = 1; 

затем реализовать getItemViewType (INT позиция) метод адаптера:

@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; 
    } 
} 

Следующий шаг заключается в создании другого держателя в зависимости от возвращаемого типа:

@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"); 
    } 
} 

Таким образом, у вас есть еще один тип ViewHolder для ваших вещей, которые нужно еще TextView, и он будет использоваться повторно в этой категории. Это предпочтительный способ сделать то, что вы хотите.


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

Это действительно некрасиво, потому что, чтобы добавить вид на itemView вам нужно отдать его в ViewGroup (чего не должно быть), поэтому убедитесь, что он всегда будет ViewGroup или его подклассом. Кроме того, вам необходимо предоставить правильные layoutParams, чтобы добавить extraTextView в itemView.

+0

Я не хочу раздувать макеты, единственный способ добавить динамические представления. – user3607798

+0

Я отредактировал свой ответ, чтобы включить другой способ добиться того, чего вы хотите, хотя это действительно не изящное решение, но если по какой-то причине, как вы говорите, вы не можете раздуть другой макет, это должно сделать трюк. – maciekjanusz

+0

@invariant Что делать, если в макете (представлении) есть кнопка, а другая нет, если предположить, что кнопка имеет событие OnClick реализовано? – Journey

0

Вы также можете установить itemView.setHasTransientState(true), и в этом случае вид не будет возвращен в оборот до тех пор, пока setHasTransientState не будет установлен на false.

Смежные вопросы