0

Хочется возможно странного: организовать перелистывание статических страниц (отдельные файлы разметки) с помощью ViewPager2, без создания фрагментов. Что-то вроде этого:

class ModbusPageAdapter(private val binding: ViewBinding, private val pages: List<ViewBinding>) : RecyclerView.Adapter<ModbusPageAdapter.ModbusPageHolder>() {

var prevPosition: Int = 0 class ModbusPageHolder(binding: ViewBinding): RecyclerView.ViewHolder(binding.root) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ModbusPageHolder { return ModbusPageHolder(binding) }

override fun getItemCount(): Int { return pages.size }

override fun onBindViewHolder(holder: ModbusPageHolder, position: Int) { val page = pages[position]

pages[prevPosition].root.visibility = View.INVISIBLE
page.root.visibility = View.VISIBLE
prevPosition = position

}

}

Т.е. в основном коде создаю основной binding для "контейнера" и список binding-ов для страниц, их передаю в адаптер viewpager-а. Однако это не работает, т.к. holder выбрасывает исключение "ViewHolder views must not be attached when created". Если внутри адаптера использовать не binding, а "надувать" из R.layout, то естественно, объекты внутри viewpager-а и в основном коде будут разными. Так вот: как их всех подружить?

  • это какой-то новый уровень извращения. для начала, почитайте про жизненный цикл Фрагментов и как они работают – Wlad Feb 15 '24 at 08:16
  • А причем здесь фрагменты? Из описания на ViewPager2: Display Views OR Fragments in a swipeable format. Я ж написал, что хочу без создания фрагментов. Не получится? – Argon-11 Feb 15 '24 at 08:19
  • Я так и не понял что вы хотите сделать. Ошибка говорит что вы пытаетесь отобразить вью из одного объекта биндинга более одного раза. А происходит это потому что в каждый холдер вы отдаёте биндинг контейнера вместо биндинга элемента. – woesss Feb 15 '24 at 12:37
  • Ну вот есть у меня несколько xml с разным содержанием. Их надо свайпить в одном экране, но при этом не создавая фрагмент на каждую разметку. В активити должен иметься биндинг к каждому из этих экранов для организации интерфейса с пользователем. – Argon-11 Feb 15 '24 at 12:37
  • Вы отдаёте биндинг контейнера во все холдеры, а должны в каждый холдер свой биндинг из списка pages. Какую-то сомнительную архитектуру вы реализуете. Но если на то пошло - задействуйте механизм viewType: https://ru.stackoverflow.com/a/470214/11515 – woesss Feb 15 '24 at 12:43
  • Спасибо! Понял свою ошибку: не вкурил, что холдер в адаптере не один )) – Argon-11 Feb 15 '24 at 12:54

1 Answers1

0

Благодаря мастеру woesss удалось разобраться.

Финальный вариант:

class SlidePageAdapter(private val pages: List<ViewBinding>) :
RecyclerView.Adapter<SlidePageAdapter.SlidePageHolder>() {
override fun getItemViewType(position: Int): Int {
    return position
}
class SlidePageHolder(binding: ViewBinding) : RecyclerView.ViewHolder(binding.root)

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SlidePageHolder {
    return SlidePageHolder(pages[viewType])
}
override fun getItemCount(): Int {
    return pages.size
}

override fun onBindViewHolder(holder: SlidePageHolder, position: Int) {
}

}

Можно передать список из любого количества биндингов на вьюхи, все работает и не выглядит извращением! Woesss, большое спасибо!