8
  1. The RecyclerView.ViewHolder class has a field that is public final View itemView. It says that the onBindViewHolder method should update the contents of the itemView to reflect the item at the given position . Doesn’t the final modifier indicate that the value of this field cannot change ?

  2. The code below is from the textbook :

    public class ViewHolder extends RecyclerView.ViewHolder {
       ...
          @Override
          public int getItemCount() {
              ...
          }
          @Override
          public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int    viewType) {
             ...
          }
          @Override
          public void onBindViewHolder(ViewHolder viewHolder, int position) {
             ...
          }
    }
    

    Why do these methods here can override the methods in the RecyclerView.Adapter class which is derived from the RecyclerView.ViewHolder class ?

https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html

https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder.html

Could someone explain it ?

Thank you.

  • They are not derived from the adapter class i don't think? They are both inner classes of RecyclerView. – Nick H Sep 06 '15 at 01:12

3 Answers3

13

Doesn’t the final modifier indicate that the value of this field cannot change ?

The final modifier on a View indicate that you can only initiate the view once (by creating a new View(context) or inflate a view from an xml file). But you can still modify the view property. (i.e. your view contains a TextView, you can set the text)

For your second question, the text book is not very precise about how to implement the adapter with a view holder. Here is a simple implementation of an adapter with a custom view holder.

public class Adapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{

    private List<String> titles;

    public Adapter(List<String> titles) {
        this.titles = titles;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        return new MyViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_view, viewGroup, false));
    }

    @Override
    public void onBindViewHolder(MyViewHolder myViewHolder, int i) {
        String title = titles.get(i);
        myViewHolder.title.setText(title);
    }

    @Override
    public int getItemCount() {
        return titles.size();
    }

    public static class MyViewHolder extends RecyclerView.ViewHolder {

        TextView title;

        public MyViewHolder(View itemView) {
            super(itemView);

            title = (TextView) itemView.findViewById(R.id.title_TV);
        }
    }

}

and the xml file for it:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <TextView
        android:id="@+id/title_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

You can see that if you extend RecyclerView.Adapter, you will have to override these 3 methods.

Hope this will help you to understand more the RecyclerView.

xiaomi
  • 6,553
  • 3
  • 29
  • 34
  • Could I ask why it should append `` to `RecyclerView.Adapter` and why the class name can be named `Adapter` which is already in http://developer.android.com/reference/android/widget/Adapter.html ? –  Sep 06 '15 at 02:46
  • I edit my post. The name of this class can by MyAdapter or whatever you want. There is no relation with the widget Adapter you linked. The method onCreateViewHolder should return a custom view holder which extends RecyclerView.ViewHolder. – xiaomi Sep 06 '15 at 02:52
  • 1
    If the name of this class is `MyAdapter`, should `RecyclerView.Adapter` be changed to `RecyclerView.Adapter` ? –  Sep 06 '15 at 03:10
  • For the first question, do you mean if I set The `final` modifier on a View, I can't change the view which has been initiated, but I still modify the view property ? –  Sep 06 '15 at 03:45
  • Yes, the final initiate the object, but you can modify the property of this object. if You use `final View view = new View(context)`, later you won't be able to to `view = null` or `view = new View(null)` – xiaomi Sep 06 '15 at 03:53
  • Could I also ask "I learned that paper in material design cannot be flipped over, but I found that like [Flipping CardView in RecyclerView](http://stackoverflow.com/questions/31325293/flipping-cardview-in-recyclerview.) I want to ask whether my knowledge is correct." ? Thank you. –  Sep 07 '15 at 12:06
  • You can do what you want, the guideline for the design is a "what you should do" but not a "what you must do". – xiaomi Sep 07 '15 at 12:20
  • This answer was complete but if you want to implement an onclick listener for a floatingactionbutton , this setOnClickListener method must be inset in which methods: onBind... or in the Custom MyViewHolder ? – maniaq Oct 27 '19 at 11:45
4

1 :- Main Layout

    <android.support.v7.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scrollbars="vertical" />

2:- items layout

<TextView
    android:id="@+id/title"
    android:textColor="#000000"
    android:textSize="16dp"
    android:textStyle="bold"
    android:layout_alignParentTop="true"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<TextView
    android:id="@+id/genre"
    android:layout_below="@id/title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<TextView
    android:id="@+id/year"
    android:textColor="#000FFF"
    android:layout_width="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_height="wrap_content" />

3:- MainActivity

 private List<Movie> movieList = new ArrayList<>();
 private RecyclerView recyclerView;
 private MoviesAdapter mAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.moviemainlayout);



    recyclerView = (RecyclerView) findViewById(R.id.recycler_view);

    mAdapter = new MoviesAdapter(movieList);
    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
    recyclerView.setLayoutManager(mLayoutManager);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setAdapter(mAdapter);

    prepareMovieData();
}

private void prepareMovieData() {
    Movie movie = new Movie("Mad Max: Fury Road", "Action & Adventure", "2015");
    movieList.add(movie);

    movie = new Movie("Inside Out", "Animation, Kids & Family", "2015");
    movieList.add(movie);

    movie = new Movie("Star Wars: Episode VII - The Force Awakens", "Action", "2015");
    movieList.add(movie);

    movie = new Movie("Shaun the Sheep", "Animation", "2015");
    movieList.add(movie);

    movie = new Movie("The Martian", "Science Fiction & Fantasy", "2015");
    movieList.add(movie);

    movie = new Movie("Mission: Impossible Rogue Nation", "Action", "2015");
    movieList.add(movie);

    movie = new Movie("Up", "Animation", "2009");
    movieList.add(movie);

    movie = new Movie("Star Trek", "Science Fiction", "2009");
    movieList.add(movie);

    movie = new Movie("The LEGO Movie", "Animation", "2014");
    movieList.add(movie);

    movie = new Movie("Iron Man", "Action & Adventure", "2008");
    movieList.add(movie);

    movie = new Movie("Aliens", "Science Fiction", "1986");
    movieList.add(movie);

    movie = new Movie("Chicken Run", "Animation", "2000");
    movieList.add(movie);

    movie = new Movie("Back to the Future", "Science Fiction", "1985");
    movieList.add(movie);

    movie = new Movie("Raiders of the Lost Ark", "Action & Adventure", "1981");
    movieList.add(movie);

    movie = new Movie("Goldfinger", "Action & Adventure", "1965");
    movieList.add(movie);

    movie = new Movie("Guardians of the Galaxy", "Science Fiction & Fantasy", "2014");
    movieList.add(movie);

    mAdapter.notifyDataSetChanged();
}

}

ModelClass items

public class Movie {
private String title, genre, year;

public Movie() {
}

public Movie(String title, String genre, String year) {
    this.title = title;
    this.genre = genre;
    this.year = year;
}

public String getTitle() {
    return title;
}

public void setTitle(String name) {
    this.title = name;
}

public String getYear() {
    return year;
}

public void setYear(String year) {
    this.year = year;
}

public String getGenre() {
    return genre;
}

public void setGenre(String genre) {
    this.genre = genre;
}

}

3 Adapter class

 public class MoviesAdapter extends 
   RecyclerView.Adapter<MoviesAdapter.MyViewHolder> {

private List<Movie> moviesList;

public class MyViewHolder extends RecyclerView.ViewHolder {
    public TextView title, year, genre;

    public MyViewHolder(View view) {
        super(view);
        title = (TextView) view.findViewById(R.id.title);
        genre = (TextView) view.findViewById(R.id.genre);
        year = (TextView) view.findViewById(R.id.year);
    }
}


public MoviesAdapter(List<Movie> moviesList) {
    this.moviesList = moviesList;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.movie_list_row, parent, false);

    return new MyViewHolder(itemView);
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    Movie movie = moviesList.get(position);
    holder.title.setText(movie.getTitle());
    holder.genre.setText(movie.getGenre());
    holder.year.setText(movie.getYear());
}

@Override
public int getItemCount() {
    return moviesList.size();
}

}

Amitsharma
  • 1,577
  • 1
  • 17
  • 29
0

The final modifier means that you can't assign another object to that pointer or reference, but you can still change the original object's internal values, like any public attributes or any other, provided the getters and setters. And, editing here, I tried to recreate the code you gave us on android studio, and it's telling me that "Method does not override method from it's superclass". Besides that, i'm getting an error because the superclass doesn't have a default constructor. So, I don't think the textbook is right.

hrss
  • 137
  • 2
  • 2
  • 10
  • Does `android.support.v7.widget.RecyclerView.Adapter` mean that `RecyclerView.Adapter` class is the subclass derived from the `RecyclerView.ViewHolder` class ? I ran the code from the textbook, and didn't get an error ... –  Sep 06 '15 at 02:13
  • I don't think so. It means it receives a parameter VH that is a subclass of ViewHolder. – hrss Sep 06 '15 at 02:14
  • In another place, it says "RecyclerView.Adapter implementations should subclass ViewHolder" (from https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder.html). What does it actually mean ? –  Sep 06 '15 at 02:16
  • And, did you actually make this code runnable? like putting some real stuff instead of "..."? I had to make some changes before i got the errors. – hrss Sep 06 '15 at 02:18
  • I think it means creating a ViewHolder class that extends RecyclerView.ViewHolder inside the adapter, like in xiaomi's answer. – hrss Sep 06 '15 at 02:23
  • I read the code again, and found that it is just like xiaomi's answer. the methods should be put in `public class MyAdapter extends RecyclerView.Adapter`, and what I write above is incorrect. –  Sep 06 '15 at 03:48