具有ViewModel和实时数据的RecylcerView适配器

时间:2018-08-29 14:54:28

标签: android mvvm android-recyclerview recycler-adapter android-jetpack

我开始使用android jetpack arch组件,并且遇到了一些混乱。另外请注意,数据绑定不是一种选择。

我有一个带有RecylcerView的活动。我有一个如下所示的ViewModel

browser.cookies.getAll

尽管我在我的recyclerview中具有以下代码,但上述内容都很好。虽然在onbindviewholder中,当我尝试观察ViewModels实时数据返回的图像时,它需要一个生命周期所有者参考,而我在回收者视图中没有该参考。请帮助谢谢

public 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
 }

}

3 个答案:

答案 0 :(得分:1)

您的适配器列表类型不应为viewmodel。如果要使用不绑定的实时数据,则希望在列表更新时自动更改用户界面。

您可以这样做:

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

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

然后创建

这样的实时数据列表
MutableLiveData<List<Movie>> movieLiveData = 
    new MutableLiveData<>();

您想要的位置。

在活动中观察此列表,然后调用observe {}中的适配器setList(Movie)方法。

如果这一切都更新了,setList(Movie)方法将被触发,然后您的用户界面将被更新。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您可以执行以下操作:

ViewModel:

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对象。