次のような基本的なカスタムビューがあります。
_public class CustomView extends RelativeLayout {
private User user;
private ImageView profilePicture;
public CustomView(Context context) {
super(context);
init();
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
inflate(getContext(), R.layout.custom_layout, this);
profilePicture = (ImageView) findViewById(R.id.profilePicture);
// ACCESS USER MODEL HERE
// e.g. user.getUsername()
}
}
_
ご覧のとおり、ビューのユーザーデータにアクセスしたい(つまり、user.getUsername()
)。
また、RecyclerView
アダプターでカスタムビューを使用できる必要があります。
現在、私のアダプターは次のようになっています。
_public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private Context context;
private List<User> userData;
public MyAdapter(Context context, List<User> userData) {
this.context = context;
this.userData = userData;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View v) {
super(v);
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
// HOW TO INFLATE THE CUSTOM VIEW?
// ViewHolder viewHolder = new ViewHolder(customView);
return viewHolder;
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
// ANYTHING HERE?
}
@Override
public int getItemCount() {
return userData.size();
}
}
_
アダプタでカスタムビューを膨らませるにはどうすればよいですか?
また、onBindViewHolder()
に何かを入れるべきですか?
注:I mustカスタムビューを使用します。これは、このビューをさまざまなアダプター(つまり、このRecyclerView
アダプターだけでなく)で使用するためです。
次のようなCustomView
クラスを想定します。
public class CustomView extends RelativeLayout {
private User user;
private ImageView profilePicture;
// override all constructors to ensure custom logic runs in all cases
public CustomView(Context context) {
this(context, null);
}
public CustomView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public CustomView(
Context context,
AttributeSet attrs,
int defStyleAttr,
int defStyleRes
) {
super(context, attrs, defStyleAttr, defStyleRes);
// put all custom logic in this constructor, which always runs
inflate(getContext(), R.layout.custom_layout, this);
profilePicture = (ImageView) findViewById(R.id.profilePicture);
}
public void setUser(User newUser) {
user = newUser;
// ACCESS USER MODEL HERE
// e.g. user.getUsername()
}
}
RecyclerView.Adapter
とRecyclerView.ViewHolder
は次のようになります。
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
// no Context reference needed—can get it from a ViewGroup parameter
private List<User> userData;
public MyAdapter(List<User> userData) {
// make own copy of the list so it can't be edited externally
this.userData = new ArrayList<User>(userData);
}
@Override
public int getItemCount() {
return userData.size();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// no need for a LayoutInflater instance—
// the custom view inflates itself
CustomView itemView = new CustomView(parent.getContext());
// manually set the CustomView's size
itemView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
));
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.getCustomView().setUser(userData.get(position));
}
public class ViewHolder extends RecyclerView.ViewHolder {
private CustomView customView;
public ViewHolder(View v) {
super(v);
customView = (CustomView) v;
}
public CustomView getCustomView() {
return customView;
}
}
}
CustomView
は独自のセットアップを管理します。セットアップは独自のコンストラクターで行われ、この場合はXMLファイルのインフレーションを使用します。 (または、プログラムで子ビューを設定できます。)RecyclerView.Adapter
はインフレーションを実行する必要がありません。新しいCustomView
インスタンスを作成し、CustomView
に独自のセットアップを心配させます。CustomView
は、User
メソッドが呼び出されるまでsetUser
インスタンスを取得できないため、コンストラクターでユーザーアクセスを行うことはできません。いずれにせよ、1つのCustomView
ライフタイムにわたって、RecyclerView
は、異なる時間に多くの異なるユーザーの情報を表示するように要求できます。 CustomView
はこれを行うことができる必要があります。したがって、setUser
メソッドが導入されています。CustomView
はXMLではなくコードによってインスタンス化されるため、サイズの属性をXMLで定義することはできません。したがって、サイズ設定は、インスタンス化後にプログラムで行われます。onBindViewHolder
は、setUser
でCustomView
を呼び出して、CustomView
を正しいUser
インスタンスにリンクするだけです。ViewHolder
クラスは、RecyclerView
アイテムとCustomView
の間の単なるリンクになりました。RecyclerView
s内の別のクラスから事前に構築されたカスタムビューを使用する(つまり、RecyclerView.Adapter
内でXMLを拡張しない)ことは、決して議論されていないようです。カスタムビューがRecyclerView
内で排他的に使用されている場合でも、素晴らしいアイデアだと思います。なぜなら、それは 懸念の分離を促進する および 単一責任原則の順守 。
_CustomView extends RelativeLayout {
_
すでにビューがあります(まあ、ViewGroup
)
カスタムビューを拡張する方法
必要はありません...カスタムビューオブジェクトのポイントは、XMLを必要としないため、インフレが発生しないことです。
new CustomView()
を作成できますが、すべてのレイアウトパラメーターを設定する必要があり、XMLで見た目がきれいになります。
ほとんどのRecyclerView
チュートリアルでは、 XMLを使用した膨張 を示しています。
_View customView = inflater.inflate(...); ViewHolder viewHolder = new ViewHolder(customView);
_
クラスチェーンには_CustomView > RelativeLayout > ViewGroup > View
_があるため、これは機能するはずです。
_LayoutInflater inflater = LayoutInflater.from(context);
_
前に言ったように、膨らませたいXMLファイルがなければこれは必要ありません。
また、context
変数も必要ありません。
parent.getContext()
は良い解決策です。
_// ANYTHING HERE?
_
ええ、そうです、ViewHolder
をViewHolder
が保持すべきデータと「バインド」する必要があります。
繰り返しになりますが、すべてではありませんが、ほとんどのチュートリアルでこれを説明しています。