0

I have two ViewHolders with two different layout files. What I'd like to do is inflate one layout for a given ViewHolder and then a second later, reinflate it with a different layout.

Here is some code:

class MyAdapter(context: Context,
                          myList: List<MyUiModel> = emptyList(),
                          private val clickListener: MyListener)
: RecyclerView.ViewHolder(context, myList) {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
    val layoutInflater = LayoutInflater.from(parent.context)
    return when (viewType) {
        TYPE_A -> 
            MyViewHolder.TypeAViewHolder(
                    layoutInflater.inflate(R.layout.type_a, parent, false), clickListener)
        else -> MyViewHolder.TypeBViewHolder(
                    layoutInflater.inflate(R.layout.type_b, parent, false), clickListener)
    }
}

So, whenever I need to instantiate TypeAViewHolder, I would need to inflate type_a layout first, and then I would like to inflate type_b layout which will replace the type_a layout (there will be fade in/fade out animation between the two which I don't need help with). I am having a hard time inflating the layouts in sequence.

I tried the following with and without Thread.sleep(1000L) in between.

TYPE_A -> {
    MyViewHolder.TypeBViewHolder(
                    layoutInflater.inflate(R.layout.type_b, parent, false), clickListener)

    MyViewHolder.TypeAViewHolder(
                    layoutInflater.inflate(R.layout.type_a, parent, false), clickListener)
}

But when I add log statements to my ViewHolders, only the last one listed (TypeAViewHolder) gets bound to.

P.S. I know what I am trying to do is an odd thing to do but it is a requirement I have.

Thanks in advance!

liminal
  • 1,144
  • 2
  • 13
  • 24
  • Are you sure you understand how RecyclerView pattern works? You only get enough viewholders to fill your viewport, so even with 6000 items in list `onCreateViewHolder` will be called about 5-10 times. – Pawel Aug 30 '18 at 19:42

2 Answers2

0

The case you are describing can be solved by using MyViewHolder.post() method. in general post will wait for the MyViewHolder to render layout B on screen and then run the code existing in the post method later on.

TYPE_A -> {
    MyViewHolder.TypeBViewHolder(
                    layoutInflater.inflate(R.layout.type_b, parent, false), clickListener)

 MyViewHolder.post(new Runnable() {
            @Override
            public void run() {
                  // if you want a delay use Thread.sleep(1000L) here 
                   Thread.sleep(1000L);

                  //to inflate view after layout B is inflated and waited for 1sec
                   MyViewHolder.TypeAViewHolder(
                             layoutInflater.inflate(R.layout.type_a, parent, false), clickListener);
            }
        }); 

}

About post method in view: https://stackoverflow.com/a/13840315/7972699

Anmol
  • 8,110
  • 9
  • 38
  • 63
0

I ended up using ViewSwitcher with a single ViewHolder to accomplish this. In the ViewHolder I handle itemView differently if it is of type ViewSwitcher

liminal
  • 1,144
  • 2
  • 13
  • 24