I have built an overview of an order with a ReyclerView. Below you can see the code for the adapter class. My problem only occurs in the following place, if the user clicks on an element of ReyclerView, a popup with an expanded view should appear.
This popup also occurs. Unfortunately, as soon as I want to populate the TextView with the order code, the app supports and says null Attempt to invoke virtual method'void android.widget.TextView.setText (java.lang.CharSequence)' on a null object reference.
How can I avoid this null error so that it all works?
import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.text.Layout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class UserBestellAdapter extends RecyclerView.Adapter<UserBestellAdapter.ViewHolder> {
ArrayList<Bestellung> bestellung;
Context mContext;
Dialog epicDialog;
public UserBestellAdapter(Context context, ArrayList<Bestellung> list) {
mContext = context;
bestellung = list;
epicDialog = new Dialog(mContext);
}
#NonNull
#Override
public UserBestellAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.adapter_bestell, parent, false);
UserBestellAdapter.ViewHolder viewHolder = new UserBestellAdapter.ViewHolder(view);
return viewHolder;
}
#NonNull
#Override
public void onBindViewHolder(#NonNull UserBestellAdapter.ViewHolder holder, int position) {
//Gesamtpreis: holder.item_betrag.setText(String.valueOf(bestellung.get(position).getBetrag()));
// Datum: holder.item_datum.setText(bestellung.get(position).getDatum());
holder.item_items.setText(bestellung.get(position).getProdukte());
//holder.item_code.setText(bestellung.get(position).getBestellnummer());
String bestellid =bestellung.get(position).getBestellnummer() + "";
holder.item_code.setText(bestellid);
holder.item_betrag.setText(Double.toString(bestellung.get(position).getSumme()));
holder.item_datum.setText(bestellung.get(position).getDatum());
holder.layout_user_bestellung.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
TextView order_overview_number = epicDialog.findViewById(R.id.order_overview_number);
order_overview_number.setText();
epicDialog.setContentView(R.layout.order_popup_waiting);
epicDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
Button btn_order_overview_finish = (Button) epicDialog.findViewById(R.id.btn_order_overview_finish);
/*
btn_order_overview_finish.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
epicDialog.dismiss();
}
});*/
epicDialog.show();
}
});
}
#Override
public int getItemCount() {
return bestellung.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private TextView item_items, item_betrag, item_datum, item_code;
private ConstraintLayout layout_user_bestellung;
public ViewHolder(#NonNull View itemView) {
super(itemView);
item_items = itemView.findViewById(R.id.items);
item_betrag = itemView.findViewById(R.id.betrag);
item_datum = itemView.findViewById(R.id.datum);
item_code = itemView.findViewById(R.id.code);
layout_user_bestellung = itemView.findViewById(R.id.layout_user_bestellung);
}
}
}
Your Dialog is initialized with new Dialog(context) but in your onClick Method you expect that your epicDialog has a TextVew with the id order_overview_number.
This will always return null and thus order_overview_number.setText() thows a NPE.
To reference a view of a Dialog the Dialog needs a layout which contains that view, similar to fragments and activities.
This may have further information for you:
How to create a Custom Dialog box in android?
https://developer.android.com/guide/topics/ui/dialogs
Related
It's a chatting application where i only wanted to display the users from database those whose numbers are available on the users device contact list.
I have got the list of contact list but i don't know how to query the database or i even tried a work around where it displays the user information who are present but those who are not present it shows a default itemview. You can check image link for reference
package com.example.myapplication;
import android.database.Cursor;
import android.graphics.Color;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
/**
* A simple {#link Fragment} subclass.
* Use the {#link Fragment1#newInstance} factory method to
* create an instance of this fragment.
*/
public class Fragment1 extends Fragment {
private FirebaseFirestore firebaseFirestore;
LinearLayoutManager linearLayoutManager;
private FirebaseAuth firebaseAuth;
ImageView imageViewOfUser;
FirestoreRecyclerAdapter<firebasemodel, NoteViewHolder> chatAdapter;
RecyclerView recyclerView;
ArrayList<String> contactList;
ArrayList<String> getcontactList;
public Fragment1() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_1, container, false);
firebaseAuth = FirebaseAuth.getInstance();
firebaseFirestore = FirebaseFirestore.getInstance();
recyclerView = view.findViewById(R.id.recyclerview);
contactList = new ArrayList<String>();
getcontactList = getContactList();
Query query = firebaseFirestore.collection("Users").whereNotEqualTo("uid", firebaseAuth.getUid());
FirestoreRecyclerOptions<firebasemodel> allusername = new FirestoreRecyclerOptions.Builder<firebasemodel>().setQuery(query, firebasemodel.class).build();
chatAdapter = new FirestoreRecyclerAdapter<firebasemodel, NoteViewHolder>(allusername) {
#Override
protected void onBindViewHolder(#NonNull NoteViewHolder noteViewHolder, int i, #NonNull firebasemodel firebasemodel) {
for (String m : getcontactList) {
if (firebasemodel.getContact().equals(m)) {
noteViewHolder.particularusername.setText(firebasemodel.getName());
String uri = firebasemodel.getImage();
Picasso.get().load(uri).into(imageViewOfUser);
if (firebasemodel.getStatus().equals("Online")) {
noteViewHolder.statusofuser.setText(firebasemodel.getStatus());
noteViewHolder.statusofuser.setTextColor(Color.rgb(66, 133, 244));
} else {
noteViewHolder.statusofuser.setText(firebasemodel.getStatus());
}
noteViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), "Clicked on particular user", Toast.LENGTH_SHORT).show();
}
});
} else {
//else code?
}
}
}
#NonNull
#Override
public NoteViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chatviewlayout, parent, false);
return new NoteViewHolder(view);
}
};
recyclerView.setHasFixedSize((true));
linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setOrientation(RecyclerView.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(chatAdapter);
return view;
}
public class NoteViewHolder extends RecyclerView.ViewHolder{
private TextView particularusername;
private TextView statusofuser;
public NoteViewHolder(#NonNull View itemView) {
super(itemView);
particularusername = itemView.findViewById(R.id.nameofuser);
statusofuser = itemView.findViewById(R.id.statusofuser);
imageViewOfUser = itemView.findViewById(R.id.imageviewofuser);
}
}
//-----------------------------------------------------------------------------------------------//
#Override
public void onStart() {
super.onStart();
chatAdapter.startListening();
}
#Override
public void onStop() {
super.onStop();
if(chatAdapter!=null){
chatAdapter.stopListening();
}
}
//-----------------------------------------------------------------------------------------//
private ArrayList<String> getContactList(){
Cursor phones = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,null,null,null);
while (phones.moveToNext()){
String phone = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER));
contactList.add(phone);
}
return contactList;
}
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 1 year ago.
I have build a RecyclerViewer application in Java using android studio.
When I run the app it crashes, when I checked the Logcat I found there is a null pointer exception in my Adapter.
onBindViewHolder method.
This covers line 49.
#Override
public void onBindViewHolder(#NonNull ContactsAdapter.ViewHolder holder, int position) {
holder.txtName.setText(contacts.get(position).getName());
holder.txtName.setText(contacts.get(position).getEmail());
Glide.with(context).asBitmap().load(contacts.get(position).getImage()).into(holder.image);
holder.parent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, contacts.get(position).getName() + " Clicked", Toast.LENGTH_SHORT).show();
}
});
}
Logcat log
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.cardview.widget.CardView.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.example.learningapplication.ContactsAdapter.onBindViewHolder(ContactsAdapter.java:49)
at com.example.learningapplication.ContactsAdapter.onBindViewHolder(ContactsAdapter.java:19)
EDIT:
Here is the full code:
package com.example.learningapplication;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ViewHolder>{
private Context context;
ArrayList<Contacts> contacts = new ArrayList<>();
public void setContacts(ArrayList<Contacts> contacts) {
this.contacts = contacts;
notifyDataSetChanged();
}
public ContactsAdapter(Context context) {
this.context = context;
}
public ContactsAdapter() {
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.contacts_layout, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ContactsAdapter.ViewHolder holder, int position) {
holder.txtName.setText(contacts.get(position).getName());
holder.txtName.setText(contacts.get(position).getEmail());
Glide.with(context).asBitmap().load(contacts.get(position).getImage()).into(holder.image);
holder.parent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, contacts.get(position).getName() + " Clicked", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return contacts.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder{
private TextView txtName;
private TextView txtEmail;
private ImageView image;
private CardView parent;
public ViewHolder(#NonNull View itemView) {
super(itemView);
txtName = itemView.findViewById(R.id.txtName);
txtEmail = itemView.findViewById(R.id.txtEmail);
image = itemView.findViewById(R.id.image);
}
}
}
``
as i understand:
holder.parent - this is null
check your initializations
I was trying to practice using the Recycler in Android Studio using Java.
I have made so much progress so far.
When I run the application it crashes immediately, I have checked the logs and I had an error on the below:
Attempt to invoke virtual method 'android.view.View androidx.recyclerview.widget.RecyclerView.findViewById(int)' on a null object reference
and
Attempt to invoke virtual method 'android.view.View androidx.recyclerview.widget.RecyclerView.findViewById(int)' on a null object reference
Below is my MainActivity class:
package com.example.recyleview;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.LinearLayout;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private RecyclerView recView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recView.findViewById(R.id.recView);
recView.setLayoutManager(new LinearLayoutManager(this));
setContentView(R.layout.activity_main);
ArrayList<Contact> contacts = new ArrayList<>();
contacts.add(new Contact("Jacob", "jacob#gmail.com", "later"));
contacts.add((new Contact("Sara ", "sara#gmail.com", "later")));
contacts.add(new Contact("Nino", "nino#gmail.com", "later"));
ContactsRecViewAdapter adapter = new ContactsRecViewAdapter(this);
adapter.setContacts(contacts);
recView.setAdapter(adapter);
}
}
and here is another class called ContactsRecViewAdapter
package com.example.recyleview;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class ContactsRecViewAdapter extends RecyclerView.Adapter<ContactsRecViewAdapter.ViewHolder>{
private ArrayList<Contact> contacts = new ArrayList<>();
private final Context context;
public ContactsRecViewAdapter(Context context) {
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.contacts_list_item, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull ContactsRecViewAdapter.ViewHolder holder, int position) {
holder.txtName.setText(contacts.get(position).getName());
holder.parent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, contacts.get(position).getName() + " Clicked", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return contacts.size();
}
public void setContacts(ArrayList<Contact> contacts) {
this.contacts = contacts;
notifyDataSetChanged();
}
public static class ViewHolder extends RecyclerView.ViewHolder{
private final TextView txtName;
private final RelativeLayout parent;
public ViewHolder(#NonNull View itemView) {
super(itemView);
txtName = itemView.findViewById(R.id.txtName);
parent = itemView.findViewById(R.id.parent);
}
}
}
Change
recView.findViewById(R.id.recView);
to
recView = findViewById(R.id.recView);
Also you have duplicated:
setContentView(R.layout.activity_main);
You have to set the contentView before you try to find the views.
I want the app to open a page when the user taps on an item and pass some extra information to that intent. That's it. I tried about 7 - 10 onclickListener types but I didn't solve anything. I am posting my adapter class with the latest implementation ( that doesn't work ). Json works and the Recyclerview loads data and images from url with no problems.
package byDragosT.myapplication;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class RecipeApiAdapter extends RecyclerView.Adapter<RecipeApiAdapter.RecipeViewHolder> {
private ArrayList<RecipeItem> recipeItems;
private Context context;
public RecipeApiAdapter(ArrayList<RecipeItem> recipeItems, Context context){
this.recipeItems = recipeItems;
this.context = context;
}
#NonNull
#Override //// Mare grija ce layout pui aici - sfat pentru viitor - mi-a luat 4 ore sa gasesc eroarea
public RecipeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recipe_item_in_recyclerview_api, parent, false);
return new RecipeViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecipeViewHolder holder, int position) {
final RecipeItem recipeItem = recipeItems.get(position);
holder.title.setText(recipeItem.getMnameRecipe());
holder.description.setText(recipeItem.getMdescribeRecipe());
Picasso.get().load(recipeItem.getItemPictureUrl())
.into(holder.jpegRecipe);
System.out.println("image with title: " + holder.title.getText() + "was added in theory");
}
#Override
public int getItemCount() {
return recipeItems.size();
}
public static class RecipeViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public ImageView jpegRecipe;
public TextView title;
public TextView description;
public RelativeLayout containerView;
public RecyclerView mRecyclerView;
RecipeViewHolder(View view){
super(view);
jpegRecipe = view.findViewById(R.id.picture);
title = view.findViewById(R.id.recipe_name);
description = view.findViewById(R.id.ingredients_list);
containerView = view.findViewById(R.id.recipe_item_container); // vezi aici
mRecyclerView = view.findViewById(R.id.recyclerView);
}
#Override
public void onClick(View v) {
int itemPosition = mRecyclerView.getChildLayoutPosition(v);
RecipeItem current = recipeItems.get(itemPosition);
Intent intent = new Intent(v.getContext(), RecipeDetailsActivity.class);
intent.putExtra("name", current.getMnameRecipe());
v.getContext().startActivity(intent);
}
}
}
Try adding view.setOnClickListener(this);
RecipeViewHolder(View view){
super(view);
view.setOnClickListener(this);
.....
}
I am trying to open a dialog box from my Recycler adapter onClick of a button.
For that i need to get the FragmentManager using the getFragmentManager method ,which can only be called with the help of the activity object .
Here is my code :
RecyclerAdapter2 :
package com.example.batrad.expenseassist;
import android.app.Activity;
import android.app.FragmentManager;
import android.content.Context;
import android.media.Image;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Collections;
import java.util.List;
/**
* Created by batrad on 11/18/2016.
*/
public class RecyclerAdapter2 extends RecyclerView.Adapter<RecyclerAdapter2.MyViewHolder> {
List<Information2> data = Collections.emptyList();
private LayoutInflater inflator;
Activity activity;
FragmentManager fm;
public RecyclerAdapter2(Context context, List<Information2> data) {
activity=(Activity)context;
inflator = LayoutInflater.from(context);
this.data = data;
fm=activity.getFragmentManager();
}
#Override
public RecyclerAdapter2.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view =inflator.inflate(R.layout.recycler_row_category,parent,false);
MyViewHolder holder=new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(RecyclerAdapter2.MyViewHolder holder, int position) {
Log.d("tag",data.get(0)+"");
Information2 info=data.get(position);
Log.d("testre",info.categoryName+info.amount);
holder.categoryName.setText(info.categoryName);
holder.amount.setText(info.amount+"");
holder.categoryImage.setImageResource(info.categoryImage);
}
public void onInsert(int size){
notifyItemInserted(size);
}
#Override
public int getItemCount() {
return data.size();
}
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView categoryName;
TextView amount;
ImageView categoryImage;
ImageView deleteIcon;
ImageView addIcon;
public MyViewHolder(View itemView) {
super(itemView);
categoryName=(TextView) itemView.findViewById(R.id.categoryName);
amount=(TextView) itemView.findViewById(R.id.amount);
categoryImage=(ImageView) itemView.findViewById(R.id.categoryImage);
deleteIcon=(ImageView) itemView.findViewById(R.id.deleteIcon);
addIcon=(ImageView) itemView.findViewById(R.id.addIcon);
addIcon.setOnClickListener(this);
}
#Override
public void onClick(View view) {
SubCategoryDialog subCategoryDialog=new SubCategoryDialog();
SubCategoryDialog.setValues(data.get(getAdapterPosition()).categoryName);
subCategoryDialog.show(fm, "Create Category");
}
}
}
Inside the constructor of RecyclerAdapter2 I am passing the context of the activity from my MainActivity Java file:
MainActivity.java :
categoryrecycleAdapter = new RecyclerAdapter2(this, getdata());
Inside RecyclerAdapter2 constructor i assign the context to Activity class's object .
And than i use the object to get the fragmentManager.
But i am getting IllegalStateException here :
java.lang.IllegalStateException: Activity has been destroyed
at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1433)
at android.app.BackStackRecord.commitInternal(BackStackRecord.java:687)
at android.app.BackStackRecord.commit(BackStackRecord.java:663)
at android.app.DialogFragment.show(DialogFragment.java:230)
at com.example.batrad.expenseassist.RecyclerAdapter2$MyViewHolder.onClick(RecyclerAdapter2.java:85)
at android.view.View.performClick(View.java:5233)
at android.view.View$PerformClick.run(View.java:21209)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:152)
Please help .
This is not the right way to attach listeners. You should set the onClickListener in the constructor of your viewholder and should send a callback to your fragment using an interface as shown below or you can also use BaseAdapter from this or this.
public interface OnItemClickListener {
void onItemClick(View v);
}
private final OnItemClickListener listener;
public RecAdapter(OnItemClickListener listener) {
this.listener = listener;
}
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemCLick(v);
}
});
}