Как передать ответ Retrofit на RecyclerViewAdapter в Android Google Книги API - PullRequest
0 голосов
/ 16 октября 2019

Я использовал Retrofit 2.0 (только что узнал, как его использовать), чтобы получить информацию об API Google Книг, и мне это удалось. Но теперь я не знаю, как передать его в RecyclerView, так как теперь мои модели были пересмотрены и теперь работают с вложенными моделями (я думаю, что это правильный термин) по сравнению с тем, что у меня было раньше ( старое переполнение стека)вопрос здесь ).

В настоящее время я получаю эту ошибку:

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)

Вот моя модель 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);


        }
    }
}

...