Можно ли использовать элемент ViewHolder вне onBindViewHolder?
Это мой класс адаптера
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = mValues[position]
with(holder.mView) {
tag = item
txvTitle.text = item.title
setOnClickListener(mOnClickListener)
}
}
inner class ViewHolder(val mView: View) :RecyclerView.ViewHolder(mView{})
Если у меня есть одна функция в адаптере, как я могу использовать txvTitle
?
fun checkHashMapExists(hashMap: HashMap<Long, ABC>?, newValues: ArrayList<OT>){
for(i in newValues){
if (hashMap?.keys.toString().contains(i.id)){
txvTitle.setTextColor(Color.parseColor("#000000")) // txvTitle cannot resolved
}
}
}
ФрагментА
override fun onResume() {
super.onResume()
mAdapter.checkHashMapExists(hashMap,otList)
}
Обычно вы не должны использовать ViewHolder
вне onBindViewHolder
. Весь код, связанный с пользовательским интерфейсом, должен вызываться внутри onBindViewHolder
. Лучше вызвать notifyDataSetChanged
или другой notifyXXX
метод, чтобы перерисовать ваш RecyclerView
контент.
@JohnJoe Добавьте someField
к своему адаптеру. Когда функция вызывается из фрагмента, обновите значение someField
и вызовите notifyDataSetChanged
. Внутри onBindViewHolder
вы должны уважать someField
. Нравится: if (someField) { use color1} else {use color2}
Несмотря на то, что не рекомендую его использовать, вы можете вызвать следующий метод, чтобы получить ViewHolder для элемента данных в позиции i
:
MyViewHolder holder = (MyViewHolder) mRecyclerView.findViewHolderForAdapterPosition(i);
if (holder != null) {
// Do whatever you want
}
Имейте в виду, что документация говорит об этом методе:
Return the
ViewHolder
for the item in the given position of the data set. UnlikefindViewHolderForLayoutPosition(int)
this method takes into account any pending adapter changes that may not be reflected to the layout yet. On the other hand, ifnotifyDataSetChanged()
has been called but the new layout has not been calculated yet, this method will return null since the new positions of views are unknown until the layout is calculated.
Вместо этого что бы я сделал, если бы я был тобой должен иметь атрибут в классе вашей модели, который указывает, какой цвет его ViewHolder должен использовать для отображения текста txtView.title
.
Затем, когда вы хотите обновить цвет элемента (или элементов) в вашем RecyclerView, вы можете изменить этот атрибут своего класса модели, а затем вызвать notifyDataSetChanged();
Адаптер не может узнать, что означает txvTitle
, поскольку он относится к одному элементу в RecyclerView
.
Однако внутри ViewHolder
это свойство (если оно существует) связано с представлением, которое «подготавливается».
Таким образом, обновления представления должны выполняться только в классе ViewHolder
.
Взгляните на пример это.
В этом примере создается отдельный класс, который расширяет RecyclerView.Viewholder(view)
.
В этом классе определен метод с именем bind
, которому передается объект (или модель), который используется для заполнения представления.
Метод create
увеличивает макет представления, которое будет отображаться в RecyclerView
Я использую notifyDataSetChanged()
. Спасибо !
Вы можете создать функцию в своем классе адаптера, которая принимает Функция высшего порядка в качестве параметра, а затем выставить свой объект ViewHolder
в этой функции для использования вне Класс адаптера.
Посмотрите, как это можно сделать:
Допустим, у вас есть Класс адаптера, как показано ниже.
class Adapter {
...
// Here we create object of our Higher order function
var holderCallback: ((RecyclerView.ViewHolder?) -> Unit)? = null
//Then We provide callback like below in onBindViewHolder method
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
... Some binding stuff
holderCallback?.let {
it(holder)
}
... even some more stuff
}
}
И теперь мы можем получить доступ извне (В вашем случае из класса Fragment)
class Fragment {
// Here we have adapter object
...
//So, we get our callback like below from any method in here
...Inside some method where we receive callback
adapter.holderCallback { viewHolder: RecyclerView.ViewHolder? -> //Here you've got ViewHolder object
// Now do some amazing stuff here !!
}
}
Вы хотите изменить цвет текста элемента держателя на основе этого метода адаптера, верно?
Я. Как я могу передать два параметра из фрагмента в класс адаптера?
Где эти оба параметра? Являются ли они классом адаптера или классом фрагмента?
Эта строка в FragmentA mAdapter.checkHashMapExists(hashMap,otList)
Кажется, я не могу ясно понять вашу дилемму.
Я хочу изменить цвет txvTitle, когда функция вызывается из фрагмента. Как я могу использовать notifyDataSetChanged в этом случае?