web-dev-qa-db-ja.com

RecyclerView.ViewHolderおよびRecyclerView.Adapterについて

  1. RecyclerView.ViewHolderクラスには、public final View itemViewのフィールドがあります。 onBindViewHolderメソッドは、指定された位置のアイテムを反映するようにitemViewの内容を更新する必要があることを示しています。 final修飾子は、このフィールドの値が変更できないことを示していませんか?

  2. 以下のコードは教科書からのものです:

    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) {
             ...
          }
    }
    

    ここでこれらのメソッドがRecyclerView.Adapterクラスから派生したRecyclerView.ViewHolderクラスのメソッドをオーバーライドできるのはなぜですか?

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

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

誰かがそれを説明できますか?

ありがとうございました。

6
user5157358

最後の修飾子は、このフィールドの値が変更できないことを示していませんか?

ビューの最後の修飾子は、ビューを1回のみ開始できることを示します(新しいビュー(コンテキスト)を作成するか、xmlファイルからビューを拡張します) )。ただし、viewプロパティは変更できます。 (つまり、ビューにTextViewが含まれている場合は、テキストを設定できます)

2番目の質問については、教科書は、ビューホルダーを使用してアダプターを実装する方法についてあまり正確ではありません。これは、カスタムビューホルダーを備えたアダプターの簡単な実装です。

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

}

そしてそのxmlファイル:

<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>

RecyclerView.Adapterを拡張する場合、これら3つのメソッドをオーバーライドする必要があることがわかります。

これがRecyclerViewの理解に役立つことを願っています。

10
xiaomi

1:-メインレイアウト

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

2:-アイテムのレイアウト

<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アイテム

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アダプタクラス

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

}

3
Amitsharma

最後の修飾子は、そのポインタまたは参照に別のオブジェクトを割り当てることができないことを意味しますが、ゲッターとセッターがあれば、パブリック属性やその他のオブジェクトのように、元のオブジェクトの内部値を変更できます。そして、ここで編集して、Android studioで提供されたコードを再作成しようとしましたが、「メソッドはスーパークラスのメソッドをオーバーライドしません」と表示されます。それ以外に、スーパークラスにはデフォルトのコンストラクターがないため、エラーが発生します。したがって、教科書は正しくないと思います。

0
hrss