Использовать элемент ViewHolder снаружи onBindViewHolder? - PullRequest
1 голос
/ 10 апреля 2019

Можно ли использовать элемент 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
         }
      }   
    }

Fragmenta

 override fun onResume() {
        super.onResume()
        mAdapter.checkHashMapExists(hashMap,otList)
    }

Ответы [ 4 ]

2 голосов
/ 10 апреля 2019

Даже если я не рекомендую использовать его , вы можете вызвать следующий метод, чтобы получить ViewHolder для элемента данных в позиции i:

MyViewHolder holder = (MyViewHolder) mRecyclerView.findViewHolderForAdapterPosition(i);
if(holder != null) {
    // Do whatever you want
}

Помните, что документация говорит об этом методе:

Возвращает ViewHolder для элемента в заданной позиции набора данных. В отличие от findViewHolderForLayoutPosition(int) этот метод учитывает любые ожидающие изменения адаптера, которые еще не могут быть отражены в макете. С другой стороны, если был вызван notifyDataSetChanged(), но новый макет еще не был рассчитан, этот метод вернет ноль, поскольку новые позиции видов неизвестны до тех пор, пока макет не будет вычислен .

Вместо этого , что бы я сделал, если бы вы были , в вашем классе модели был бы атрибут, указывающий, какой цвет должен использовать его ViewHolder для отображения текста txtView.title.

Затем, когда вы захотите обновить цвет элемента (или элементов) в вашем RecyclerView, вы можете изменить этот атрибут класса вашей модели и затем вызвать notifyDataSetChanged();

1 голос
/ 10 апреля 2019

Вы можете создать функцию в своем классе адаптера, которая будет принимать функцию более высокого порядка в качестве параметра, а затем выставить объект 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 !!
    }
}
1 голос
/ 10 апреля 2019

Адаптер не может знать, что означает txvTitle, поскольку он относится к одному элементу в RecyclerView. Однако в пределах ViewHolder это свойство (если оно существует) относится к представлению, которое «готовится».

Таким образом, обновления представления должны выполняться только в классе ViewHolder.

Взгляните на этот пример. В этом примере создается отдельный класс, который расширяет RecyclerView.Viewholder(view). Внутри этого класса определен метод с именем bind, которому передается объект (или модель), который используется для заполнения представления. Метод create раздувает компоновку вида, который будет нарисован в RecyclerView

1 голос
/ 10 апреля 2019

Обычно вы не должны использовать ViewHolder за пределами onBindViewHolder.Весь код, связанный с пользовательским интерфейсом, должен вызываться внутри onBindViewHolder.Предпочитайте notifyDataSetChanged или другой метод notifyXXX, чтобы перерисовать содержимое RecyclerView.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...