Как реализовать одиночный выбор элемента в RecyclerView?
Насколько я знаю при прокрутке списка он не сохраняется, а при обратном прокручивании его на видимое место загружается разметка по умолчанию (не выбранная), поэтому выбор с элементов сбрасывается.
Приложение отображает список жанров, и сами фильмы (Картинка и русское название). Мне нужно реализовать выбор жанра (Просто чтобы фон изменялся и не исчезал при прокрутке), а при выборе другого жанра, старый снимал своё выделение как показано ниже:
Перепробовал много способов, но так и не нашел ответа на ру/eng сайтах/форумах.
Adapter
class Adapter(Items: ArrayList<Item>, val listener: Listener): RecyclerView.Adapter<Adapter.ViewHolder>(){
var Items = Items
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
var itemView: View? = null
when(viewType){
0 -> itemView = LayoutInflater.from(parent.context).inflate(R.layout.genres,parent, false)
1 -> itemView = LayoutInflater.from(parent.context).inflate(R.layout.list_item_genre,parent, false)
2 -> itemView = LayoutInflater.from(parent.context).inflate(R.layout.list_item_film,parent, false)
}
return ViewHolder(itemView!!)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
when(holder.itemViewType){
0,1 -> {
var genre: Genre = Items[position] as Genre
holder.textView?.text = genre.getTitle()
holder.bind(listener)
}
2 -> {
var film: Film = Items[position] as Film
holder.localized_name?.text = film.getName()
val transformation: Transformation = RoundedTransformationBuilder()
.cornerRadiusDp(4f)
.build()
Picasso.get().load(film.getUrl()).resize(145,216)
.error(R.drawable.ic_baseline_collections_240).transform(transformation).into(holder.imageView)
}
}
}
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var textView: TextView? = null
var imageView: ImageView? = null
var localized_name: TextView? = null
init {
textView = itemView.findViewById(R.id.list_item_genre)
imageView = itemView.findViewById(R.id.image_film)
localized_name = itemView.findViewById(R.id.localized_name)
}
fun bind(listener: Adapter.Listener){
textView?.setOnClickListener { listener.onClickFilter() }
textView?.setOnClickListener{
}
}
}
override fun getItemCount(): Int = Items.size
override fun getItemViewType(position: Int): Int {
val type: Int = Items.get(position).getItemType()
return type
}
interface Listener{
fun onClickFilter()
}}
MainActivity
class MainActivity : AppCompatActivity(), Adapter.Listener {
var Items: ArrayList<Item> = arrayListOf()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportActionBar?.title = "TestKinoApp"
init()
}
fun init(){
val recycler: RecyclerView = findViewById(R.id.recyclerView1)
val glmanager = GridLayoutManager(this@MainActivity,2) // Layout с двумя колонками
var uniqueSortedGenres: List<String> // Уникальный список жанров
CoroutineScope(Dispatchers.IO).launch {
val retrofit = Retrofit.Builder()
.baseUrl("https://s3-eu-west-1.amazonaws.com/sequeniatesttask/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val filmApi = retrofit.create(FilmApi::class.java)
val response = filmApi.getNestedFilms()
withContext(Dispatchers.Main) {
val items = response.body()?.films
val Allgenres: MutableList<String> = mutableListOf() // Все имеющиеся жанры
if(items != null){
for (i in 0 until items.count()){
Allgenres += items[i].genres
}
} else{
Log.e("RETROFIT_EROR", response.toString())
}
val SortedGenres = Allgenres.sorted() // Сортируется по алфавиту ( с повторами )
val Unique = LinkedHashSet<String>(SortedGenres) // // Отсортированный список с уникальными значениями (без повторов)
uniqueSortedGenres = Unique.toList()
//--------------------------------------------------------------------------------------------------------------------------------|
Fill_List(uniqueSortedGenres,items) // Заполнение списка
//--------------------------------------------------------------------------------------------------------------------------------|
val adapter = Adapter(Items,this@MainActivity)
val onSpanSizeLookup: SpanSizeLookup = object : SpanSizeLookup() { // Различное отображение элемнтов в зависимости от типа элемента
override fun getSpanSize(position: Int): Int {
if (adapter.getItemViewType(position) == 0 ) { return 2 } // Если заголовок, то во всю ширину
if (adapter.getItemViewType(position) == 1) { return 2 } // Если жанр, то во всю ширину
else{ return 1 }// Если фильм то в пол-ширины
}
}
glmanager.spanSizeLookup = onSpanSizeLookup;
recycler.layoutManager = glmanager
recycler.adapter = adapter
}
}
}
private fun Fill_List(UniqueSortedGenres: List<String>, ListFilms: List<Films>?){
Items.add(Genre("Жанры",0,0)) // Заголовок "Жанры"
// Добавление в список уникальных, отсортированных по алфавиту элементов жанра
for (i in 0 until UniqueSortedGenres.size)
{
Items.add(
Genre(
UniqueSortedGenres[i].substring(0,1).uppercase() + UniqueSortedGenres[i].substring(1),
1,
1 + i.toLong()))
}
Items.add(Genre("Фильмы",0,(Items.size + 1).toLong())) // Заголовок "Фильмы"
if (ListFilms!=null) {
for (i in 0 until ListFilms.count()) { // Добавление элементов в список фильмов (localized_name, image_url)
Items.add(Film(ListFilms[i].localized_name, ListFilms[i].image_url ?: "N/A", 2, (i+UniqueSortedGenres.size).toLong()))
}
}
}
Если понадобиться позже приложу остальной код.
