как выделить выбранный элемент просмотра ресайклеров?

У меня есть Recycler View с изображениями, загруженными из внутреннего хранилища. Я хочу выделить выделенный элемент при нажатии. Я много пробовал, но он не работал. Фактически, мне нужно, когда я нажимаю на любой элемент в представлении Recycler, что элемент должен идти в My ArrayList, и он также должен быть подсвечен, и снова, когда я нажимаю или говорю, что он отменяет выбор, он должен снова стать нормальным. Вот мой код:

public class Images extends Fragment { private List imageList; Cursor imageCursor; RecyclerView recyclerView; MyImageAdapter adapter; ActionButton clickButton; List listofImages; List pos; int columnIndex; StringBuilder stringBuilder; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootlayout = inflater.inflate(R.layout.image, container, false); listofImages=new ArrayList(); pos=new ArrayList(); stringBuilder=new StringBuilder(); ContentResolver imageResolver = getActivity().getContentResolver(); Uri imageUri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI; String projection[]={MediaStore.Images.Thumbnails._ID,MediaStore.Images.Media.TITLE}; imageCursor = getActivity().managedQuery(imageUri, projection, null, null, null); clickButton= (ActionButton) rootlayout.findViewById(R.id.action_button); recyclerView = (RecyclerView) rootlayout.findViewById(R.id.recycler_view_image); adapter = new MyImageAdapter(getActivity(), getImageList()); recyclerView.setAdapter(adapter); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(),recyclerView,new RecyclerTouchListener.ClickListener() { @Override public void onClick(View view, int position) { TextView tv= (TextView) view.findViewById(R.id.list_text_all); int flag=0; String[] projection = {MediaStore.Images.Media.DATA}; imageCursor = getActivity().managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null, null, null); columnIndex = imageCursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); imageCursor.moveToPosition(position); // Get image filename String imagePath = imageCursor.getString(columnIndex); if (listofImages.contains(imagePath)){ Log.d("Contains Test","Yes"); listofImages.remove(imagePath); pos.remove(position); } else { listofImages.add(imagePath); pos.add(position); Log.d("Contains Test","No"); } String s=listofImages.size()+" "+imagePath; Log.d("Inserted",s); } @Override public void onLongClick(View view, int position) {} })); clickButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { for (int i=0;i<listofImages.size();i++){ stringBuilder.append(listofImages.get(i)+"\n"); } Toast.makeText(getActivity(),stringBuilder,Toast.LENGTH_LONG).show(); } }); return rootlayout; } public List getImageList() { imageList=new ArrayList(); if(imageCursor!=null && imageCursor.moveToFirst()){ int titleColumn = imageCursor.getColumnIndex (android.provider.MediaStore.Images.Media.TITLE); int idColumn = imageCursor.getColumnIndex (android.provider.MediaStore.Images.Media._ID); do { ImageHolder img=new ImageHolder(); img.id=imageCursor.getLong(idColumn); img.title=imageCursor.getString(titleColumn); img.iconid= imageCursor.getInt(idColumn); imageList.add(img); } while (imageCursor.moveToNext()); } return imageList; } } 

Это мой class адаптера:

 public class MyImageAdapter extends RecyclerView.Adapter { Context context; private LayoutInflater inflater; List data= Collections.emptyList(); private ClickListener clickListener; int width,height; public MyImageAdapter(Context context, List data1) { inflater = LayoutInflater.from(context); this.data=data1; this.context=context; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.all_row, parent, false); MyViewHolder holder=new MyViewHolder(view); return holder; } @Override public void onBindViewHolder(MyViewHolder holder, int position) { try{ ImageHolder current=data.get(position); holder.title.setText(current.title); Log.d("Imageid:"+current.iconid,""); Uri IMAGE_URI = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + current.iconid); Bitmap bitmap = Bitmap.createScaledBitmap(decodeUri(IMAGE_URI), 200, 200, true); holder.img.setImageBitmap(bitmap); } catch(Exception e){} } public void deleteRecyclerData(int position){ data.remove(position); notifyItemRemoved(position); } private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException { BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream( context.getContentResolver().openInputStream(selectedImage), null, o); final int REQUIRED_SIZE = 100; int width_tmp = o.outWidth, height_tmp = o.outHeight; int scale = 1; while (true) { if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) { break; } width_tmp /= 2; height_tmp /= 2; scale *= 2; } BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; return BitmapFactory.decodeStream( context.getContentResolver().openInputStream(selectedImage), null, o2); } @Override public int getItemCount() { return data.size(); } public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ TextView title; // TextView artist; ImageView img; CheckBox checkBox; public MyViewHolder(View itemView) { super(itemView); title= (TextView) itemView.findViewById(R.id.list_text_all); img= (ImageView) itemView.findViewById(R.id.list_image_all); img.setOnClickListener(this); } @Override public void onClick(View v) {} } public interface ClickListener{ public void itemClicked(View view, int position); } } 

Вы можете использовать StateListDrawable для достижения желаемого эффекта.

пример

Создайте новый файл ресурса Drawable в каталоге с возможностью drawable со следующим содержимым:

selector_row.xml

        

Теперь просто используйте этот StateListDrawable в качестве фона в строке-макете вашего RecyclerView

row_recyclerview.xml

    

Теперь, как только метод onClick() в вашем адаптере вызывается, вам просто нужно сделать следующее:

 // myBackground is the RelativeLayout root of your row myBackground.setSelected(true); 

Фон строк будет иметь цвет (в данном случае darker_gray ), если вы вызываете myBackground.setSelected(false) . Конечно, вы должны создать SparseBooleanArray, например, чтобы узнать, какая строка выбрана, а какая нет, поскольку строки будут повторно использоваться при прокрутке.

Изменить: запомнить выбранные элементы
Идея SparseBooleanArray заключается в том, чтобы запомнить выбранные элементы. Следуя образцу о том, как его использовать:

 public class MyImageAdapter extends RecyclerView.Adapter { private SparseBooleanArray selectedItems; // Other stuff [...] @Override public void onBindViewHolder(MyViewHolder holder, int position) { // Set the selected state of the row depending on the position holder.myBackground.setSelected(selectedItems.get(position, false)); } public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ @Override public void onClick(View v) { // Save the selected positions to the SparseBooleanArray if (selectedItems.get(getAdapterPosition(), false)) { selectedItems.delete(getAdapterPosition()); myBackground.setSelected(false); } else { selectedItems.put(getAdapterPosition(), true); myBackground.setSelected(true); } } } } 

в RecyclerView нет селектора, такого как ListView и GridView, но вы пытаетесь найти что-то, что сработало для меня

создать селектор, как показано ниже

              

затем установите этот чертеж в качестве фона вашего макета строки RecyclerView как

 android:background="@drawable/selector" 

Вы можете добавить это в свой row_item.xml

 android:clickable="true" android:background="?attr/selectableItemBackground" 

Например:

  

Если версия для Android – Lolipop или выше, селектор имеет пульсацию. И подсветка для другой версии. Надеюсь, поможет

Я пробовал несколько способов в течение нескольких часов, и вот два решения, с которыми я столкнулся. Оба решения предполагают, что мой RecyclerView объявлен следующим образом:

activity.xml

  

Здесь ничего особенного, просто регулярное объявление RecyclerView . Теперь давайте посмотрим другие файлы, начиная с самого легкого и жизнеспособного решения.

Первое решение (только для XML)

макет / item.xml

Два важных атрибута здесь, в корневой ViewGroup являются background и clickable .

   ...  

рисуем / selector_item.xml

      

Второе решение (XML + Java)

item.xml

Здесь нет background или атрибута clickable .

  ...  

Adapter.java

 public class Adapter extends RecyclerView.Adapter { public class ViewHolder extends RecyclerView.ViewHolder { public ViewHolder(View itemView) { super(itemView); itemView.setOnTouchListener(itemTouchListener); } } ... private View.OnTouchListener itemTouchListener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: v.setBackgroundResource(R.drawable.background_item_event_pressed); break; case MotionEvent.ACTION_CANCEL: // CANCEL triggers when you press the view for too long // It prevents UP to trigger which makes the 'pressed' background permanent which isn't what we want case MotionEvent.ACTION_OUTSIDE: // OUTSIDE triggers when the user's finger moves out of the view case MotionEvent.ACTION_UP: v.setBackgroundResource(R.drawable.background_item_event); break; default: break; } return true; } }; ... } 

Я настоятельно рекомендую использовать первое решение, так как его проще поддерживать и более мощным, так как оно также позволяет добавлять эффекты пульсации (в файлы drawable/background_item... XML), которые, как я считаю, невозможны с решением 2.

вы можете использовать этот код из адаптера

 LinearLayoutManager RvLayoutManager = (LinearLayoutManager)rootlayout.getLayoutManager(); View itemSelected = RvLayoutManager.findViewByPosition(position); itemSelected.setBackgroundColor(Color.Red); 

Вы должны создать селектор, который можно использовать с android:state_focused="true" как android:state_focused="true" ниже.

         

затем установите этот чертеж в качестве фона вашего макета строки RecyclerView как

 android:background="@drawable/selector" 

Если вам удастся использовать наблюдаемый паттерн, такой как Otto или AndroidRx, вы можете следить за тем, как выделить фон, как описано выше, и для каждого элемента itemView для viewHolder вы можете подписаться на наблюдаемую и отмену подписки, когда она отвлекается от вашего recyclerview, как я сделал здесь :

https://github.com/juanmendez/jm_android_dev/blob/master/01.fragments/06.fragments_with_rx/app/src/main/java/info/juanmendez/android/recyclerview/ui/listing/recyclerview/CountryHolder.java# L49

Кстати, для быстрой демонстрации мой itemView использует linearLayout, поэтому было легко установить цвет фона как желтый.

введите описание изображения здесь

Это решение более интерактивно выглядит как tableView в IOS. Затем он выделит ярлыки ячеек.

 @Override public void onBindViewHolder(Cell holder, final int position) { if(requests != null) { holder.setView(requests.get(position), context); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v) { Logs.print("In OnClickListener", position + " selected"); } }); holder.itemView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Logs.print("In Touch Handler", "A press has started"); v.setSelected(true); break; case MotionEvent.ACTION_UP: Logs.print("In Touch Handler", "A press has been completed"); v.setSelected(false); break; case MotionEvent.ACTION_CANCEL: Logs.print("In Touch Handler", "gesture aborted"); v.setSelected(false); break; } return true; } }); } } 
  • В чем разница между агрегацией, составом и зависимостью?
  • Выводит ли квадрат из прямоугольника нарушением Принципа замещения Лискова?
  • Стиль стилей для дизайна материалов для Android
  • MySQL: несколько таблиц или одна таблица со многими столбцами?
  • Как установить текст для просмотра из макета заголовка ящика в навигационном ящике без раздувания
  • Дизайн по контракту с использованием утверждений или исключений?
  • Существует ли типичный шаблон реализации государственного аппарата?
  • HTTP POST с параметрами запроса URL - хорошая идея или нет?
  • Откуда вы знаете, когда использовать шаблоны дизайна?
  • Как отличаются параметры прокси, декоратора, адаптера и моста?
  • Заводской шаблон. Когда использовать заводские методы?
  • Давайте будем гением компьютера.