Recycler List Adapter is null after initialization - java

My app has a tab bar with three fragments. During the onCreate Method I call a function called initPlantList. This function initializes my RecyclerListAdapter.
private void initPlantList(){
RecyclerView rV = findViewById(R.id.plantsRecycler);
PlantListAdapter pLA = new PlantListAdapter(this);
Log.d("PLA", pLA.hasContext());
rV.setAdapter(pLA);
rV.setLayoutManager(new LinearLayoutManager(this));
}
I get this error java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setAdapter(android.support.v7.widget.RecyclerView$Adapter)' on a null object reference when I attempt to call rV.setAdapter(pLA);
Here is my Adapter Class
public class PlantListAdapter extends
RecyclerView.Adapter<PlantListAdapter.ViewHolder>{
private static final String TAG = "PlantListAdapter";
private Context mContext;
public PlantListAdapter(Context c){
this.mContext = c;
}
public String hasContext(){
if(this.mContext != null){
return mContext.getPackageResourcePath();
}
return "false";
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layoutplantlist, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder: called.");
holder.image.setImageDrawable(MyApplication.myPlantList.get(position).getImage());
holder.plantName.setText(MyApplication.myPlantList.get(position).getName());
}
#Override
public int getItemCount() {
return MyApplication.myPlantList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
CircleImageView image;
TextView plantName;
RelativeLayout plantListItem;
public ViewHolder(View itemView) {
super(itemView);
image = itemView.findViewById(R.id.plantImage);
plantName = itemView.findViewById(R.id.plantName);
plantListItem = itemView.findViewById(R.id.plantListItem);
}
}
}
Any thoughts on why it is reffering to pLA as a null object reference?

It is not your adapter that is null. Its is your Recyclerview. You are using a fragment therefore you can’t use (findViewById).
You have to find it using the view you inflated.
Try this:
private void initPlantList(View v){
RecyclerView rV = v.findViewById(R.id.plantsRecycler);
PlantListAdapter pLA = new PlantListAdapter(this);
Log.d("PLA", pLA.hasContext());
rV.setAdapter(pLA);
rV.setLayoutManager(new LinearLayoutManager(this));
}
And when you call that method in your fragment onCrrateView() just pass the view as a parameter.
Hope it helps you

Related

How to refresh a TextView from another class?

I get this error:
Attempt to invoke virtual method 'android.view.Window$Callback
android.view.Window.getCallback()' on a null object reference
public class AdaptadorCarrito extends
RecyclerView.Adapter<AdaptadorCarrito.ViewHolderCarrito> {
ArrayList<CarritoVo> listaCarrito;
AdaptadorCarrito adapter;
RecyclerView.Adapter madapter;
int i = 1;
public AdaptadorCarrito(ArrayList<CarritoVo> listaCarrito) {
this.listaCarrito = listaCarrito;
}
#NonNull
#Override
public ViewHolderCarrito onCreateViewHolder(#NonNull final ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list_carrito, null, false);
final ViewHolderCarrito myHolder = new ViewHolderCarrito(view);
final CafeteriaDB cafeteriaDB = new CafeteriaDB(parent.getContext());
myHolder.item_list_carrito.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int newPosition = myHolder.getAdapterPosition();
cafeteriaDB.eliminarProducto(myHolder.etiNombre.getText().toString(), myHolder.etiInfo.getText().toString());
eliminarProducto(newPosition);
// i++;
// Toast.makeText(parent.getContext(),"Producto Eliminado "+i+" eliminado",Toast.LENGTH_SHORT).show();
CarritoCompras obj = new CarritoCompras();
TextView tv = obj.getTextView(); //Error Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference
tv.setText(String.valueOf(cafeteriaDB.getTotal()));
}
});
return myHolder;
}
private void eliminarProducto(int position) {
listaCarrito.remove(position);
notifyItemRemoved(position);
}
#Override
public void onBindViewHolder(#NonNull ViewHolderCarrito holder, int position) {
CarritoVo positions = listaCarrito.get(position);
holder.etiNombre.setText(listaCarrito.get(position).getNombre());
holder.etiPrecio.setText(String.valueOf(listaCarrito.get(position).getPrecio()));
holder.etiInfo.setText(listaCarrito.get(position).getInfo());
holder.etiCantidades.setText(String.valueOf(listaCarrito.get(position).getCantidad()));
holder.etiFoto.setImageBitmap(positions.getFoto());
}
#Override
public int getItemCount() {
//return listaCarrito.size();
return (listaCarrito == null) ? 0 : listaCarrito.size();
}
public class ViewHolderCarrito extends RecyclerView.ViewHolder {
LinearLayout item_list_carrito;
TextView etiNombre, etiPrecio, etiInfo, etiCantidades, txtTotalB, txtTotalF;
ImageView etiFoto;
public ViewHolderCarrito(#NonNull View itemView) {
super(itemView);
item_list_carrito = (LinearLayout) itemView.findViewById(R.id.id_carrito_item);
etiFoto = (ImageView) itemView.findViewById(R.id.fotoC);
etiNombre = (TextView) itemView.findViewById(R.id.nombreC);
etiPrecio = (TextView) itemView.findViewById(R.id.precioC);
etiInfo = (TextView) itemView.findViewById(R.id.infoC);
etiCantidades = (TextView) itemView.findViewById(R.id.cantidadC);
}
}
}
Activity
public class CarritoCompras extends AppCompatActivity implements Carrito.OnFragmentInteractionListener{
TextView txtTotalF;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_carrito_compras);
CafeteriaDB db = new CafeteriaDB(this);
getTextView();
txtTotalF = (TextView)findViewById(R.id.totalF);
txtTotalF.setText(String.valueOf(db.totalFilas()));
}
public TextView getTextView(){
TextView txtTotalB = (TextView)findViewById(R.id.totalB); //Error Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference
return txtTotalB;
}
#Override
public void onFragmentInteraction(Uri uri) {
}
}
You can do like the following way
Step 1:
Load TextView at only once
TextView txtTotalB; // declare class level
inside onCreate()
txtTotalB = (TextView)findViewById(R.id.totalB);
Step 2:
create method
public TextView getTextView(){
return txtTotalB
}
Step 3:
inside your adapter class access your activity method like below
TextView tv = ((CarritoCompras)context).getTextView();
tv.setText(String.valueOf(cafeteriaDB.getTotal())); // now here you done
You can use Interfaces for communication.
Create an interface as shown below:
public interface RecyclerItemClickListener {
void onItemClick(String text);
}
In your adapter class, create declare a variable of type RecyclerItemClickListener and modify the Adapter's constructor to accept an instance of 'RecyclerItemClickListener' as a parameter. i.e Modify your Adapter class as shown below:
public class AdaptadorCarrito extends
RecyclerView.Adapter<AdaptadorCarrito.ViewHolderCarrito> {
RecyclerItemClickListener recyclerItemClickListener; //Here we are declaring a variable of the created interface
ArrayList<CarritoVo> listaCarrito;
AdaptadorCarrito adapter;
RecyclerView.Adapter madapter;
int i = 1;
//Modifying the constructor to initialize the above declared listener
public AdaptadorCarrito(ArrayList<CarritoVo> listaCarrito, RecyclerItemClickListener listener) {
this.listaCarrito = listaCarrito;
this.recyclerItemClickListener = listener;
}
#NonNull
#Override
public ViewHolderCarrito onCreateViewHolder(#NonNull final ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list_carrito, null, false);
final ViewHolderCarrito myHolder = new ViewHolderCarrito(view);
final CafeteriaDB cafeteriaDB = new CafeteriaDB(parent.getContext());
myHolder.item_list_carrito.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int newPosition = myHolder.getAdapterPosition();
cafeteriaDB.eliminarProducto(myHolder.etiNombre.getText().toString(), myHolder.etiInfo.getText().toString());
eliminarProducto(newPosition);
// i++;
// Toast.makeText(parent.getContext(),"Producto Eliminado "+i+" eliminado",Toast.LENGTH_SHORT).show();
CarritoCompras obj = new CarritoCompras();
/*TextView tv = obj.getTextView(); //Error Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference
tv.setText(String.valueOf(cafeteriaDB.getTotal()));*/
//Here we are passing the test to be displayed in the textview to your activity
recyclerItemClickListener.onItemClick(String.valueOf(cafeteriaDB.getTotal()));
}
});
return myHolder;
}
private void eliminarProducto(int position) {
listaCarrito.remove(position);
notifyItemRemoved(position);
}
#Override
public void onBindViewHolder(#NonNull ViewHolderCarrito holder, int position) {
CarritoVo positions = listaCarrito.get(position);
holder.etiNombre.setText(listaCarrito.get(position).getNombre());
holder.etiPrecio.setText(String.valueOf(listaCarrito.get(position).getPrecio()));
holder.etiInfo.setText(listaCarrito.get(position).getInfo());
holder.etiCantidades.setText(String.valueOf(listaCarrito.get(position).getCantidad()));
holder.etiFoto.setImageBitmap(positions.getFoto());
}
#Override
public int getItemCount() {
//return listaCarrito.size();
return (listaCarrito == null) ? 0 : listaCarrito.size();
}
public class ViewHolderCarrito extends RecyclerView.ViewHolder {
LinearLayout item_list_carrito;
TextView etiNombre, etiPrecio, etiInfo, etiCantidades, txtTotalB, txtTotalF;
ImageView etiFoto;
public ViewHolderCarrito(#NonNull View itemView) {
super(itemView);
item_list_carrito = (LinearLayout) itemView.findViewById(R.id.id_carrito_item);
etiFoto = (ImageView) itemView.findViewById(R.id.fotoC);
etiNombre = (TextView) itemView.findViewById(R.id.nombreC);
etiPrecio = (TextView) itemView.findViewById(R.id.precioC);
etiInfo = (TextView) itemView.findViewById(R.id.infoC);
etiCantidades = (TextView) itemView.findViewById(R.id.cantidadC);
}
}
}
Now in your Activity where you will be instantiating the AdaptadorCarrito Object, you need to pass the instance of RecyclerItemClickListener as parameter to the Adapter's constructor.
Example:
AdaptadorCarrito adapter = new AdaptadorCarrito(listaCarrito , new RecyclerItemClickListener() {
#Override
public void onItemClick(String text) {
//In here you can set your TextView's text
TextView txtTotalB = (TextView)findViewById(R.id.totalB);
txtTotalB.setText(text);
}
});
Thanks for answering, I was able to solve my problem, which was to update a text view that was in an activity but that needed the help of an event that was in another class to do so.
first adding an activity in the constructor of the adapter
Activity activity;
public AdaptadorCarrito(ArrayList<CarritoVo> nlistaCarrito, Activity nactivity) {
nListCarrito = nlistaCarrito;
this.activity = nactivity;
}
Then calling TextView the this way:
public ViewHolderCarrito onCreateViewHolder(#NonNull final ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list_carrito,null,false);
final ViewHolderCarrito myHolder = new ViewHolderCarrito(view);
final CafeteriaDB cafeteriaDB = new CafeteriaDB(parent.getContext());;
final CarritoCompras carrito = new CarritoCompras();
---->final TextView txtTotalB = (TextView)this.activity.findViewById(R.id.totalB);
txtTotalB.setText(String.valueOf(cafeteriaDB.getTotal()));
myHolder.item_list_carrito.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int newPosition = myHolder.getAdapterPosition();
cafeteriaDB.eliminarProducto(myHolder.etiNombre.getText().toString(), myHolder.etiInfo.getText().toString());
eliminarProducto(newPosition);
Toast.makeText(parent.getContext(),"Producto Eliminado",Toast.LENGTH_SHORT).show();
-----> txtTotalB.setText(String.valueOf(cafeteriaDB.getTotal()));
}
});
return myHolder;
}
and finally creating an instance of the adapter in the activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_carrito_compras);
ArrayList<CarritoVo> nLlistaCarrito = null;
------>AdaptadorCarrito adapter = new AdaptadorCarrito(nLlistaCarrito,this);
CafeteriaDB cafeteriaDB = new CafeteriaDB(this);
TextView txtTotalB = (TextView)findViewById(R.id.totalB);
txtTotalB.setText(String.valueOf(cafeteriaDB.totalFilas()));
TextView txtTotalF = (TextView)findViewById(R.id.totalF);
txtTotalF.setText(String.valueOf(cafeteriaDB.totalFilas()));
}

'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference Adapter.Messageadapter.onBindViewHolder

I am getting:
Attempt to invoke virtual method 'void
android.widget.TextView.setText(java.lang.CharSequence)' on a null
object reference
This error is at the beginning of the crash.
This is my first time getting this type of error
public class Messageadapter extends RecyclerView.Adapter {
private static final int MSG_TYPE_LEFT=0;
private static final int MSG_TYPE_RIGHT=1;
private Context mContext;
private List<Chat> mChat;
private String imageurl;
FirebaseUser fuser;
public Messageadapter(Context mContext, List<Chat> mChat,String imageurl) {
this.mContext=mContext;
this.mChat=mChat;
this.imageurl=imageurl;
}
#NonNull
#Override
public Messageadapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if(viewType==MSG_TYPE_RIGHT){
View view= LayoutInflater.from(mContext).inflate(R.layout.chat_item_right,parent,false);
return new Messageadapter.ViewHolder(view);
}else {
View view= LayoutInflater.from(mContext).inflate(R.layout.chat_item_left,parent,false);
return new Messageadapter.ViewHolder(view);
}
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
Chat chat=mChat.get(position);
((ViewHolder) holder).show_message.setText(chat.getMessage());///////Error is said on this line/////////////////
((UserAdapter.ViewHolder) holder).profile_image.setImageResource(R.mipmap.ic_launcher);
}
#Override
public int getItemCount() {
return mChat.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView show_message;
public ImageView profile_image;
public ViewHolder(#NonNull View itemView) {
super(itemView);
show_message=itemView.findViewById(R.id.show_message);
profile_image=itemView.findViewById(R.id.profileimage);
}
}
#Override
public int getItemViewType(int position) {
fuser= FirebaseAuth.getInstance().getCurrentUser();
if(mChat.get(position).getSender().equals(fuser.getUid())){
return MSG_TYPE_RIGHT;
}
else {
return MSG_TYPE_LEFT;
}
}
}
I want this Viewholder to pick this message but it is not displaying.
Here ((ViewHolder) holder).show_message.setText(chat.getMessage());
you are casting the base recycler view holder not your view holder
instead make it like this ((UserAdapter.ViewHolder).show_message.setText(chat.getMessage());

Attempt to invoke interface method 'int java.util.List.size()' on a null object reference in recyclerview [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
Hello everyone I'm working with an app and I'm consuming rest api using retrofit2. I have a list of companies that I need to show using recyclerview. I have followed a lot of resources and tutorials but none helped me. In the logcat session I have an error: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference in my adapter....
in this line :
#Override
public int getItemCount() {
return companies.size();
}
Here is my code:
my adapter
private List<Company> companies;
private Context context;
public CompanyAdapter(List<Company> companies, Context context) {
this.companies = companies;
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.row_companies, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int position) {
Company comp = companies.get(position);
viewHolder.compName.setText(comp.getName());
viewHolder.compDesc.setText(comp.getDescription());
viewHolder.compNipt.setText(comp.getNipt());
}
#Override
public int getItemCount() {
return companies.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView compName, compDesc, compNipt;
public ViewHolder(#NonNull View itemView) {
super(itemView);
compName = (TextView) itemView.findViewById(R.id.tvCompanyName);
compDesc = (TextView) itemView.findViewById(R.id.tvCompanyDescription);
compNipt = (TextView) itemView.findViewById(R.id.tvCompanyNipt);
}
}
and my activity
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private List<Company> companies;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_companies_list);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.companies_list);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new CompanyAdapter(companies, this);
recyclerView.setAdapter(adapter);
}
What I'm doing wrong...
Any help is appreciated!
#Override
public int getItemCount() {
return companies == null ? 0 : companies.size()
}

How to set a progress for many progress-bars in RecyclerView

I am using a RecyclerView to view many Progress Bars as a slide show and an adapter.
This my adapter class
public class RecAdapter extends RecyclerView.Adapter<RecAdapter.ViewHolder> {
private static final String TAG = "RecAdapter";
private ArrayList progressbars = new ArrayList<>();
private Context pcontex;
public RecAdapter(Context pcontex ,ArrayList progressbars) {
this.progressbars = progressbars;
this.pcontex = pcontex;
}
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.progress,viewGroup,false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int i) {
Log.d(TAG, "onBindViewHolder: called");
}
#Override
public int getItemCount() {
return progressbars.size() ;
}
public class ViewHolder extends RecyclerView.ViewHolder {
ProgressBar b ;
ConstraintLayout parent;
public ViewHolder(#NonNull View itemView) {
super(itemView);
b = itemView.findViewById(R.id.progressBar);
parent= itemView.findViewById(R.id.parent);
}
}
}
My MainActivity code-
Prog = new ArrayList<>(); b2 = findViewById(R.id.progressBar) ;
b = findViewById(R.id.progressBar);
probitmap();
private void probitmap(){
Log.d(TAG, "probitmap: preparing bit maps");
Prog.add(b);
Prog.add(b2);
Recycle();// this method is out of on create
}
private void Recycle(){
Log.d(TAG, "Recycle: init recycleview");
recyclerView =findViewById(R.id.Rec);
RecAdapter Adapter = new RecAdapter(this,Prog);
recyclerView.setAdapter(Adapter);
LinearLayoutManager layoutManager
= new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(layoutManager);
}
The code is working perfectly but I need to retrieve every progress bar that is in the recycle view and set progress for each one.
I tried multiple ways but it doesn't work. Here is what I tried-
for (int i = 0; i < recyclerView.getChildCount(); i++) {
RecAdapter.ViewHolder holder = (RecAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(i);
holder.b.setProgress(50);
}
Use OnBindViewHolder to manage each "row" generated by the recycler.
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int i) {
viewHolder.b.setProgress(progressbar.get(i)); //i is the position of the recycler
viewHolder.b.setListener....
}

Unable to call method in Adapter from ViewHolder (RecyclerView)

I'm trying to delete an item from my RecyclerView when the user clicks on it. However, even though the delete method in the Adapter is public I get the error 'Cannot resolve method delete(int)' when trying to call 'delete' method from the onClick in MyViewHolder.
What gives? It's public so why can't I call it?
GroceryItemAdapter
public class GroceryItemAdapter extends RecyclerView.Adapter<MyViewHolder> {
private LayoutInflater inflater;
private Context context;
List<MetaData> data = Collections.emptyList();
public GroceryItemAdapter(Context context, List<MetaData> data) {
this.context = context;
inflater = LayoutInflater.from(context);
this.data = data;
}
public void delete(int position) {
data.remove(position);
notifyItemRemoved(position);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.grocery_item_row, parent, false);
MyViewHolder holder = new MyViewHolder(view);
Log.i("GroceryHero", "onCreateViewHolder called");
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
MetaData current = data.get(position);
holder.title.setText(current.title);
holder.icon.setImageResource(current.iconid);
Log.i("GroceryHero","onBindViewHolder called " + position);
}
#Override
public int getItemCount() {
return data.size();
}
}
MyViewHolder:
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView title;
ImageView icon;
public MyViewHolder(View itemView) {
super(itemView);
Log.i("GroceryHero", "MyViewHolder called");
title = (TextView) itemView.findViewById(R.id.grocery_text);
icon = (ImageView) itemView.findViewById(R.id.grocery_icon);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Item clicked at " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
delete(getAdapterPosition()); // ERROR: Cannot resolve method
}
}
You're trying to call delete from the view holder class. But delete is a method of the adapter class. You can may be pass an instance of adapter to the view holder in onCreateViewHolder and store it as a private field.
GroceryItemAdapter mAdapter;
public MyViewHolder(View itemView, GroceryItemAdapter adapter) {
mAdapter = adapter;
...
}
// now you can call
mAdapter.delete(getAdapterPosition());

Categories