简体   繁体   English

如何修复,数据无法在回收站视图中显示,API

[英]how to fix, data cant show in recycler view, API

why my data cant show, the error in logcat is "No adapter attached; skipping layout" and "the mapper function return null", 为什么我的数据无法显示,logcat中的错误是“未连接适配器;跳过布局”和“映射器函数返回null”,

this my viewModel i get my api in here Model.java 这是我的viewModel我在这里Model.java中获得我的api

public class Model extends ViewModel {

    private static final String API_KEY = "my-api";

    private MutableLiveData<ArrayList<MoviesItems>> listMovies = new MutableLiveData<>();

    void setMovies(){
        AsyncHttpClient client = new AsyncHttpClient();
        final ArrayList<MoviesItems> listItems = new ArrayList<>();
        String url = "https://api.themoviedb.org/3/discover/movie?api_key=" + API_KEY + "&language=en-US";

        client.get(url, new AsyncHttpResponseHandler() {
            @Override
            public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {

                try {
                    String result = new String(responseBody);
                    JSONObject object = new JSONObject(result);
                    JSONArray list = object.getJSONArray("results");

                    for (int i = 0;1 < list.length(); i++){

                        JSONObject movies = list.getJSONObject(i);
                        MoviesItems moviesItems = new MoviesItems(movies);
                        listItems.add(moviesItems);

                    }
                    listMovies.getValue();
                }catch (Exception e){
                    Log.d("Exception", e.getMessage());
                }
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
                Log.d("onFailure", error.getMessage());
            }
        });
    }

    public LiveData<ArrayList<MoviesItems>>  getMovies(){
        return listMovies;
    }
}

and this my fragment i think my error in here MoviesFragment.java 这是我的片段,我认为我在这里的错误MoviesFragment.java

     View rootView = inflater.inflate(R.layout.fragment_movies, container, false);

        viewModel = ViewModelProviders.of(this).get(Model.class);
        viewModel.getMovies().observe(this, getMovie);

        //pb = rootView.findViewById(R.id.pb);

        moviesAdapter = new MoviesAdapter(getActivity());
        moviesAdapter.notifyDataSetChanged();

        rv_grid_movies = rootView.findViewById(R.id.rv_grid_movies);
        RecyclerView.LayoutManager manager = new GridLayoutManager(getActivity(), 2);
        rv_grid_movies.setLayoutManager(manager);
        rv_grid_movies.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(3), true));
        rv_grid_movies.setItemAnimator(new DefaultItemAnimator());
        rv_grid_movies.setAdapter(moviesAdapter);
        rv_grid_movies.setHasFixedSize(true);


        return rootView;
    }

    private Observer<ArrayList<MoviesItems>> getMovie = new Observer<ArrayList<MoviesItems>>() {
        @Override
        public void onChanged(@Nullable ArrayList<MoviesItems> moviesItems) {
            if (moviesItems != null){
                moviesAdapter.setData(moviesItems);
                //loadData(false);
            }
        }
    };

this my modelitems this place i get jsonObject MoviesItems.java 这是我的modelitems这个地方,我得到jsonObject MoviesItems.java

 public MoviesItems(JSONObject object){

        try {

            //JSONArray array = object.getJSONArray("results");
            int id = object.getInt("id");
            String title = object.getString("title");
            String overview = object.getString("overview");
            String poster_path = object.getString("poster_path");
            String release_date = object.getString("release_date");

            this.id = id;
            this.title = title;
            this.overview = overview;
            this.poster_path = poster_path;
            this.release_date = release_date;

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

    }

and this my adapter MoviesAdapter.java 这是我的适配器MoviesAdapter.java

public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.MoviesViewHolder> {

    private ArrayList<MoviesItems> mItems;
    private Context context;

    public MoviesAdapter(Context context){
        this.context = context;
    }

    public void setData(ArrayList<MoviesItems> mItems) {
        mItems.clear();
        mItems.addAll(mItems);
        notifyDataSetChanged();
    }

    public void addItems(final MoviesItems moviesItems){
        mItems.add(moviesItems);
        notifyDataSetChanged();
    }

    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    @Override
    public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);
    }

    private void clearData(){
        mItems.clear();
    }

    @NonNull
    @Override
    public MoviesViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.grid_movies, viewGroup, false);
        final MoviesViewHolder holder = new MoviesViewHolder(view);

        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull MoviesViewHolder moviesViewHolder, int i) {
        moviesViewHolder.bind(mItems.get(i));
    }

    @Override
    public int getItemCount() {
        return (mItems != null) ? mItems.size(): 0;
    }

    public class MoviesViewHolder extends RecyclerView.ViewHolder {

        TextView txt_title_movies, txt_date_movies, txt_description_movies;
        ImageView img_movies;
        String url = "https://image.tmdb.org/t/p/original";

        public MoviesViewHolder(@NonNull View itemView) {
            super(itemView);
            txt_title_movies = itemView.findViewById(R.id.txt_titlemovie);
            txt_date_movies = itemView.findViewById(R.id.txt_datemovie);
            txt_description_movies = itemView.findViewById(R.id.txt_descriptionmovie);
            img_movies = itemView.findViewById(R.id.img_movie);
        }


        public void bind(MoviesItems moviesItems) {
            txt_title_movies.setText(moviesItems.getTitle());
            txt_date_movies.setText(moviesItems.getRelease_date());
            txt_description_movies.setText(moviesItems.getOverview());
            Glide.with(context)
                    .load(url+moviesItems.getPoster_path())
                    .into(img_movies);
        }
    }
}

and this json i want get 我想要的这个json

{
  "page": 1,
  "total_results": 432039,
  "total_pages": 21602,
  "results": [
    {
      "vote_count": 672,
      "id": 384018,
      "video": false,
      "vote_average": 6.5,
      "title": "Fast & Furious Presents: Hobbs & Shaw",
      "popularity": 317.725,
      "poster_path": "/keym7MPn1icW1wWfzMnW3HeuzWU.jpg",
      "original_language": "en",
      "original_title": "Fast & Furious Presents: Hobbs & Shaw",
      "genre_ids": [
        28
      ],
      "backdrop_path": "/hpgda6P9GutvdkDX5MUJ92QG9aj.jpg",
      "adult": false,
      "overview": "A spinoff of The Fate of the Furious, focusing on Johnson's US Diplomatic Security Agent Luke Hobbs forming an unlikely alliance with Statham's Deckard Shaw.",
      "release_date": "2019-08-01"
    },

and this my error 这是我的错误

 java.lang.NullPointerException: The mapper function returned a null value.
        at io.reactivex.d.b.b.a(ObjectHelper.java:39)
        at io.reactivex.d.e.b.g$a.onNext(ObservableMap.java:59)
        at io.reactivex.d.e.b.i$a.run(ObservableScalarXMap.java:248)
        at io.reactivex.d.e.b.f.b(ObservableJust.java:35)
        at io.reactivex.h.a(Observable.java:11442)
        at io.reactivex.d.e.b.g.b(ObservableMap.java:33)
        at io.reactivex.h.a(Observable.java:11442)
        at io.reactivex.d.e.b.l$b.run(ObservableSubscribeOn.java:96)
        at io.reactivex.a.b.b$b.run(HandlerScheduler.java:109)
        at android.os.Handler.handleCallback(Handler.java:754)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:165)
        at android.app.ActivityThread.main(ActivityThread.java:6375)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
  • Screen Image 屏幕图像

在此处输入图片说明

In MoviesFragment.java inside observer of ArrayList<MoviesItems> onChanged() method call moviesAdapter.notifyDataSetChanged(); MoviesFragment.java内的观察者ArrayList<MoviesItems>调用onChanged()方法调用moviesAdapter.notifyDataSetChanged(); after the moviesAdapter.setData(moviesItems); moviesAdapter.setData(moviesItems);

On response of your API, you aren't setting up newly received value in LiveData variable. 根据API的响应,您不会在LiveData变量中设置新接收的值。

So make below changes and your code will work. 因此,请进行以下更改,您的代码将起作用。

void setMovies(){
    AsyncHttpClient client = new AsyncHttpClient();
    final ArrayList<MoviesItems> listItems = new ArrayList<>();
    String url = "https://api.themoviedb.org/3/discover/movie?api_key=" + API_KEY + "&language=en-US";

    client.get(url, new AsyncHttpResponseHandler() {
        @Override
        public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {

            try {
                String result = new String(responseBody);
                JSONObject object = new JSONObject(result);
                JSONArray list = object.getJSONArray("results");

                for (int i = 0;1 < list.length(); i++){

                    JSONObject movies = list.getJSONObject(i);
                    MoviesItems moviesItems = new MoviesItems(movies);
                    listItems.add(moviesItems);

                }

               // Replace below line.
               // listMovies.getValue();
               // With
                listMovies.setValue(listItems);
            }catch (Exception e){
                Log.d("Exception", e.getMessage());
            }
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
            Log.d("onFailure", error.getMessage());
        }
    });
} 

UPDATE 2: 更新2:

Change position of code as below in fragment. 如下更改片段中代码的位置。

    viewModel = ViewModelProviders.of(this).get(Model.class);
    //pb = rootView.findViewById(R.id.pb);

    moviesAdapter = new MoviesAdapter(getActivity());
    moviesAdapter.notifyDataSetChanged();

    rv_grid_movies = rootView.findViewById(R.id.rv_grid_movies);
    RecyclerView.LayoutManager manager = new GridLayoutManager(getActivity(), 2);
    rv_grid_movies.setLayoutManager(manager);
    rv_grid_movies.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(3), true));
    rv_grid_movies.setItemAnimator(new DefaultItemAnimator());
    rv_grid_movies.setAdapter(moviesAdapter);
    rv_grid_movies.setHasFixedSize(true);

    // Add observer here, after initialising adapter and recyclerview.
    viewModel.getMovies().observe(this, getMovie);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM