Hi I am a Beginner in android and still learning and I am making a book library app that has some features and there is a bug or a null pointer exception to be precise in the get item count in the recycler view adapter and this is the first time that something like that happened thanks.
adapter:
package com.example.newbookstoreplzwork;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import androidx.transition.TransitionManager;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
public class BookRecViewAdapter extends RecyclerView.Adapter<BookRecViewAdapter.ViewHolder> {
private static final String TAG = "BookRecViewAdapter";
ArrayList<Book> books = new ArrayList<>();
private Context mcontexet;
private String parent;
public BookRecViewAdapter(Context mcontexet , String parent) {
this.mcontexet = mcontexet;
this.parent = parent;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout .list_item_book , parent , false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
Log.d(TAG, "onBindViewHolder: Working!!!!!");
holder.txtName.setText(books.get(position).getName());
Glide.with(mcontexet).asBitmap().load(books.get(position).getImageUrl()).into(holder.imgBook);
holder.txtDescreption.setText(books.get(position).getShortDesc());
holder.txtAuthor.setText(books.get(position).getAuthor());
if (books.get(position).isExpanded()){
TransitionManager.beginDelayedTransition(holder.parent);
holder.expandedRealtiveLayout.setVisibility(View.VISIBLE);
holder.downArrow.setVisibility(View.GONE);
if (parent.equals(All_Books_Actvity.parentActvity)){
holder.delete.setVisibility(View.GONE);
}
if (parent.equals(Book.fav)){
holder.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder dialog = new AlertDialog.Builder(mcontexet);
dialog.setMessage("Are you sure You want to delete " + books.get(position).getName());
dialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Utils.getInstance(mcontexet).removeFromFav(books.get(position))) {
Toast.makeText(mcontexet, " Book removed", Toast.LENGTH_SHORT).show();
notifyDataSetChanged();
}
}
});
dialog.setNegativeButton("no", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
dialog.create().show();
}
});
}else if (parent.equals(Book.already)){
holder.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder dialog = new AlertDialog.Builder(mcontexet);
dialog.setMessage("Are you sure You want to delete " + books.get(position).getName());
dialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Utils.getInstance(mcontexet).removeLreadyRead(books.get(position))) {
Toast.makeText(mcontexet, " Book removed", Toast.LENGTH_SHORT).show();
notifyDataSetChanged();
}
}
});
dialog.setNegativeButton("no", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
dialog.create().show();
}
});
} else if (parent.equals(Book.currently)){
holder.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder dialog = new AlertDialog.Builder(mcontexet);
dialog.setMessage("Are you sure You want to delete " + books.get(position).getName());
dialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Utils.getInstance(mcontexet).removeFromCurrently(books.get(position))) {
Toast.makeText(mcontexet, " Book removed", Toast.LENGTH_SHORT).show();
notifyDataSetChanged();
}
}
});
dialog.setNegativeButton("no", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
dialog.create().show();
}
});
}else{
holder.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder dialog = new AlertDialog.Builder(mcontexet);
dialog.setMessage("Are you sure You want to delete " + books.get(position).getName());
dialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Utils.getInstance(mcontexet).removeFromWantToRead(books.get(position))){
Toast.makeText(mcontexet, "Book Removed", Toast.LENGTH_SHORT).show();
}
}
});
dialog.setNegativeButton("no", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
dialog.create().show();
}
});
}
}else{
TransitionManager.beginDelayedTransition(holder.parent);
holder.expandedRealtiveLayout.setVisibility(View.GONE);
holder.downArrow.setVisibility(View.VISIBLE);
}
holder.parent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(mcontexet , Book_Actvity.class);
intent.putExtra(Book_Actvity.BOOK_ID ,books.get(position).getId());
mcontexet.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return Utils.getInstance(mcontexet).getAllBooksArrayList().size();
}
public void setBooks(ArrayList<Book> books) {
this.books = books;
notifyDataSetChanged();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private CardView parent;
private ImageView imgBook;
private TextView txtName , txtDescreption , txtAuthor ;
private RelativeLayout expandedRealtiveLayout;
private ImageView upArrow , downArrow , delete;
public ViewHolder(@NonNull View itemView) {
super(itemView);
parent = itemView.findViewById(R.id.parent);
imgBook = itemView.findViewById(R.id.imgBook);
txtName = itemView.findViewById(R.id.txtBookName);
txtDescreption = itemView.findViewById(R.id.txtShortDesc);
expandedRealtiveLayout = itemView.findViewById(R.id.expandedRealtiveLayout);
upArrow = itemView.findViewById(R.id.btnArrowUpp);
downArrow = itemView.findViewById(R.id.btnArrowDown);
txtAuthor = itemView.findViewById(R.id.txtAuthor);
delete = itemView.findViewById(R.id.btnDelete);
downArrow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Book book = books.get(getAdapterPosition());
book.setExpanded(!book.isExpanded());
notifyItemChanged(getAdapterPosition());
}
});
upArrow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Book book = books.get(getAdapterPosition());
book.setExpanded(!book.isExpanded());
notifyItemChanged(getAdapterPosition());
}
});
}
}
}
Utils class
package com.example.newbookstoreplzwork;
import android.content.Context;
import android.content.SharedPreferences;
import android.view.inputmethod.InlineSuggestionsRequest;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
imp
ort java.util.ArrayList;
public class Utils {
private SharedPreferences sharedPreferences;
public static Utils instance;
private static final String ALL_Books = "ALLBOOKS";
private static String DB_KEY = "db";
public static final String booksIntext = "booksInText";
private static final String ALREADY_READ_BOOKS = "AlreadyReadArraylist";
private static final String FAVOURITE_BOOKS = "Favourite_Books";
private static final String CURRENTLY_READING_BOOKS = "Currently_Reading_Books";
private static final String WANT_TO_READ_BOOKS = "Want_To_Read_Books";
private static ArrayList<Book> allBooksArrayList;
Utils(Context context) {
sharedPreferences = context.getSharedPreferences(DB_KEY, Context.MODE_PRIVATE);
if (null == getAllBooksArrayList()) {
initData();
}
SharedPreferences.Editor editor = sharedPreferences.edit();
Gson gson = new Gson();
if (getCurrentlyReadingArrayList() == null) {
editor.putString(CURRENTLY_READING_BOOKS, gson.toJson(new ArrayList<Book>()));
editor.commit();
}
if (getAlreadyReadArrayList() == null) {
editor.putString(ALREADY_READ_BOOKS, gson.toJson(new ArrayList<Book>()));
editor.commit();
}
if (getWishListArrayList() == null) {
editor.putString(WANT_TO_READ_BOOKS, gson.toJson(new ArrayList<Book>()));
editor.commit();
}
if (getFavoritesArrayList() == null) {
editor.putString(FAVOURITE_BOOKS, gson.toJson(new ArrayList<Book>()));
editor.commit();
}
}
private void initData() {
ArrayList<Book> books = new ArrayList<>();
books.add(new Book(1, "wimpy kid", "karam Shadi", 134, "https://kbimages1-a.akamaihd.net/a93f1391-68be-478b-acb0-63cd7881aed8/1200/1200/False/the-getaway-diary-of-a-wimpy-kid-book-12.jpg",
"asdfasd", "jhkjhkhkjhkjghjghgfg"));
books.add(new Book(2, "majduddin Book", "majduddin", 90, "https://s3images.coroflot.com/user_files/individual_files/702459_am5ekrun22pd6wav_kbesce8q.png ", "long", "dodo"));
SharedPreferences.Editor editor = sharedPreferences.edit();
Gson gson = new Gson();
String booksInText = gson.toJson(books);
editor.putString(booksInText, booksInText);
editor.commit();
}
public static Utils getInstance(Context context) {
if (instance != null) {
return instance;
} else {
instance = new Utils(context);
return instance;
}
}
public ArrayList<Book> getCurrentlyReadingArrayList() {
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<Book>>() {
}.getType();
ArrayList<Book> books = gson.fromJson(sharedPreferences.getString(CURRENTLY_READING_BOOKS, null), type);
return books;
}
public ArrayList<Book> getAlreadyReadArrayList() {
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<Book>>() {
}.getType();
ArrayList<Book> books = gson.fromJson(sharedPreferences.getString(ALREADY_READ_BOOKS, null), type);
return books;
}
public ArrayList<Book> getWishListArrayList() {
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<Book>>() {
}.getType();
ArrayList<Book> books = gson.fromJson(sharedPreferences.getString(WANT_TO_READ_BOOKS, null), type);
return books;
}
public ArrayList<Book> getFavoritesArrayList() {
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<Book>>() {
}.getType();
ArrayList<Book> books = gson.fromJson(sharedPreferences.getString(FAVOURITE_BOOKS, null), type);
return books;
}
public ArrayList<Book> getAllBooksArrayList() {
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<Book>>() {}.getType();
ArrayList<Book> books = gson.fromJson(sharedPreferences.getString(ALL_Books, null), type);
return books;
}
public Book getBookById(int id) {
ArrayList<Book> books = getAllBooksArrayList();
if (null != books) {
for (Book b : books) {
if (b.getId() == id) {
return b;
}
}
}
return null;
}
public boolean addToAlreadyReadBooks(Book book) {
ArrayList<Book> books = getAlreadyReadArrayList();
if (null != books) {
if (books.add(book)) {
SharedPreferences.Editor editor = sharedPreferences.edit();
Gson gson = new Gson();
editor.remove(ALREADY_READ_BOOKS);
editor.putString(ALREADY_READ_BOOKS, gson.toJson(books));
editor.commit();
return true;
}
}
return false;
}
public boolean addToCurrentlyReadingBooks(Book book) {
ArrayList<Book> books = getCurrentlyReadingArrayList();
if (null != books) {
if (books.add(book)) {
SharedPreferences.Editor editor = sharedPreferences.edit();
Gson gson = new Gson();
editor.remove(CURRENTLY_READING_BOOKS);
editor.putString(CURRENTLY_READING_BOOKS, gson.toJson(books));
editor.commit();
return true;
}
}
return false;
}
public boolean addToFavourites(Book book) {
ArrayList<Book> books = getFavoritesArrayList();
if (null != books) {
if (books.add(book)) {
SharedPreferences.Editor editor = sharedPreferences.edit();
Gson gson = new Gson();
editor.remove(FAVOURITE_BOOKS);
editor.putString(FAVOURITE_BOOKS, gson.toJson(books));
editor.commit();
return true;
}
}
return false;
}
public boolean addTOWantToWantToRead(Book book) {
ArrayList<Book> books = getWishListArrayList();
if (null != books) {
if (books.add(book)) {
SharedPreferences.Editor editor = sharedPreferences.edit();
Gson gson = new Gson();
editor.remove(WANT_TO_READ_BOOKS);
editor.putString(WANT_TO_READ_BOOKS, gson.toJson(books));
editor.commit();
return true;
}
}
return false;
}
public boolean removeFromFav(Book book) {
ArrayList<Book> books = getFavoritesArrayList();
if (null != books) {
for (Book b : books) {
if (b.getId() == book.getId()) {
if (books.remove(b)) {
Gson gson = new Gson();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove(FAVOURITE_BOOKS);
editor.putString(FAVOURITE_BOOKS, gson.toJson(books));
editor.commit();
return true;
}
}
}
}
return false;
}
public boolean removeFromCurrently(Book book) {
ArrayList<Book>books = getCurrentlyReadingArrayList();
if (null!=books){
for (Book b: books){
if (b.getId() == book.getId()){
if (books.remove(b)){
Gson gson = new Gson();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove(CURRENTLY_READING_BOOKS);
editor.putString(CURRENTLY_READING_BOOKS , gson.toJson(books));
editor.commit();
return true;
}
}
}
}
return false;
}
public boolean removeLreadyRead(Book book) {
ArrayList<Book>books = getAlreadyReadArrayList();
if (null!=books){
for (Book b: books){
if (b.getId() == book.getId()){
if (books.remove(b)){
Gson gson = new Gson();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove(ALREADY_READ_BOOKS);
editor.putString(ALREADY_READ_BOOKS , gson.toJson(books));
editor.commit();
return true;
}
}
}
}
return false;
}
public boolean removeFromWantToRead(Book book) {
ArrayList<Book>books = getWishListArrayList();
if (null!=books){
for (Book b: books){
if (b.getId() == book.getId()){
if (books.remove(b)){
Gson gson = new Gson();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove(WANT_TO_READ_BOOKS);
editor.putString(WANT_TO_READ_BOOKS , gson.toJson(books));
editor.commit();
return true;
}
}
}
}
return false;
}
}
the Error message:
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
at com.example.newbookstoreplzwork.BookRecViewAdapter.getItemCount(BookRecViewAdapter.java:179)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:4044)
at androidx.recyclerview.widget.RecyclerView.onMeasure(RecyclerView.java:3534)
at android.view.View.measure(View.java:25086)
at androidx.constraintlayout.widget.ConstraintLayout$Measurer.measure(ConstraintLayout.java:792)
at androidx.constraintlayout.solver.widgets.analyzer.BasicMeasure.measure(BasicMeasure.java:480)
at androidx.constraintlayout.solver.widgets.analyzer.BasicMeasure.measureChildren(BasicMeasure.java:134)
at androidx.constraintlayout.solver.widgets.analyzer.BasicMeasure.solverMeasure(BasicMeasure.java:277)
at androidx.constraintlayout.solver.widgets.ConstraintWidgetContainer.measure(ConstraintWidgetContainer.java:119)
at androidx.constraintlayout.widget.ConstraintLayout.resolveSystem(ConstraintLayout.java:1578)
at androidx.constraintlayout.widget.ConstraintLayout.onMeasure(ConstraintLayout.java:1690)
at android.view.View.measure(View.java:25086)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6872)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:146)
at android.view.View.measure(View.java:25086)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6872)
at androidx.appcompat.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:490)
at android.view.View.measure(View.java:25086)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6872)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:25086)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6872)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
at android.view.View.measure(View.java:25086)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6872)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:742)
at android.view.View.measure(View.java:25086)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:3083)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1857)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2146)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1745)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7768)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:967)
at android.view.Choreographer.doCallbacks(Choreographer.java:791)
at android.view.Choreographer.doFrame(Choreographer.java:726)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:952)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
and I am really sorry it is somewhat long to read but I really do not know what to copy to know what is enough