Как передать данные из действия или фрагмента в viewmodel? - PullRequest
2 голосов
/ 28 марта 2020

Я создаю проект, в котором я использую themoviedb API для получения данных. Для этого я использую архитектуру MVVM. Из MovieListFragment я хочу передать категорию, такую ​​как популярный, top_rated, в MovieViewModel для соответствующей фильтрации фильмов, но там я получаю нулевое значение.

Вот класс MovieListFragment: -

public class MovieListFragment extends Fragment {

    private MovieViewModel movieViewModel;
    private static final String BASE_URL = "https://api.themoviedb.org";
    private static final String API_KEY = "API_KEY";
    private String category;

    private GridView gridView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_movie_list, container, false);
        gridView = rootView.findViewById(R.id.images_grid_view);

        movieViewModel = ViewModelProviders.of(this).get(MovieViewModel.class);
        movieViewModel.setCategory(category);  // from here i am passing value
        movieViewModel.getMoviesRepository().observe(getActivity(), new Observer<MovieResults>() {  // error line no :- 76
                @Override
                public void onChanged(MovieResults movieResults) {
                    final List<MovieResults.ResultsBean> listOfMovies = movieResults.getResults();  // error line no :- 79

                    MovieListAdapter mAdapter = new MovieListAdapter(getContext(), listOfMovies);
                    gridView.setAdapter(mAdapter);
                    gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                        @Override
                        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                            mCallback.onImageSelected(position, listOfMovies);
                        }
                    });
                }
            });
        return rootView;
    }

    public void setCategory(String category) {
        this.category = category;
    }
}

Вот класс MovieViewModel: -

public class MovieViewModel extends AndroidViewModel {
    private String category;
    private static final String API_KEY = "api_key";
    private MovieRepository repository;
    private MutableLiveData<MovieResults> listOfMovies;

    public MovieViewModel(@NonNull Application application) {
        super(application);
        Log.d("MovieViewModel", category); // but here i am getting null value
        listOfMovies = repository.getListOfMovies(category, API_KEY);
    }

    public MutableLiveData<MovieResults> getMoviesRepository() {
        return listOfMovies;
    }

    public void setCategory(String category) {
        this.category = category;
    }
}

Я получаю такую ​​ошибку: -

java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.mountblue.moviesapp.entity.MovieResults.getResults()' on a null object reference
        at com.mountblue.moviesapp.fragment.MovieListFragment$2.onChanged(MovieListFragment.java:79)
        at com.mountblue.moviesapp.fragment.MovieListFragment$2.onChanged(MovieListFragment.java:76)

Ответы [ 3 ]

0 голосов
/ 28 марта 2020

Поскольку Категория читается конструктором MovieViewModel перед установщиком, она всегда равна нулю.

А как насчет категории в качестве аргументов метода?

public class MovieViewModel extends AndroidViewModel {

    private static final String API_KEY = "api_key";
    private MovieRepository repository;
    private MutableLiveData<MovieResults> listOfMovies = new MutableLiveData<MovieResults>();

    public MovieViewModel(@NonNull Application application) {
        super(application);
    }

    public MutableLiveData<MovieResults> getMoviesRepository(category) {
        loadData(category);
        return listOfMovies;
    }

    private void loadData(category) {
        // Do an asynchronous operation to fetch MovieResults.
        repository.getListOfMovies(category, API_KEY);

        ...
        // Receive asynchronous result in callback

        // Post the result after getting the asynchronous result.
        listOfMovies.postValue(response)
    }
}

Для более подробной реализации, нужен класс хранилища.

Документы: https://developer.android.com/topic/libraries/architecture/viewmodel

0 голосов
/ 13 апреля 2020

Вам необходимо создать фабрику моделей представления для передачи данных в модель представления из действия или фрагмента. Вы можете сослаться на это здесь .

0 голосов
/ 28 марта 2020

Если вы получаете null значение для строки category в строке movieViewModel.setCategory(category);, это означает, что поле category из MovieListFragment равно нулю.

Попробуйте проверить, вызвали ли вы setCategory(String category) метод fragment.

Если это не так, пожалуйста, уточните ошибку. Например, на какой линии это происходит et c.

...