【问题标题】:How can i capture clicks in RecycleView using databinding and MVVM如何使用数据绑定和 MVVM 在 RecyclerView 中捕获点击
【发布时间】:2017-09-19 10:47:57
【问题描述】:

我有很多适配器和视图、视图模型等等。由于很难维护那些我想在这种情况下使用数据绑定和 mvvm。现在我尝试将项目点击转发到视图模型中。由于它是一个回收视图,因此我很乐意不要失去减少内存使用量的功能。

目前我有一个设置 ViewModel 的视图(活动)。 ViewModel 本身有一个适配器。适配器有一个构造函数,它接收视图模型并将其设置到项目中。

Item 使用它来将事件发送回 ViewModel。它是如何影响记忆的?有没有更好的方法来做到这一点?我以前用过 RXJava,但这看起来是同一个概念,不是吗?这是我的示例代码(截断)。

查看

public class ScenesFragment extends BaseFragment implements Observer {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    this.scenesFragmentBinding = DataBindingUtil.inflate(inflater, R.layout.scenes_fragment, container, false);
    this.scenesListViewModel = new ScenesListViewModel(getContext());
    this.scenesFragmentBinding.setViewModel(this.scenesListViewModel);

    View view = this.scenesFragmentBinding.getRoot();
    return view;
}

}

基本布局

<layout ... >
    <data><variable name="viewModel" type=".viewmodel.ScenesListViewModel"/></data>
        <android.support.v7.widget.RecyclerView
            app:adapter="@{viewModel.adapter}"
            app:layoutManager="@{viewModel.layoutManager}" />
</layout>

视图模型

public class ScenesListViewModel extends Observable implements IViewModel {

    public final SceneAdapter adapter;
    private List<Scene> scenes = new ArrayList<>();

    public ScenesListViewModel(@NonNull Context context) {
        this.adapter = new SceneAdapter(context, scenes, this);
     }

    public void onRemoveClick(Scene scene) {
        Timber.d("Clicked remove in the scene:" + scene);
    }
}

项目布局

<layout>
    <data>
        <variable name="scene"type=".model.Scene"/>
        <variable name="viewModel" type=".viewmodel.ScenesListViewModel"/>
    </data>
               <ImageButton
                    android:id="@+id/sceneDelete"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:layout_margin="15dp"
                    android:layout_weight="1"
                    android:background="@null"
                    android:onClick="@{() -> viewModel.onRemoveClick(scene)}"
                    android:src="@drawable/ic_delete_forever_white_48px"/>
                 </LinearLayout>
   </layout>

最后是将 viewModel 设置到项目中的适配器。

适配器

public class SceneAdapter extends RecyclerView.Adapter<SceneAdapter.BindingHolder> {
private Context context;
private List<Scene> scenes;
private ScenesListViewModel scenesListViewModel;

public SceneAdapter(Context context, List<Scene> list, ScenesListViewModel scenesListViewModel) {
    this.context = context;
    this.scenes = list;
    this.scenesListViewModel = scenesListViewModel;
}

@Override public void onBindViewHolder(SceneAdapter.BindingHolder holder, int position) {
    final Scene scene = scenes.get(position);
    holder.binding.setScene(scene);
    holder.binding.setViewModel(scenesListViewModel);
    holder.binding.executePendingBindings();
}

另一种方法是在 ViewModel 中设置一个 Listener,但这更有可能是 mvp 然后是 mvvm。我也可以再次使用 RXJava 并在适配器中创建一个主题,但我想使用 android 板载工具来解决它。

【问题讨论】:

    标签: android mvvm data-binding


    【解决方案1】:

    在您的 BindingHolder 子类中实现 onClickListener

    class BindingHolder extends RecyclerView.ViewHolder
        implements OnClickListener {
          // code code code
     }
    @Override
        public void onClick(View v) {
            //code code code, use getAdapterPosition() to get the... adapter position
        }
    }
    

    【讨论】:

    • 谢谢,但这与数据绑定无关,它是我最后写的可能方式之一。
    【解决方案2】:

    您可以使用“by activityViewModels”在 ViewHolder 中获取相同的 ViewModel。

    【讨论】:

    • 从 2017 年开始......除此之外,它是 Java,而不是 Kotlin。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多