Скрытие просмотров в RecyclerView

У меня такой код как этот

public static class MyViewHolder extends RecyclerView.ViewHolder { @InjectView(R.id.text) TextView label; public MyViewHolder(View itemView) { super(itemView); ButterKnife.inject(this, itemView); } public void hide(boolean hide) { label.setVisibility(hide ? View.GONE : View.VISIBLE); } } 

Который отображает одну строку в RecyclerView . R.id.text на самом деле является корневым представлением макета, который накачивается и передается конструктору здесь.

Я использую реализацию LinearLayoutManager по LinearLayoutManager .

В bindViewHolder я вызываю hide(true) в экземпляре MyViewHolder , но вместо свертывания строки, как и ожидалось, строка становится невидимой, сохраняя ее высоту и положение в RecyclerView . Кто-нибудь еще сталкивается с этой проблемой?

Как вы скрываете элементы в RecyclerView?

Solutions Collecting From Web of "Скрытие просмотров в RecyclerView"

Не существует встроенного способа скрыть ребенка в RV, но, конечно, если его высота станет 0, она не будет видна :). Я предполагаю, что ваш корневой макет имеет некоторую минимальную высоту (или точную высоту), которая делает ее еще занятой, даже если она GONE.

Кроме того, если вы хотите удалить представление, удалите его из адаптера, не скрывайте его. Есть ли причина, по которой вы хотите скрыть вместо удаления?

Поместите метод setVisibility(boolean isVisible) в ViewHolder .

Вы можете изменить параметры itemView (ширина и высота) для LayoutManager :

 public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ ... public void setVisibility(boolean isVisible){ RecyclerView.LayoutParams param = (RecyclerView.LayoutParams)itemView.getLayoutParams(); if (isVisible){ param.height = LinearLayout.LayoutParams.WRAP_CONTENT; param.width = LinearLayout.LayoutParams.MATCH_PARENT; itemView.setVisibility(View.VISIBLE); }else{ itemView.setVisibility(View.GONE); param.height = 0; param.width = 0; } itemView.setLayoutParams(param); } public ViewHolder(View itemView) { super(itemView); ... } } 

И изменить видимость для ItemDecoration (Divider):

 public class DividerItemDecoration extends RecyclerView.ItemDecoration { ... @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { ... for (int i = 0; i < parent.getChildCount(); i++) { if (parent.getChildAt(i).getVisibility() == View.GONE) continue; /* draw dividers */ } } } 

Ты можешь это сделать!

Во-первых, вам нужно определить позицию позиции, которую вы хотите скрыть. Для этого вы можете настроить getItemViewType.

Далее, onCreateViewHolder, зависит от типа представления. Вы можете сделать что-то вроде этого:

 if(viewType == TYPE_HIDE) { v = LayoutInflater.from(parent.getContext()).inflate(R.layout.empty_item, parent, false); vHolder = new ViewHolder(context, v, viewType, this); break; } return vHolder; 

-> пустой элемент – это макет, который ничего не имеет (иначе говоря, по умолчанию он создается по умолчанию). Или код:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> </LinearLayout> 

Надеюсь, это поможет!

Итак, так, как я это сделал, в конце концов, у меня был весь набор данных, скажем, myObjects и у меня были сценарии, где я хотел бы показать только подмножества этого набора данных.

Поскольку настройка видимости строк в RecyclerView не приводит к развалу высот, а установка высот строк тоже не показала ничего, что мне нужно было сделать, просто сохранить вторичный набор данных, называемый myObjectsShown который был не более чем List<Integer> который будет индексировать в myObjects чтобы определить, какие объекты будут отображаться.

Затем я периодически обновлял myObjectsShown чтобы содержать правильные индексы.

Следовательно,

 public int getItemCount() { return myObjectsShown.size(); } 

а также

 public void onBindViewHolder(MyViewHolder holder, int position) { Object myObject = myObjects.get(myObjectsShown.get(position)); // bind object to viewholder here... } 

Для полноты вам следует заметить, что настройка видимости вида GONE не будет скрывать поля. Вам нужно сделать что-то вроде этого:

  if(itemView.getVisibility() != GONE) itemView.setVisibility(GONE); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) itemView.getLayoutParams(); layoutParams.setMargins(0, 0, 0, 0); itemView.setLayoutParams(layoutParams); 

Для скрытия вида в RecyclerView я скрываю / показываю представление в OnBindViewHolder :

 if (item.isShown) { vh.FooterLayout.setVisibility(View.Visible); } else { vh.FooterLayout.setVisibility(View.Gone); } 

И, например, из операции я просто перерисовывал необходимый элемент: _postListAdapter.notifyItemChanged(position) // если вы хотите показать / скрыть нижний колонтитул – позиция amountOfPosts.size() а также изменить переменную bool – amountOfPosts[amountOfPosts.size()].isShown