简体   繁体   中英

About RecyclerView.ViewHolder and RecyclerView.Adapter

  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.

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. (ie 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.

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();
}

}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM