Почему мой значок FectedTextView поднимается на разные элементы в моей GridView?

StackOverflow https://stackoverflow.com/questions/5850456

Вопрос

у меня есть GridView чьи элементы основаны на FrameLayout содержащий ImageView и CheckedTextView. Анкет XML -файл для Framelayout выглядит следующим образом:

<FrameLayout
xmlns:android = "http://schemas.android.com/apk/res/android"
android:id="@+id/gridImage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center_horizontal">
<ImageView
android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:adjustViewBounds="false">
</ImageView>
<CheckedTextView
android:id="@+id/imageTick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_gravity="center_horizontal|bottom"
android:checkMark="@drawable/icon"
android:checked="false"
android:visibility="invisible"
>
</CheckedTextView>
</FrameLayout>

РЕДАКТИРОВАТЬ: Это адаптер getView() Метод, который я использую для каждого элемента:

public View getView(int position, View convertView, ViewGroup parent) {
        Log.d("getView()", position+"");
        View v;
        ImageView imageView;
        if(convertView == null) {

            v = LayoutInflater.from(mContext).inflate(R.layout.photo_text_view, null);
            v.setLayoutParams(new GridView.LayoutParams(100,100));
        }
        else
        {
            v = convertView;

        }
        imageView = (ImageView) v.findViewById(R.id.image);
        imageView.setImageBitmap(mThumbsIds.get().get(position));

        v.setPadding(8, 8, 8, 8);
        return v;
    }

В своем классе деятельности я загружаю контекстное меню, и однажды я выбираю опцию, я сделаю CheckedTextView видимо для этого GridView элемент как так:

GridView gridView = (GridView) findViewById(R.id.gridview);
    View selected =gridView.getChildAt(position);
    CheckedTextView selectedCheck = (CheckedTextView)selected.findViewById(R.id.imageTick);
    selectedCheck.setChecked(true);
    selectedCheck.setVisibility(View.VISIBLE);

Так что с этого момента может произойти две вещи:

1) Допустим, я выбрал элемент в позиции 0, CheckedTextView становится видимым, но когда я прокручиваю вниз по своей Gridview, еще один элемент (например, позиция 17) имеет свой проверенный текст. Это продолжается на случайных элементах, когда я прокручиваю вниз к дну.

2) Если я выберу элемент внизу, прокрутите обратно вверх и запустите один из методов, чтобы сделать все невидимые. NullPointerException брошен для элемента внизу. Это происходит на данный момент: View selected =gridView.getChildAt(position); где выбран становится нулевым.

Что тут происходит? Почему эти случайные проверки текста становятся видимыми, и почему я получаю исключения?

Это было полезно?

Решение

Проблемы заключаются в том, как вы отслеживаете проверенные элементы:

GridView gridView = (GridView) findViewById(R.id.gridview);
View selected =gridView.getChildAt(position);
CheckedTextView selectedCheck = (CheckedTextView)selected.findViewById(R.id.imageTick);
selectedCheck.setChecked(true);
selectedCheck.setVisibility(View.VISIBLE);

1) getChildAt Не даст вам правильный представление, если вы проникли в контент и индексируете позицию адаптера. При ссылке на активное представление в GridView или же ListView Вы хотите сделать что -то вроде этого:

final int index = position - gridView.getFirstVisiblePosition();
View selected = gridView.getChildAt(index);

Причина в том, что ваш GridView Сохраняет представление о детских предметах для адаптеров, которые он в настоящее время отображает. У него могут быть только дети для детей с 4 по 23, если элементы от 0 до 3 были прокручены из вершины ранее.

Вот почему вы получаете исключения, когда делаете View selected =gridView.getChildAt(position); Представление на эту позицию на самом деле не существует, когда она вне экрана, поэтому getChildAt возврат null.

2) Когда ListView или же GridView Имеет ли изменение контента или в противном случае ему необходимо повторно рассказать о своих детских взглядах, он делает это путем повторного связывания существующих взглядов, используя convertView параметр к вашему адаптеру. Ваш адаптер никогда не настраивает проверенное состояние ваших представлений товара, поэтому можно повторно используется проверенное представление для элемента, который должен быть неконтролированным позже.

Чтобы решить это, у вас должна быть модель данных, которую ваш адаптер представляет отслеживание проверенного состояния ваших предметов, а не полагаться на представления предмета, чтобы сделать это. Это означает, что ваш адаптер всегда должен проверять/устанавливать проверенное состояние элемента в getView. Анкет Это может выглядеть примерно так:

imageView = (ImageView) v.findViewById(R.id.image);
imageView.setImageBitmap(mThumbsIds.get().get(position));

CheckedTextView checkView = (CheckedTextView) v.findViewById(R.id.imageTick);

if (mData.isItemChecked(position)) {
    checkView.setChecked(true);
    checkView.setVisibility(View.VISIBLE);
} else {
    checkView.setVisibility(View.GONE);
}

Затем, когда выбран вариант, должен изменить проверенное состояние элемента, а не фрагмент кода выше сделайте что -то вроде:

data.setItemChecked(position, true);
adapter.notifyDataSetChanged();

notifyDataSetChanged() скажу GridView что он должен повторно включать представления предметов, которые будут иметь getView Метод исправьте проверенные состояния должным образом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top