Подтвердить что ты не робот

Скрытие просмотров в 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.

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

Использовать метод 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 */    

        }
    }
}

Ответ 3

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

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

Далее, 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>

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

Ответ 4

Хорошо, так что, в конце концов, я сделал весь свой набор данных, скажем, 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...
} 

Ответ 5

Для скрытия вида в 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

Ответ 6

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

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