Android gridview сохраняет выбранный элемент

У меня есть GridView с несколькими элементами, но элементы должны быть выбраны после вызова onClickListener. Как я могу добиться этого?

Я уже пробовал v.setSelected(true) но он, похоже, не работает.

 gridview.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View v, int position, long id) { // Toast.makeText(Project.this, "Red" + position, // Toast.LENGTH_SHORT).show(); //position = al catelea element v.setPressed(true); if (bp == 2) { if (position == 0) { Square.setSex(R.drawable.girl_body2v); Square2.setHair(R.drawable.girl_hair_01v); SquareAccesories.setAcc(R.drawable.girl_accessories_01v); SquareEyes.setEyes(R.drawable.eyes_1v); SquareLips.setLips(R.drawable.lip_1v); Square3.setDress(R.drawable.girl_tops_01v); SquareShoes.setShoes(R.drawable.girl_shoes_01v); SquarePants.setPants(R.drawable.girl_bottom_01v); setS(2); 

Это небольшая часть кода для onClickListener, потому что у меня много дел.

Концепция, которую вы хотите достичь, возможна, но не так, как вы сейчас работаете.

Лучшим и простым решением было бы отслеживать состояния щелкнутых элементов и давать им правильную компоновку внутри адаптера. Я привел небольшой пример:

Мероприятия

 public class StackOverFlowActivity extends Activity { GridView gridView; MyCustomAdapter myAdapter; ArrayList<GridObject> myObjects; static final String[] numbers = new String[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); myObjects = new ArrayList<GridObject>(); for (String s : numbers) { myObjects.add(new GridObject(s, 0)); } gridView = (GridView) findViewById(R.id.gridView1); myAdapter = new MyCustomAdapter(this); gridView.setAdapter(myAdapter); gridView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) { myObjects.get(position).setState(1); myAdapter.notifyDataSetChanged(); } }); } static class ViewHolder { TextView text; } private class MyCustomAdapter extends BaseAdapter { private LayoutInflater mInflater; public MyCustomAdapter(Context context) { mInflater = LayoutInflater.from(context); } @Override public View getView(int position, View convertView, ViewGroup parent) { GridObject object = myObjects.get(position); ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.list_item_icon_text, null); holder = new ViewHolder(); holder.text = (TextView) convertView.findViewById(R.id.text); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.text.setText(object.getName()); if (object.getState() == 1) { holder.text.setBackgroundColor(Color.GREEN); } else { holder.text.setBackgroundColor(Color.BLUE); } return convertView; } @Override public int getCount() { return myObjects.size(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } } } 

GridObject

 public class GridObject { private String name; private int state; public GridObject(String name, int state) { super(); this.name = name; this.state = state; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getState() { return state; } public void setState(int state) { this.state = state; } } 

main.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <GridView android:id="@+id/gridView1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:columnWidth="50dp" android:gravity="center" android:numColumns="auto_fit" android:stretchMode="columnWidth" > </GridView> </LinearLayout> 

list_item_icon_text

 <?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="match_parent" android:orientation="vertical" > <TextView android:id="@+id/text" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> 

Я думаю, что лучший подход – рассказать GridView что вы хотите поддержать выбор (проверку) элементов:

 gridView.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE); 

А затем убедитесь, что элементы в GridView реализуют интерфейс Checkable . Это означает, что элементы могут быть либо Checkbox , ToggleButton и так далее, либо вы можете добавить поддержку Checkable самостоятельно – например, сделать RelativeLayout доступным. (См. Пример ниже.)

В отличие от другого ответа большая часть работы берет на себя сама GridView – не onClickListener . Вместо того, чтобы хранить состояние самостоятельно, просто вызовите gridView.getCheckedItemIds() или аналогичный метод.


Чтобы сделать RelativeLayout (или что-либо) проверенным, сделайте его подкласс:

 public class CheckableRelativeLayout extends RelativeLayout implements Checkable { private boolean checked = false; private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked }; public CheckableRelativeLayout(Context context) { super(context); } public CheckableRelativeLayout(Context context, AttributeSet attrs) { super(context, attrs); } public CheckableRelativeLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected int[] onCreateDrawableState(int extraSpace) { final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); if (isChecked()) mergeDrawableStates(drawableState, CHECKED_STATE_SET); return drawableState; } @Override public boolean isChecked() { return checked; } @Override public void setChecked(boolean _checked) { checked = _checked; refreshDrawableState(); } @Override public void toggle() { setChecked(!checked); } } 

Обратите внимание, что метод onCreateDrawableState обновляет визуальный стиль. Вам не нужно это делать, вы можете, например, напрямую изменить фон в методе setChange.

Затем используйте CheckableRelativeLayout в качестве верхнего вида для элементов в GridView:

 <foo.bar.CheckableRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="@drawable/my_awesome_background" ... more stuff > ... content of the relative layout </com.test.CheckableRelativeLayout> 

И определите, как меняется фон при проверке элемента в res/drawable/my_awesome_background.xml :

 <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:state_checked="true" > <!-- This applies when the item is checked. --> <shape android:shape="rectangle" > <solid android:color="#A8DFF4" /> </shape> </item> <item> <!-- This applies when the item is not checked. --> <shape android:shape="rectangle" > <solid android:color="#EFEFEF" /> </shape> </item> </selector> 

Вот верная версия ответа Штрикса (который, я думаю, лучше, чем принятый ответ), когда вам не нужно повторно использовать этот код в другом месте. Вместо создания нового класса и реализации Checked вы можете просто создать анонимный класс внутри вашего метода Adapter.getView , переопределив onCreateDrawableState как в ответе Strix, но замените isChecked() там с ((AbsListView)parent).isItemChecked(position) . Вот полный код моего адаптера, который рисует рамку вокруг отмеченных эскизов в галерее:

 public class ImageAdapter extends BaseAdapter { private final int[] CHECKED_STATE_SET = { android.R.attr.state_checked }; public int getCount() {return images.size();} public Object getItem(int position) {return images.get(position);} public long getItemId(int position) {return position;} public View getView(final int position, final View convertView, final ViewGroup parent) { final ImageView imageView = new ImageView(getApplicationContext()) { @Override public int[] onCreateDrawableState(int extraSpace) { final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); if (((AbsListView)parent).isItemChecked(position)) { mergeDrawableStates(drawableState, CHECKED_STATE_SET); } return drawableState; } }; imageView.setBackground(getResources().getDrawable(R.drawable.my_awesome_background)); imageView.setScaleType(ImageView.ScaleType.CENTER); final byte[] buffer = images.get(position); final Bitmap bmp = BitmapFactory.decodeByteArray(buffer, 0, buffer.length); imageView.setImageBitmap(bmp); return imageView; } } 

Я знаю, что ответ немного стар. Но я думаю, что это самый простой из всех. В классе адаптера добавьте переменную, содержащую выбранную позицию позиции. Установите трансверсальность для всех изображений, исключая выбранную в методе GetView. В обработчике кликов в основном методе безопасно выбранное ItemPosition. Сообщите об этом адаптеру.

В классе адаптера добавьте переменную, содержащую выбранную позицию позиции.

 public class GridImageAdapter extends BaseAdapter { public int selectedImage = 0; 

Установите трансверсацию для всех изображений, исключая выбранную в методе GetView.

 @Override public View getView(final int position, View convertView, final ViewGroup parent) { int[] images = { R.drawable.walk, R.drawable.run, R.drawable.jump } ImageView imageView = new ImageView(mContext); if (position < imgMapper.length) { imageView.setImageResource(images[position]); if (position != selectedImage) { imageView.setImageAlpha(50); } imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); imageView.setLayoutParams(new GridView.LayoutParams(150, 150)); }; return imageView; } 

В обработчике кликов в основном методе безопасно выбранное ItemPosition. Уведомлять адаптер, который он изменил

  myGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View v, int position, long id) { GridImageAdapter myAdapter = (GridImageAdapter) myGridView.getAdapter(); myAdapter.selectedImage = position; myAdapter.notifyDataSetChanged(); } }); 

gridview в gridview должны быть CheckBoxs , таким образом вы можете проверить и снять отметку с них.

Intereting Posts
Ошибка «Android SDK version not found» при запуске эмулятора Genymotion для Android из Appcelerator Studio Есть ли прямое событие для блокировки клавиатуры? Как настроить textView на основе текста на Android Верхний индекс и подстрочный индекс в Android-приложении XML Http Get Request возвращает html? Правильный способ подключения USB-аксессуаров Позиция прокрутки переходит к предыдущим элементам списка при прокрутке в пользовательском представлении списка Android RecyclerView создает и связывает все взгляды на изменение набора данных Макет Название папки для 7 "планшета Android.view.InflateException: двоичная строка XML-файла # 4: ошибка раздувания класса SwitchPreference Android Lint – Как скрыть предупреждение «Ресурс Xxx кажется неиспользуемым» Ошибка PLACES_API_INVALID_APP с Android Play Places WRITE_SETTINGS Разрешение неоднозначность Как отобразить текст «Загрузка …» при извлечении элементов для ListView Как отключить тень вокруг вида карты в андроиде