为了账号安全,请及时绑定邮箱和手机立即绑定

带有 viewModel 和实时数据的 RecyclerView 适配器

带有 viewModel 和实时数据的 RecyclerView 适配器

HUX布斯 2021-08-19 18:41:42
我开始使用 android jetpack arch 组件并遇到了一些困惑。另请注意数据绑定不是一个选项。我有一个具有 RecylcerView 的活动。我有一个如下所示的 ViewModelpublic class Movie extends ViewModel {public Movie movie;public URL logoURL;private MutableLiveData<Drawable> logo;public MutableLiveData<Drawable> getLogo() {    if (logo == null) {        logo = new MutableLiveData<>();    }    return logo;}public PikTvChannelItemVM(Movie movie, URL logo) {    this.movie = movie;    this.logoURL = logoURL;}public Bitmap getChannelLogo() {  //Do some network call to get the bitmap logo from the url }}以上都很好,尽管在我的回收站视图中有以下代码。尽管在 onbindviewholder 中,当我尝试从 viewmodels 实时数据中观察返回的图像时,它需要一个生命周期所有者参考,而我的回收者视图中没有。
查看完整描述

3 回答

?
慕容森

TA贡献1853条经验 获得超18个赞

您的适配器列表类型不应是视图模型。如果您想在没有绑定的情况下使用实时数据,您需要在列表更新时自动更改 ui。

你可以这样做:

首先,您的电影类必须是模型类,而不是视图模型。

像往常一样做适配器。只需添加一个setList(Movie) 方法。此方法应更新适配器列表。不要忘记在更新列表后通知适配器。

然后创建 livedata 列表,如

MutableLiveData<List<Movie>> movieLiveData = 
    new MutableLiveData<>();

你想在哪里。

在活动中观察这个列表,并在observe{}中调用适配器setList(Movie)方法。

毕竟,如果您的列表更新,setList(Movie)将触发 medhod,然后您的 ui 将更新。


查看完整回答
反对 回复 2021-08-19
?
弑天下

TA贡献1818条经验 获得超8个赞

我会尝试向适配器发送一个列表以显示它。我会观察适配器外部的数据,因为观察数据而不是显示数据不是适配器的责任。


查看完整回答
反对 回复 2021-08-19
?
湖上湖

TA贡献2003条经验 获得超2个赞

你可以这样做:


视图模型:


class MyViewModel : ViewModel() {

    private val items = MutableLiveData<List<String>>()


    init {

        obtainList()

    }


    fun obtainList() { // obtain list from repository

        items.value = listOf("item1", "item2", "item3", "item4")

    }


    fun getItems(): LiveData<List<String>> {

        return items

    }

}

您的片段(或活动):


public class ContentFragment extends Fragment {

    private MyViewModel viewModel;

    private RecyclerView recyclerView;

    private MyAdapter adapter;

    

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        viewModel = new ViewModelProvider(this).get(MyViewModel.class);

    }


    @Override

    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, 

            Bundle savedInstanceState) {

        View root = inflater.inflate(R.layout.fragment_main, container, false);

        recyclerView = root.findViewById(R.id.recycler_view);

        recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 4));

       

        // add observer 

        viewModel.getItems().observe(this, items -> {

            adapter = new MyAdapter(items); // add items to adapter

            recyclerView.setAdapter(adapter);

        });


        return root;

    }

适配器:


class MyAdapter(val list: List<String>) : RecyclerView.Adapter<MyAdapter.TextViewHolder {

    ...

    override fun onBindViewHolder(holder: TextViewHolder, position: Int) {

        holder.textView.text = list[position] // assign titles from the list.

        ...

    }

}

可以使用任何自定义对象代替 String 对象。


查看完整回答
反对 回复 2021-08-19
  • 3 回答
  • 0 关注
  • 633 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信