#kotlin #android-recyclerview #adapter #android-viewbinding
Вопрос:
Я новичок в языке программирования Котлин. У меня есть несколько вопросов, касающихся повторного просмотра и привязки просмотра. Возможно, мой английский не очень хорош. Я сожалею об этом. Но я сделаю все возможное, чтобы объяснить. Я был бы рад, если бы вы могли ответить на мои вопросы. Пожалуйста, прочитайте вопросы, просмотрев изображения
1.) Мы передаем представление конструктору класса LandmarkHolder. Но когда мы отправляем это представление конструктору класса RecyclerView.ViewHolder, мы создаем binding.root.
а) Насколько я знаю, мне нужно написать объект RecyclerViewRowBinding (который я написал как привязку) в конструкторе Recycler.ViewHolder «таким же образом» и отправить его туда. Но почему я должен писать binding.root вместо «привязка»? Почему я не могу просто ввести «привязка»? Потому что привязка уже имеет сам дизайн.
2.) При создании раздувателя макета мы обычно обращаемся к XML-файлу старым методом (R. layout. ….) и раздуть его, то есть преобразовать в код java. Структура здесь изменилась. Конечно, он снова преобразуется в код java, но возникает запутанная ситуация, которую я не смог решить:
Класс из recycler_row.xml файл создается под названием RecyclerRowBinding.
У этого класса есть метод надувания. Я читал с его веб-сайта. Кроме того, этот класс напрямую ссылается на идентификаторы представлений в макете, которые связаны с ним. Теперь у меня в голове застряло вот что: что я здесь раздуваю? Потому что в старом использовании (с finviewbyid), когда мы писали метод inflate, мы добавляли исходный xml-файл внутри метода iflate.(Например, CardView), но в этом новом методе его нет. После того, как родитель записан, attachtoParent записывается как False.
3.)То, что мы называем этим родителем, представляет мой RecyclerView?
4.) Объект holder в функции onBindViewHolder принадлежит классу Landmarkholder. Поэтому он использует свойства этого класса. Но я вижу, что он может получить доступ к чему-то, называемому ItemView. Вот как ItemView может относиться к классу Landmarkholder. Но я смотрю на сам класс, ничего, связанного с этим представлением элементов, не определено. Как это доходит до представления элемента? Конечно, цель вызова itemview-вызвать контекст. Если контекст в нем существует, то itemview также является производным от другого класса. Является ли он производным от класса представления? и класс представления имеет этот контекст, я думаю, это правильно? Как я могу назвать это представление элементов с объектом «держатель»?
5.) Этот onCreateViewHolder возвращает объект LandmarkHolder(привязка). Затем эту функцию необходимо вызвать в другом месте, чтобы она работала. (Обычно его, конечно, следует называть) Но откуда он взялся? На самом эмуляторе?
Комментарии:
1. Пожалуйста, опубликуйте фактический текст вашего кода вместо изображений кода. Это облегчает чтение, и люди, которые вам отвечают, могут скопировать и вставить его, а также для того, чтобы вопрос появлялся в результатах поиска.
Ответ №1:
Я не понял всех ваших вопросов, но, возможно, этот обзор поможет.
ViewBinding берет каждый из ваших XML-макетов и создает для них класс привязки, состоящий из свойств, соответствующих каждому представлению, имеющему идентификатор, плюс еще одно свойство с именем root
, содержащее представление верхнего уровня. Он также имеет статические функции, называемые bind
и inflate
. Так что, если у вас есть такой макет:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="vertical">
<TextView
android:id="@ id/recyclerRowTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="Test"
android:textColor="#0820aa"
android:textSize="20sp" />
</LinearLayout>
Затем он создает класс, эквивалентный этому (на Java, но я покажу версию Kotlin, так как это то, что вы изучаете).:
class RecyclerRowBinding private constructor(
val root: LinearLayout,
val recyclerRowTextView: TextView
) {
companion object {
fun bind(view: View): RecyclerRowBinding {
val root = view as LinearLayout
val recyclerRowTextView = root.findViewById<TextView>(R.id.recyclerRowTextView)
return RecyclerRowBinding(root, recyclerRowTextView)
}
fun inflate(layoutInflater: LayoutInflater): RecyclerRowBinding {
return inflate(layoutInflater, null, false)
}
fun inflate(layoutInflater: LayoutInflater, parent: ViewGroup?, attachToParent: Boolean): RecyclerRowBinding {
val root = layoutInflater.inflate(R.layout.recycler_row, parent, attachToParent)
return bind(root)
}
}
}
Я не совсем понял ваши вопросы, но кое-что нужно заметить:
- Он по-прежнему раздувает ваши представления из XML с помощью LayoutInflater, как если бы вы делали это без привязки к представлению.
- Сама привязка не является классом представления. Он содержит только ссылки на представления.
Конструктору абстрактного класса RecyclerView.ViewHolder требуется itemView
объект, который является корневым представлением макета элемента, поэтому вы должны перейти binding.root
к этому конструктору. Сама привязка-это не представление. У RecyclerView.ViewHolder также есть свойство для этого itemView
, поэтому при создании собственного держателя представления с привязкой существует два разных способа доступа к корневому представлению: либо с помощью holder.binding.root
или holder.itemView
. Однако binding.root
он будет иметь тип LinearLayout и itemView
будет менее конкретным ViewGroup
.
Adapter.onCreateViewHolder()
вызывается RecyclerView, когда ему требуется другое представление для отображения и у него нет предыдущих представлений, которые он мог бы переработать.
Комментарии:
1. Прежде всего, спасибо вам за ваш ответ. Я добавил еще одно изображение. В изображении есть вопрос. Я был бы очень рад, если бы вы ответили.
2. И как вы можете открыть класс RecyclerRowBinding? Я нажимаю на него, нажимая ctrl, но он направляет меня к XML-файлу этого класса.
3. Что касается вашего вопроса на изображении, класс привязки не может быть одновременно представлением и вашей конкретной привязкой. Например, корнем вашего макета является класс LinearLayout. Привязка-это класс, который содержит ссылки на ваши конкретные представления, поэтому он не может быть экземпляром LinearLayout. Кроме того, класс привязки может быть привязан к экземплярам вашего макета, которые уже были созданы. Они не означают, что вы должны проверять класс привязки, но вы можете найти его, если поищете в
generated
каталоге своего проекта после его создания.4. Спасибо за ваш ответ, мне было трудно его понять, но вы мне помогли, большое спасибо