Esby
Esby

Reputation: 105

Android | ViewHolder

I have taken an example code for implementing a RecyclerView, but trying to transpose it to work in a Child Fragment in my app.

The code is under 'Create Lists - examples' Creating Lists and Cards

I run into trouble with my adapter..

public static class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView mTextView;
        public ViewHolder(TextView v) {
            super(v);
            mTextView = v;
        }
    }

>  @Override
>     public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
>                                                    int viewType) {
>         View v = LayoutInflater.from(parent.getContext())
>                                .inflate(R.layout.my_text_view, parent, false);
>         ViewHolder vh = new ViewHolder(v);
>         return vh;
>     }

First, it doesn't build, complaining that I am calling constructor ViewHolder with a View, when the constructor is expecting a TextView. Looking at the code, I agree! But this is an official example so it must be right?

So what is different to my version compared with the example? Two things that I can think of...

1) the layout my_text_view is not given in the example, so I made my own. Did I make it right?

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
    android:id="@+id/t_title"
    android:title="title"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"/>

</LinearLayout>

2) I am calling the adapter from my child fragment, and the example was not written with fragments in mind. I've probably bitten off more than I can understand there.

Still, working this through, as far as i understand. The 'parent' coming into my OnCreateViewHolder, is my RecyclerView ?

'v' should be the LinearLayout of my 'my_text_view' ?

'ViewHolder' should end up being a class with property mTextView equaling the TextView from my xml.

I just don't see how I go from v=LinearLayout , to TextView??

Anyone like to help explain to this noob ??

Upvotes: 1

Views: 926

Answers (1)

DeeV
DeeV

Reputation: 36035

That example is not very good. It looks like two different projects spliced together. It should be something like this:

   public class MyAdapter extends RecyclerView.Adapter {
    public static class ViewHolder extends RecyclerView.ViewHolder {
            public TextView mTextView;
            public ViewHolder(View v) {
                super(v);
                mTextView = (TextView) v.findViewById(R.id.t_title);
            }
        }

      @Override
      public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_text_view, parent, false);
         ViewHolder vh = new ViewHolder(v);
         return vh;
      }
   }

To explain this segment:

onCreateViewHolder is the method that will be called any time the RecyclerView needs to create a new type of ViewHolder. This may get called only a dozen or so times to get enough Views to cover the screen or it may be called quite a few times if you have many view types.

The parameter parent in this case will be the RecyclerView that accompanies it. Why not just make it RecycerView? Because Google designers decided it should be a ViewGroup. Also it's an Adapter pattern so the only guarantee you're supposed to have is that it's a ViewGroup (i.e., may not be a RecyclerView so you shouldn't build the Adapter with that assumption). Realistically, it will pretty much always be a RecyclerView though.

The parameter int viewType is to tell you what kind of View you're building. This is determined if you override getItemViewType() method of the Adapter. You don't need to worry about this if you only have one type of View though.

For the ViewHolder, this is to basically cache the different types of Views in your layout. These can be ImageView, TextView, etc. These will be "recycled" constantly as the user scrolls so you're not always creating them. That way, you only have to update the Views with the current information. In this case, there's just a title. The ViewHolder passed in bindViewHolder will be where the actual updating happens. This is called all the time, so there's no need to initialize the Views in onCreateViewHolder. Just need to create them.

Upvotes: 3

Related Questions