GridView с элементами CustomLayout и состоянием

Я работаю над макетом, который должен отображать динамический список элементов. Каждый элемент имеет определенный UUID, имя (текст баннера), URL-адрес изображения и логическое значение, указывающее, выбран ли он, - я также создал POJO для их хранения. Я создал собственный макет, чтобы поместить элементы в сетку, две иконки с текстом баннера. Это выглядит так:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
  <RelativeLayout
    android:id="@+id/ItemLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <ImageView
        android:id="@+id/ItemImage"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignParentTop="true"
        android:background="@android:color/transparent" />
    <ImageView
        android:id="@+id/ItemOverlayImage"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignParentTop="true"
        android:background="@android:color/transparent" />
    <TextView
        android:id="@+id/ItemTextBanner"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="2dp"
        android:background="#BF000000"
        android:gravity="center"
        android:textStyle="bold" />
  </RelativeLayout>
</FrameLayout>

Я также создал пользовательский адаптер и действие, и у меня нет проблем с получением всех элементов, изображения, загруженного и закодированного в растровые изображения и устанавливаемого текстового баннера. Проблема в том, что я хочу, чтобы "выбранное" состояние и изображение менялись при нажатии на элемент.

Я знаю, что могу добавить GridView.setOnItemOnClickListener и внутри я знаю, какой элемент был выбран, а также родительский вид, из которого он получен, но я не уверен, как получить его "выбранное" состояние. Эта ссылка использует состояние из статического списка в адаптере и является тем, что я смоделировал после. Я добавил следующий метод и вызвал его из GridView.setOnItemOnClickListener,

public void itemSelected(View parent, int position)
{
    if(items.get(position).isSelected())
    {
        ImageView interestSelected = (ImageView)parent.findViewById(R.id.ItemOverlayImage);
        interestSelected.setImageResource(0);
    }
    else
    {
        ImageView interestSelected = (ImageView)parent.findViewById(R.id.ItemOverlayImage);
        interestSelected.setImageResource(R.drawable.overlay);          
    }
}

Первая проблема очевидна, я не сохраняю состояние в массиве элементов, но это легко исправить. Настоящая проблема в том, что только первый элемент получает оверлей. Так как мне изменить R.id.ItemOverlayImage для выбранного элемента в GridView, а не только для первого? Или я в этом совершенно не прав?

1 ответ

Решение

Несколько моментов, касающихся вашего кода:

Вы, вероятно, получаете только первый элемент с наложением, потому что вы ищете findViewById на родителя, GridView а не вид строки view, так findViewById вернет первый ImageView что он находит (который находится в первом видимом ряду). Чтобы показать это наложение, у вас есть несколько вариантов того, как это сделать, в зависимости от кода, который вы использовали в адаптере. getView Если вы хотите, чтобы в тот момент отображался только один элемент с наложением (например, когда вы щелкаете один элемент, предыдущий, который был нажат (если есть), будет отменен), или если у вас есть варианты для переключения элемента (щелчок -> наложение, еще один клик -> без наложения). Не зная информации выше, вот как я бы это сделал:

public void onItemClick (AdapterView<?> parent, View view, int position, long id) {
     ImageView overlay = (ImageView) view.findViewById(R.id.ItemOverlayImage);
     if (!items.get(position).isSelected()) { // the item doesn't have an overlay
         overlay.setImageResource(R.drawable.overlay); // set the overlay
         items.setSelected(true); // set to true so the adapter knows it
     } else { // the item has the overlay so we remove it
         overlay.setImageResource(0);
         items.setSelected(false); set to false so the adapter knows it
     }
}

Пока вы используете в getView метод isSelected установить или не установить оверлей, все будет в порядке.

Также вы должны удалить FrameLayout это оборачивает RelativeLayout, как вы ничего не делаете с этим (?!?).

Другие вопросы по тегам