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
, как вы ничего не делаете с этим (?!?).