How to pass Retrofit response to RecyclerViewAdapter in Android Google Books API

前提是你 提交于 2019-12-11 17:34:03

问题


I've been using Retrofit2.0 (just learned how to use it) to retrieve Google Books API info, I have finally succeeded. But now I don't know know how to pass it to RecyclerView since now my models have gotten revised and now deal with nested models (I think that is the correct term) compared to what I had before to (old Stack Overflow question here).

Currently, I'm getting this error:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android_myneighborsbookshelf, PID: 8806
    java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.List.get(int)' on a null object reference
        at com.example.android_myneighborsbookshelf.adapters.SearchViewRecyclerViewAdapter.onBindViewHolder(SearchViewRecyclerViewAdapter.java:90)
        at com.example.android_myneighborsbookshelf.adapters.SearchViewRecyclerViewAdapter.onBindViewHolder(SearchViewRecyclerViewAdapter.java:27)
        at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7033)
        at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7075)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5991)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6258)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6097)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6093)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
        at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4115)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3832)
        at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4385)
        at android.view.View.layout(View.java:20672)
        at android.view.ViewGroup.layout(ViewGroup.java:6194)
        at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1083)
        at android.view.View.layout(View.java:20672)
        at android.view.ViewGroup.layout(ViewGroup.java:6194)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1812)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1656)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1565)
        at android.view.View.layout(View.java:20672)
        at android.view.ViewGroup.layout(ViewGroup.java:6194)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:20672)
        at android.view.ViewGroup.layout(ViewGroup.java:6194)
        at androidx.appcompat.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:446)
        at android.view.View.layout(View.java:20672)
        at android.view.ViewGroup.layout(ViewGroup.java:6194)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:20672)
        at android.view.ViewGroup.layout(ViewGroup.java:6194)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1812)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1656)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1565)
        at android.view.View.layout(View.java:20672)
        at android.view.ViewGroup.layout(ViewGroup.java:6194)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at com.android.internal.policy.DecorView.onLayout(DecorView.java:753)
        at android.view.View.layout(View.java:20672)
        at android.view.ViewGroup.layout(ViewGroup.java:6194)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2792)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2319)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1460)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7183)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949)
        at android.view.Choreographer.doCallbacks(Choreographer.java:761)
        at android.view.Choreographer.doFrame(Choreographer.java:696)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Here is my model Book2.java

public class Book2 {

//    @SerializedName("title")
    private String mTitle;


    @SerializedName("items")
    private List<Items> items;

    public Book2() {
        // no arg constructor needed
    }

    public Book2(Items items) { // <-- not too sure if this is correct
        this.mTitle = mTitle; // <-- not too sure if this is correct
    }

    public List<Items> getItems() {
        return items;
    }

    public void setItems(List<Items> items) {
        this.items = items;
    }


    public class Items {

        @SerializedName("volumeInfo")
        private VolumeInfo volumeInfo;


        public VolumeInfo getVolumeInfo() {
            return volumeInfo;
        }

        public void setVolumeInfo(VolumeInfo volumeInfo) {
            this.volumeInfo = volumeInfo;
        }
    }


    public static class VolumeInfo extends Book2 {

        @SerializedName("title")
        private String mTitle;

        @SerializedName("authors")
        private ArrayList<String> mAuthors;

        @SerializedName("publisher")
        private String mPublisher;

        @SerializedName("publishedDate")
        private String mPublishedDate;

        @SerializedName("description")
        private String mDescription;

//        @SerializedName("industryIdentifiers")
//        private ArrayList<String> mIndustryIdentifiers;

        @SerializedName("categories")
        private ArrayList<String> mCategories;

        @SerializedName("imageLinks")
        private ImageLinks mImageLinks;

        public VolumeInfo(String title) {
            this.mTitle = title;
        }


        public String getmTitle() {
            return mTitle;
        }

        public void setmTitle(String mTitle) {
            this.mTitle = mTitle;
        }

        public ArrayList<String> getmAuthors() {
            return mAuthors;
        }

        public void setmAuthors(ArrayList<String> mAuthors) {
            this.mAuthors = mAuthors;
        }

        public String getmPublisher() {
            return mPublisher;
        }

        public void setmPublisher(String mPublisher) {
            this.mPublisher = mPublisher;
        }

        public String getmPublishedDate() {
            return mPublishedDate;
        }

        public void setmPublishedDate(String mPublishedDate) {
            this.mPublishedDate = mPublishedDate;
        }

        public String getmDescription() {
            return mDescription;
        }

        public void setmDescription(String mDescription) {
            this.mDescription = mDescription;
        }

/*
        public ArrayList<String> getmIndustryIdentifiers() {
            return mIndustryIdentifiers;
        }

        public void setmIndustryIdentifiers(ArrayList<String> mIndustryIdentifiers) {
            this.mIndustryIdentifiers = mIndustryIdentifiers;
        }

 */

        public ArrayList<String> getmCategories() {
            return mCategories;
        }

        public void setmCategories(ArrayList<String> mCategories) {
            this.mCategories = mCategories;
        }


        public ImageLinks getmImageLinks() {
            return mImageLinks;
        }

        public void setmImageLinks(ImageLinks mImageLinks) {
            this.mImageLinks = mImageLinks;
        }
    }

    public class ImageLinks {
        @SerializedName("thumbnail")
        private String mThumbnail;

        public String getmThumbnail() {
            return mThumbnail;
        }

        public void setmThumbnail(String mThumbnail) {
            this.mThumbnail = mThumbnail;
        }
    }
}

MainActivity2.java

public class MainActivity2 extends AppCompatActivity {


    private RecyclerView mRecyclerView;
    private ArrayList<Book2> mBooks;
//    private ArrayList<Book2> mBooks;
    private SearchViewRecyclerViewAdapter mSearchViewRecyclerViewAdapter;
    private RequestQueue mRequestQueue;

    private static  final  String BASE_URL2="https://www.googleapis.com/books/v1/";
//    private static  final  String BASE_URL_TYPICODE="https://jsonplaceholder.typicode.com/";
//    private static  final  String BASE_URL="https://www.googleapis.com/books/v1/volumes?q=";



    private EditText search_edit_text;
    Button search_button;
    ProgressBar loading_indicator;
    private TextView error_message;

//    private static final String LOG_TAG = MainActivity2.class.getSimpleName();
    private static final String TAG = "MainActivity2";



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_book_main2);

        search_edit_text=findViewById(R.id.search_box);
        search_button= findViewById(R.id.search_buttton);
        loading_indicator=findViewById(R.id.loading_indicator);
        error_message= findViewById(R.id.message_display);

        mRecyclerView = findViewById(R.id.recycler_view);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mBooks = new ArrayList<>();
        mRequestQueue = Volley.newRequestQueue(this);


        search_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mBooks.clear();
                search();
            }
        });



    }

    private void parseJson3(String key){
        // source = https://medium.com/@wkrzywiec/making-use-of-open-rest-api-with-retrofit-dac6094f0522
        //  youtube tutorial here: https://www.youtube.com/watch?v=4JGvDUlfk7Y


        JsonPlaceHolderApi serviceEndPoint = ServiceGenerator.createService(JsonPlaceHolderApi.class);

        Call<Book2> call = serviceEndPoint.getQueryItems2("volumes?q=enders+game");


        call.enqueue(new Callback<Book2>() {
            @Override
            public void onResponse(Call<Book2> call, retrofit2.Response<Book2> response) {

                if (response.isSuccessful()) {

                    String title ="";
//                List<String> author = "";
                    String author =" ";
                    String publishedDate = "Not Available";
                    String publisher = "Not Available";
                    String description = "No Description";
                    int pageCount = 1000;
                    String category = "No categories Available ";
                    String buy ="";
//                String volumeInfoString = "";
                    String bookJSONString = null;
                    String thumbnail = "";
                    String previewLink = "";
                    String price = "";
                    String url = "";



//                for (int i = 0; i < grantResults.length; i++) {
                    for (int i = 0; i < response.body().getItems().size(); i++) {


                        Log.d(TAG, "onResponse: success getmTitle: " + response.body().getItems().get(i).getVolumeInfo().getmTitle());
                        title = response.body().getItems().get(i).getVolumeInfo().getmTitle();
                        Log.d(TAG, "onResponse: success getmAuthors: " + response.body().getItems().get(i).getVolumeInfo().getmAuthors());
//                    author = response.body().getItems().get(i).getVolumeInfo().getmAuthors();
                        Log.d(TAG, "onResponse: success getmCategories: " + response.body().getItems().get(i).getVolumeInfo().getmCategories());
//                    category = response.body().getItems().get(i).getVolumeInfo().getmCategories();
                        Log.d(TAG, "onResponse: success getmDescription: " + response.body().getItems().get(i).getVolumeInfo().getmDescription());
                        description = response.body().getItems().get(i).getVolumeInfo().getmDescription();
                        Log.d(TAG, "onResponse: success getmPublisher: " + response.body().getItems().get(i).getVolumeInfo().getmPublisher());
                        publisher = response.body().getItems().get(i).getVolumeInfo().getmPublisher();
                        Log.d(TAG, "onResponse: success getmImageLinks: " + response.body().getItems().get(i).getVolumeInfo().getmImageLinks().getmThumbnail());
                        thumbnail = response.body().getItems().get(i).getVolumeInfo().getmImageLinks().getmThumbnail();
                    }

                    Log.d(TAG, "onResponse: title = " + title);


//                    mBooks.add(new Book2(title, author, publishedDate, description ,category
//                            , thumbnail, buy, previewLink, price, pageCount, url));

                    mBooks.add(new Book2.VolumeInfo(title));


                    mSearchViewRecyclerViewAdapter = new SearchViewRecyclerViewAdapter(MainActivity2.this , mBooks);
                    mRecyclerView.setAdapter(mSearchViewRecyclerViewAdapter);

                } else {

                    Log.d(TAG, "onResponse: call in MainActivity2 was not successful");
                }
            }

            @Override
            public void onFailure(Call<Book2> call, Throwable t) {

                Log.d(TAG, "onFailure: didnt work" + t);
            }
        });
    }
private boolean Read_network_state(Context context)
    {    boolean is_connected;
        ConnectivityManager cm =(ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
        NetworkInfo info = cm.getActiveNetworkInfo();
        is_connected=info!=null&&info.isConnectedOrConnecting();
        return is_connected;
    }


    private void search()
    {
        String search_query = search_edit_text.getText().toString();

        boolean is_connected = Read_network_state(this);
        if(!is_connected)
        {
            error_message.setText(R.string.Failed_to_Load_data);
            mRecyclerView.setVisibility(View.INVISIBLE);
            error_message.setVisibility(View.VISIBLE);
            return;
        }

        //  Log.d("QUERY",search_query);


        if(search_query.equals(""))
        {
            Toast.makeText(this,"Please enter your query",Toast.LENGTH_SHORT).show();
            return;
        }
        String final_query=search_query.replace(" ","+");

        Uri uri=Uri.parse(BASE_URL2+final_query);
//        Uri uri=Uri.parse(BASE_URL+final_query);
        Uri.Builder buider = uri.buildUpon();

        parseJson3(buider.toString());
    }
}

SearchViewRecyclerViewAdapter.java

public class SearchViewRecyclerViewAdapter extends RecyclerView.Adapter<SearchViewRecyclerViewAdapter.MyViewHolder> {

    private Context mContext;
    private List<Book2> mData;
    private RequestOptions options;
    private static final String LOG_TAG = SearchViewRecyclerViewAdapter.class.getSimpleName();


    public SearchViewRecyclerViewAdapter(Context mContext, List<Book2> mData) {
        this.mContext = mContext;
        this.mData = mData;

        //Request option for Glide
        options = new RequestOptions().centerCrop().placeholder(R.drawable.loading_shape).error(R.drawable.loading_shape);
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {

        View view;
        LayoutInflater inflater = LayoutInflater.from(mContext);
        view = inflater.inflate(R.layout.book_raw_item2 , parent , false);
        final MyViewHolder viewHolder =  new MyViewHolder(view);
        viewHolder.container.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {  
                Intent i = new Intent(mContext , BookProfileActivity2.class);
                int pos = viewHolder.getAdapterPosition();
//                i.putExtra("book_title" ,mData.get(pos).getTitle());
                i.putExtra("book_title" ,mData.get(pos).getItems().get(pos).getVolumeInfo().getmTitle());
//                i.putExtra("book_author" ,mData.get(pos).getAuthors());
                i.putExtra("book_title" ,mData.get(pos).getItems().get(pos).getVolumeInfo().getmAuthors());
//                i.putExtra("book_desc" ,mData.get(pos).getDescription());
                i.putExtra("book_title" ,mData.get(pos).getItems().get(pos).getVolumeInfo().getmDescription());
//                i.putExtra("book_categories" ,mData.get(pos).getCategories());
                i.putExtra("book_title" ,mData.get(pos).getItems().get(pos).getVolumeInfo().getmCategories());
//                i.putExtra("book_publish_date" ,mData.get(pos).getPublishedDate());
                i.putExtra("book_title" ,mData.get(pos).getItems().get(pos).getVolumeInfo().getmPublishedDate());
//                i.putExtra("book_info" ,mData.get(pos).getmUrl());
//                i.putExtra("book_buy" ,mData.get(pos).getBuy());
//                i.putExtra("book_preview" ,mData.get(pos).getPerview());
//                i.putExtra("book_thumbnail" ,mData.get(pos).getThumbnail());
                i.putExtra("book_title" ,mData.get(pos).getItems().get(pos).getVolumeInfo().getmImageLinks().getmThumbnail());
//                i.putExtra("volumeInfo" ,mData.get(pos).getVolumeInfo());

//                Log.d(LOG_TAG, "onClick: " + mData.get(pos).getVolumeInfo());


                mContext.startActivity(i);
            }
        });
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int i) {

        Book2 book = mData.get(i); // <-- Tried this. 
        Book2.VolumeInfo book = mData.get(i).getItems().get(i).getVolumeInfo(); // <-- Tried this
        holder.tvTitle.setText(book.getItems().get(i).getVolumeInfo().getmTitle()); // <-- Error occurs here  

    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

    public static class MyViewHolder extends RecyclerView.ViewHolder{

        ImageView ivThumbnail;
        TextView tvTitle, tvCategory, tvPrice, tvAuthor;
        LinearLayout container;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);

            ivThumbnail = itemView.findViewById(R.id.thumbnail);
            tvTitle = itemView.findViewById(R.id.title);
            tvAuthor = itemView.findViewById(R.id.author);
            tvCategory = itemView.findViewById(R.id.category);
            tvPrice = itemView.findViewById(R.id.price);
            container = itemView.findViewById(R.id.container);


        }
    }
}

来源:https://stackoverflow.com/questions/58406028/how-to-pass-retrofit-response-to-recyclerviewadapter-in-android-google-books-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!