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

Android: как скрыть элемент ListView

Как вы можете скрыть элемент в ListView или по крайней мере установить его высоту на ноль?

Я попытался установить видимость представления в GONE, но он все еще сохраняет пространство элемента (высота).

4b9b3361

Ответ 1

Повторное рассмотрение старого вопроса, но у меня была эта проблема, когда я хотел скрыть элементы списка временно на основе критериев вне данных списка. То, что я закончил делать, это создать макет "нулевого элемента" в xml и вернуть его на основе моих критериев вместо преобразования в getView()...

вместо возврата convertView, я вернул свой null_item...

return inflater.inflate(R.layout.null_item, null);

null_item.xml:

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

</LinearLayout>

Ответ 2

если вы хотите скрыть элемент следующим образом:

convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,1));
convertView.setVisibility(View.GONE);

не может быть AbsListView.LayoutParams(-1,0);

если convertview повторно используется, вы должны добавить это ниже, чтобы установить высоту назад:

if(convertView.getVisibility() == View.GONE) {
    convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT));
    convertView.setVisibility(View.VISIBLE);
}

Ответ 3

Когда дело доходит до ListView, чтобы сделать его эффективным, мы используем шаблон ViewHolder. Способ использования шаблона ViewHolder и R.layout.row_null следующего xml

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

следует использовать с getViewTypeCount() и getItemViewType (int position) следующим образом.

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int position) {
        return (hideStatusCheck(position)) ? 1 : 0;
    }

    @Override
    public View getView(int pos, View convertView, ViewGroup parent) {
        View rowView = convertView;

        if (hideStatusCheck(pos)) {
            if (rowView == null || rowView.getTag() != null) {
                LayoutInflater inflater = mActivity.getLayoutInflater();
                rowView = inflater.inflate(R.layout.row_null, parent, false);
            }
        } else {
            if (rowView == null) {
                rowView = inflateNormalView(parent);
            } else if (rowView.getTag() == null) {
                rowView = inflateNormalView(parent);
            } else {
                ViewHolder holderToCheck = (ViewHolder) rowView.getTag();
                Integer storedPos = (Integer) holderToCheck.getTag(POSITION);
                if (storedPos == null || storedPos != pos)
                    rowView = inflateNormalView(parent);
            }
            ViewHolder holder = (ViewHolder) rowView.getTag();
            holder.setTag(POSITION,pos);
                        /*
                        Populate data
                        */
            return rowView;
    }

    private View inflateNormalView(ViewGroup parent) {
                    View rowView;
        LayoutInflater inflater = mActivity.getLayoutInflater();
        rowView = inflater.inflate(R.layout.normal_item, parent, false);
        ViewHolder viewHolder = new ViewHolder();
        assert rowView != null;
                    /* Initiate normal findViewById thing*/
        rowView.setTag(viewHolder);
        return rowView;
    }

Мы проверяем тип элемента item и, если он отвечает проверке hide, он возвращает 1, в противном случае 0. ListView знает, что будут два типа View из getViewTypeCount. Теперь getView вернет approriate View в зависимости от hideStatusCheck. Чтобы создать надежный ListView, мы хотим использовать шаблон ViewHolder. Нам не нужно использовать ViewHolder, когда он скрыт. Мы просто надуваем R.layout.row_null и возвращаем его. Мы будем использовать ViewHolder для R.layout.normal_item. Вот сложная часть, предполагающая, что проверка скрытия не является статичной. Первая проверка rowView==null является стандартной. Вторая проверка rowView.getTag()==null заключается в том, чтобы увидеть, вернется ли представление в нормальное состояние от сокрытия. Третья проверка последнего предложения else заключается в проверке того, является ли ViewHolder сохраненным в теге правильным ViewHolder. Если эти условия соблюдены, мы снова раздуваем представление. Да, это правда, что шаблон ViewHolder не используется повсюду, но он использует определенные расширения. Это лучше, чем ничего.

Ответ 4

Я немного потрудился с перетаскиванием списка из здесь. Когда элемент выталкивается из списка, который должен быть перемещен вокруг занимаемого им пространства ячеек, он имеет высоту, установленную в 1px (см. Строку 238), поэтому она появляется "ушла". Я не мог найти способ справиться с этим лучше, так как установка высоты до 0 сбой, как и видимость GONE.

Тем не менее, если вы действительно хотите избавиться от строки менее временно, может быть хорошей идеей изменить поддержку Adapter и вызвать notifyDataSetChanged() на нем.

Ответ 5

Я смотрю исходный код. И есть только один способ скрыть элемент без notifyDataSetChanged(). Вы должны установить видимость GONE для всех внутренних видов и удалить фоновое изображение и paddings для просмотра позиций.

Примечание. Строка с таким невидимым элементом будет выбрана.

P.S: Это очень полезно для ExpandableListView, если вы хотите скрыть групповой просмотр сам.

Ответ 6

добавить в объект ListView: андроид: dividerHeight = "0px" Android: делитель = "# FFFFFF"

Цвет разделителя не имеет значения только установка dividerHeight не работает

Это устраняет разделитель, хотя...

Ответ 7

Я думаю, что у меня гораздо более легкое/безопасное решение: вам просто нужно "внедрить" ваш элемент в макет и изменить видимость этого родительского макета.

<?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="wrap_content"
    android:orientation="horizontal" >

    <!-- Embed ListView Item into a "parent" Layout -->
    <LinearLayout
        android:id="@+id/parentLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <!-- This is the normal content of your ListView Item -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="World" />

    </LinearLayout>
</LinearLayout>

Тогда в вашем коде просто выполните:

public View getView(int position, View view, ViewGroup parent) {
    if (view == null) {
        LayoutInflater li = mActivity.getLayoutInflater();
        view = li.inflate(R.layout.my_listview_item, null);
    }
    LinearLayout parentLayout = (LinearLayout) view.findViewById(R.id.parentLayout);
    if (shouldDisplayItem(position)) {
        parentLayout.setVisibility(View.VISIBLE);
    } else {
        parentLayout.setVisibility(View.GONE);
    }
    return view;
}

Таким образом, вы всегда используете/повторно используете один и тот же элемент и просто скрываете/показываете его.