如何将数据从 Activity 或 Fragment 传递到 ViewModel?

问题描述 投票:0回答:3

我正在创建一个项目,在其中使用moviedb api 来获取数据。为此,我使用 MVVM 架构。从 MovieListFragment 中,我想将流行、top_erated 等类别传递给 MovieViewModel 以相应地过滤电影,但我得到的是 null 值。

这是 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)
java android android-studio mvvm android-mvvm
3个回答
0
投票

如果您在第

null
行中获取字符串
category
movieViewModel.setCategory(category);
值,则意味着
category
的字段
MovieListFragment
为空。

尝试检查您是否在

setCategory(String category)
上调用了
fragment
方法。

如果不是这种情况,请详细说明错误。例如。它发生在哪一行等等。


0
投票

由于 Category 是由 MovieViewModel 的构造函数在 setter 之前读取的,因此它始终为 null。

类别作为方法参数怎么样?

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
投票

在MovieListFragment类中:

首先删除这一行:

movieViewModel.setCategory(category);

并在此处传递“类别”:

movieViewModel.getMoviesRepository(category)
就像下面的代码:

movieViewModel.getMoviesRepository(category).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);
                    }
                });
            }
        });

在MovieViewModel类中:

将此行移入 getMoviesRepository(String Category)

listOfMovies = repository.getListOfMovies(category, API_KEY);

只需从

setCategory()
类中删除类别变量和
MovieViewModel
方法,如下所示:

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

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

    public MutableLiveData<MovieResults> getMoviesRepository(String category) {
        Log.d("MovieViewModel", category); // but here i am getting null value
        listOfMovies = repository.getListOfMovies(category, API_KEY);
        return listOfMovies;
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.