如何将 ViewModel 与 Repository 连接起来,以便将数据传播到 View(MVVM、Livedata) [英] How to connect ViewModel with Repository so that data is propagated to the View (MVVM, Livedata)

查看:42
本文介绍了如何将 ViewModel 与 Repository 连接起来,以便将数据传播到 View(MVVM、Livedata)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我添加了一些代码以使我的问题更清楚.

I've added some code to make my question more clear.

改造界面:

public interface JsonPlaceHolderAPI {
    public static final String BASE_URL = "https://jsonplaceholder.typicode.com/";

    @GET("todos/{number}")
    Call<ResponseBody> getJsonResponse(@Path("number") String number);
}

存储库:--> fetchResponse() 将 Viewmodel 的 MutableLiveData 作为参数,并使用它更新其值,然后触发 View 更改其 UI.

The repository: --> fetchResponse() takes Viewmodel's MutableLiveData as parameter and uses it to update its value and then trigger View to change its UI.

public class Repository {

    private final JsonPlaceHolderAPI api;

    public Repository() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .build();
        api = retrofit.create(JsonPlaceHolderAPI.class);
    }


    public void fetchResponse(String number, final MutableLiveData<CharSequence> mld){
        final MutableLiveData<CharSequence> ml = new MutableLiveData<>();

        api.getJsonResponse(number).enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    mld.setValue(response.body().string());

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {}
        });
    }
}

视图模型:

public class MainActivityViewModel extends AndroidViewModel {
    MutableLiveData<CharSequence> response = new MutableLiveData<>();
    Repository repository;

    public MainActivityViewModel(@NonNull Application application) {
        super(application);
        repository = new Repository();
    }


    public void fetchData(String number) {
        response.setValue("Loading data");
        repository.fetchResponse(number, response);
    }

    public LiveData<? extends CharSequence> getLiveData() {
        return response;
    }
}

视图:

...
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewModel = ViewModelProviders.of(this).get(MainActivityViewModel.class);
        initViews();

        viewModel.getLiveData().observe(this, new Observer<CharSequence>() {
            @Override
            public void onChanged(CharSequence charSequence) {
                if (charSequence != null) {
                    txt.setText(charSequence);
                }
            }
        });


    }
    ...

我不确定是否应该将 MutableLiveData 从 viewModel 传递到存储库.

I am not sure if I should pass the MutableLiveData from the viewModel to the Repository.

是否有任何推荐的方法可以让 viewModel 知道数据已准备好从 Repository 发布??

Is there any recommended way to let viewModel know that data is ready to be published from Repository??

我已经阅读了很多问题和文章,但我仍然不明白.如果有人向我解释实现它的好方法,我会很高兴!

I have read a lot of questions and articles and still I don't get it. I would love if somebody explain to me a nice way to achieve it!

推荐答案

Api

public interface TodoApi {
    @GET("todos/")
    Call<List<Todo>> getTodos();

    @GET("todos/{id}")
    Call<Todo> getTodo(@Path("id") long id);
}

存储库

    public class TodoRepository {
    private static final String TAG = "TodoRepository";
    private static final TodoRepository ourInstance = new TodoRepository();
    private TodoApi api;

    private MutableLiveData<List<Todo>> todoListLiveData = new MutableLiveData<>();
    private MutableLiveData<Todo> todoLiveData = new MutableLiveData<>();

    public static TodoRepository getInstance() {
        return ourInstance;
    }

    private TodoRepository() {
        api = ApiBuilder.create(TodoApi.class);
    }

    public LiveData<List<Todo>> getTodos() {
        api.getTodos().enqueue(new Callback<List<Todo>>() {
            @Override
            public void onResponse(@NonNull Call<List<Todo>> call, @NonNull Response<List<Todo>> response) {
                todoListLiveData.setValue(response.body());
            }

            @Override
            public void onFailure(@NonNull Call<List<Todo>> call, @NonNull Throwable t) {
                Log.d(TAG, "onFailure: failed to fetch todo list from server");
            }
        });
        return todoListLiveData;
    }

    public LiveData<Todo> getTodo(long id) {
        api.getTodo(id).enqueue(new Callback<Todo>() {
            @Override
            public void onResponse(@NonNull Call<Todo> call, @NonNull Response<Todo> response) {
                todoLiveData.setValue(response.body());
            }

            @Override
            public void onFailure(@NonNull Call<Todo> call, @NonNull Throwable t) {
                Log.d(TAG, "onFailure: failed to get todo");
            }
        });
        return todoLiveData;
    }
}

视图模型

    public class MainActivityViewModel extends ViewModel {
    private static final String TAG = "MainActivityViewModel";

    private TodoRepository repository = TodoRepository.getInstance();

    private MutableLiveData<Boolean> isLoading = new MutableLiveData<>();
    private LiveData<List<Todo>> todoLiveData;

    public MainActivityViewModel() {
        super();
        isLoading.setValue(true);
        todoLiveData = repository.getTodos();
    }

    @Override
    protected void onCleared() {
        super.onCleared();
    }

    public MutableLiveData<Boolean> getIsLoading() {
        return isLoading;
    }

    public LiveData<List<Todo>> getTodoLiveData() {
        return todoLiveData;
    }
}

查看

@Override

View

@Override

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    todoListRecyclerView = findViewById(R.id.todo_recycler_view);
    loadingIndicator = findViewById(R.id.todo_loading_indicator);
    mViewModel = ViewModelProviders.of(this).get(MainActivityViewModel.class);
    getSupportActionBar().setTitle("Todos");

    mViewModel.getIsLoading().observe(this, new Observer<Boolean>() {
        @Override
        public void onChanged(Boolean isLoading) {
            if (isLoading) loadingIndicator.setVisibility(View.VISIBLE);
            else loadingIndicator.setVisibility(View.GONE);
        }
    });

    mViewModel.getTodoLiveData().observe(this, new Observer<List<Todo>>() {
        @Override
        public void onChanged(List<Todo> todos) {
            mViewModel.getIsLoading().postValue(false);
            initRecyclerView(todos);
        }
    });
}

完整样本

https://github.com/AnvarNazar/RetrofitTypicodeApiExample

这篇关于如何将 ViewModel 与 Repository 连接起来,以便将数据传播到 View(MVVM、Livedata)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆