RecyclerView 中的 RatingBar
RatingBar in a RecyclerView
我有一个 RecyclerView
,里面有一个 TextView
和一个 RatingBar
。我不太确定在哪里处理 setOnRatingBarChangeListener
,应该在 RecyclerViewAdapter
还是其他地方处理?
总是尝试通过接口抽象这些东西,以便以后可以重用它并轻松维护代码。
你有多种方式。
首先考虑普通RecylerView.Adapter
class
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private List<Record> mRecords;
private OnRecordEventListener mClickListener;
public RecyclerViewAdapter(List<Record> records,OnRecordEventListener listener) {
this.mRecords = records;
this.mClickListener = listener;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recyclerview_item, viewGroup, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
Record record = records.get(i);
viewHolder.textViewTitle.setText(record.getName());
viewHolder.ratingBar.setRating(record.getRating());
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView textViewTitle;
private RatingBar ratingBar;
public ViewHolder(View itemView) {
super(itemView);
textViewTitle = (TextView) itemView.findViewById(R.id.text_view_title);
ratingBar = (RatingBar) itemView.findViewById(R.id.rating_bar_rating);
}
}
}
我会使用这样的界面
public interface OnRecordEventListener {
void onRatingBarChange(Record item,float value);
}
请注意,我可以做类似的东西
public interface OnRecordEventListener implements OnRatingBarChangeListener
但是你不会将项目对象 (Record
) 传递回实现此接口的 class,唯一的方法是 setTag
到 RatingBar
但我认为这是不好的解决方案。
并且您的 Activity
、Fragment
或任何对象都应实现此接口
创建时 ViewHolder
像这样将侦听器传递给构造函数。
public ViewHolder(View itemView, OnRecordEventListener listener) {
super(itemView);
textViewTitle = (TextView) itemView.findViewById(R.id.text_view_title);
ratingBar = (RatingBar) itemView.findViewById(R.id.rating_bar_rating);
bar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
@Override
public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
if (fromUser) {
listener.onRatingBarChange(mRecords.get(getLayoutPosition()), rating);
}
}
});
}
当然还有 onCreateViewHolder
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recyclerview_item, viewGroup, false);
return new ViewHolder(v,mClickListener);
}
您也可以根据需要使用 onBindViewHolder
中的 setter 方法执行此操作。我认为传递给构造函数就足够了。
另一种方法是在评级栏更改时使用类似 EventBus
的用户发送事件,但对我个人而言,使用侦听器方法更好,EventBus
是强大的设计架构,但它是很难调试,我认为在这种情况下它会是多余的。
编辑
此外,您还可以将此接口用于其他事件,例如按钮点击或其他任何事件,您只需要将方法添加到接口中,实现它并绑定到 ViewHolder
构造函数中。
更新
考虑到您在 Activity
中使用 RecyclerView
public class RecyclerActivity extends Activity implements OnRecordEventListener {
// all institutionalization, callbacks, hook methods
@Override
public void onCreate() {
// Initialization .....
mRecyclerView.setLayoutManager(...);
// Passing this because this class implements interface
mRecyclerView.setAdapter(new RecyclerViewAdapter(mRecord,this));
}
@Override
void onRatingBarChange(Record item,float value) {
// Save your object into database here
}
}
这取决于您的底层架构。
如果你正在使用 ORM
,那么你的对象可能是从基础 ORM 对象 class 继承而来的,所以它可能有 save
, update
如果您使用 ContentProvider
或 Cursor
直接从 Activity
保存数据,您应该手动进行序列化并保存到数据库中。
我有一个 RecyclerView
,里面有一个 TextView
和一个 RatingBar
。我不太确定在哪里处理 setOnRatingBarChangeListener
,应该在 RecyclerViewAdapter
还是其他地方处理?
总是尝试通过接口抽象这些东西,以便以后可以重用它并轻松维护代码。
你有多种方式。
首先考虑普通RecylerView.Adapter
class
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private List<Record> mRecords;
private OnRecordEventListener mClickListener;
public RecyclerViewAdapter(List<Record> records,OnRecordEventListener listener) {
this.mRecords = records;
this.mClickListener = listener;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recyclerview_item, viewGroup, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
Record record = records.get(i);
viewHolder.textViewTitle.setText(record.getName());
viewHolder.ratingBar.setRating(record.getRating());
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView textViewTitle;
private RatingBar ratingBar;
public ViewHolder(View itemView) {
super(itemView);
textViewTitle = (TextView) itemView.findViewById(R.id.text_view_title);
ratingBar = (RatingBar) itemView.findViewById(R.id.rating_bar_rating);
}
}
}
我会使用这样的界面
public interface OnRecordEventListener {
void onRatingBarChange(Record item,float value);
}
请注意,我可以做类似的东西
public interface OnRecordEventListener implements OnRatingBarChangeListener
但是你不会将项目对象 (Record
) 传递回实现此接口的 class,唯一的方法是 setTag
到 RatingBar
但我认为这是不好的解决方案。
并且您的 Activity
、Fragment
或任何对象都应实现此接口
创建时 ViewHolder
像这样将侦听器传递给构造函数。
public ViewHolder(View itemView, OnRecordEventListener listener) {
super(itemView);
textViewTitle = (TextView) itemView.findViewById(R.id.text_view_title);
ratingBar = (RatingBar) itemView.findViewById(R.id.rating_bar_rating);
bar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
@Override
public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
if (fromUser) {
listener.onRatingBarChange(mRecords.get(getLayoutPosition()), rating);
}
}
});
}
当然还有 onCreateViewHolder
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recyclerview_item, viewGroup, false);
return new ViewHolder(v,mClickListener);
}
您也可以根据需要使用 onBindViewHolder
中的 setter 方法执行此操作。我认为传递给构造函数就足够了。
另一种方法是在评级栏更改时使用类似 EventBus
的用户发送事件,但对我个人而言,使用侦听器方法更好,EventBus
是强大的设计架构,但它是很难调试,我认为在这种情况下它会是多余的。
编辑
此外,您还可以将此接口用于其他事件,例如按钮点击或其他任何事件,您只需要将方法添加到接口中,实现它并绑定到 ViewHolder
构造函数中。
更新
考虑到您在 Activity
RecyclerView
public class RecyclerActivity extends Activity implements OnRecordEventListener {
// all institutionalization, callbacks, hook methods
@Override
public void onCreate() {
// Initialization .....
mRecyclerView.setLayoutManager(...);
// Passing this because this class implements interface
mRecyclerView.setAdapter(new RecyclerViewAdapter(mRecord,this));
}
@Override
void onRatingBarChange(Record item,float value) {
// Save your object into database here
}
}
这取决于您的底层架构。
如果你正在使用
ORM
,那么你的对象可能是从基础 ORM 对象 class 继承而来的,所以它可能有save
,update
如果您使用
ContentProvider
或Cursor
直接从Activity
保存数据,您应该手动进行序列化并保存到数据库中。