Android: как скрыть элемент ListView - PullRequest
20 голосов
/ 14 апреля 2010

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

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

Ответы [ 7 ]

24 голосов
/ 29 мая 2013

Восстановить старый вопрос, но у меня была эта проблема, когда я хотел временно скрыть элементы списка на основе критериев вне данных списка. В итоге я создал макет «пустой элемент» в xml и вернул его на основе моих критериев вместо представления convert в 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>
11 голосов
/ 06 января 2015

, если вы хотите спрятать предмет так:

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);
}
8 голосов
/ 24 января 2014

Когда речь идет о 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;
    }

Мы выполняем проверку типа View элемента, и если он соответствует проверке скрытия, он возвращает 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 не используется повсеместно, но он используется для определенных расширений. Это лучше, чем ничего.

2 голосов
/ 29 ноября 2010

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

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

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

2 голосов
/ 14 апреля 2010

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

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

0 голосов
/ 13 мая 2014

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

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

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

0 голосов
/ 24 июля 2010

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

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

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

...