RecyclerView 中的 RatingBar

RatingBar in a RecyclerView

我有一个 RecyclerView,里面有一个 TextView 和一个 RatingBar。我不太确定在哪里处理 setOnRatingBarChangeListener,应该在 RecyclerViewAdapter 还是其他地方处理?

总是尝试通过接口抽象这些东西,以便以后可以重用它并轻松维护代码。

你有多种方式。

首先考虑普通RecylerView.Adapterclass

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,唯一的方法是 setTagRatingBar但我认为这是不好的解决方案。

并且您的 ActivityFragment 或任何对象都应实现此接口

创建时 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 
    }
}

这取决于您的底层架构。

  1. 如果你正在使用 ORM ,那么你的对象可能是从基础 ORM 对象 class 继承而来的,所以它可能有 saveupdate

  2. 如果您使用 ContentProviderCursor 直接从 Activity 保存数据,您应该手动进行序列化并保存到数据库中。