I'm trying to make an activity that displays a list of objects in a card, in a recyclerview list. The list in the main activity takes values set by an EditText in a second activity. I got everything working fine, but when I got the intent from the second activity, I got this error, and I get the error even when working with dummy data, which I didn't before.
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at jacob.fragile.contactlist.ContactsAdapter$ViewHolder.bindTo(ContactsAdapter.java:69)
at jacob.fragile.contactlist.ContactsAdapter.onBindViewHolder(ContactsAdapter.java:43)
at jacob.fragile.contactlist.ContactsAdapter.onBindViewHolder(ContactsAdapter.java:19)
As I haven't touched the Contacts Adapter in several days, and it was working before, I don't think there is an issue there. This is my main activity.
public class MainActivity extends AppCompatActivity {
ArrayList<Contacts> mContacts;
private RecyclerView mRecyclerView;
private ContactsAdapter mAdapter;
//Declare lists to be filled with Data from Add Contact Activity
public static ArrayList<String> nameList = new ArrayList<>();
public static ArrayList<String> ageList = new ArrayList<>();
public static ArrayList<String> colorList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recyclerView);
mContacts = new ArrayList<>();
mAdapter = new ContactsAdapter(this, mContacts);
mRecyclerView.setAdapter(mAdapter);
// Get the data.
initializeData();
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
}
private void initializeData() {
//Listen for the intent
/*Intent intent = getIntent();
String nameValue = intent.getStringExtra(AddContact.NAME_MESSAGE);
String ageValue = intent.getStringExtra(AddContact.AGE_MESSAGE);
String colorValue = intent.getStringExtra(AddContact.COLOR_MESSAGE);*/
nameList.add("nameValue");
ageList.add("ageValue");
colorList.add("colorValue");
// Get the data from the lists.
String[] names = nameList.toArray(new String[nameList.size()]);
String[] age = ageList.toArray(new String[ageList.size()]);
String[] color = colorList.toArray(new String[colorList.size()]);
TypedArray imageResources =
getResources().obtainTypedArray(R.array.images);
// Clear the existing data (to avoid duplication).
mContacts.clear();
// Create the ArrayList of contacts with names and
// ages.
for(int i=0;i<names.length;i++){
mContacts.add(new Contacts(names[i],age[i], color[i], imageResources.getResourceId(i, 0)));
}
// Notify the adapter of the change.
mAdapter.notifyDataSetChanged();
//Recycle the typed array
imageResources.recycle();
}
public void fabClick(View view) {
Intent intent = new Intent(this, AddContact.class);
startActivity(intent);
}
}
Here's my ContactAdapter.java, though that isn't the actual issue
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ViewHolder> {
public static final String TAG = "RecyclerViewAdapter";
private ArrayList<Contacts> mContacts;
private Context mContext;
public ContactsAdapter(Context context, ArrayList<Contacts> contacts) {
this.mContacts = contacts;
this.mContext = context;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(mContext).
inflate(R.layout.list_item, parent, false));
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Log.d(TAG,"On viewHolder: called");
Contacts contacts = mContacts.get(position);
holder.bindTo(contacts);
}
@Override
public int getItemCount() {return mContacts.size();}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView imageView;
TextView name;
TextView age;
TextView color;
public ViewHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.contact_image);
name = itemView.findViewById(R.id.name);
age = itemView.findViewById(R.id.age);
color = itemView.findViewById(R.id.colorSpinner);
}
void bindTo(Contacts contacts) {
//Set the text views
name.setText(contacts.getName());
age.setText(contacts.getAge());
color.setText(contacts.getColor());
//Load in the images
Glide.with(mContext).load(contacts.getImageResource()).into(imageView);
}
}
}
Finally, here's the list_item that the Textviews are setting to. colorSpinner is a spinner in the second activity that gets converted to a string, so using a textview is valid
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<RelativeLayout
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/contact_image"
android:layout_width="96dp"
android:layout_height="96dp" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/contact_image"
android:padding="8dp"
android:text="@string/placeholder_name" />
<TextView
android:id="@+id/age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/name"
android:layout_toRightOf="@+id/contact_image"
android:padding="8dp"
android:text="@string/placeholder_number"
android:textColor="?android:textColorSecondary" />
<TextView
android:id="@+id/color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/age"
android:layout_toRightOf="@+id/contact_image"
android:padding="8dp"
android:text="@string/placeholder_color"
android:textColor="?android:textColorSecondary" />
</RelativeLayout>
I don't know why there's suddenly an issue. Please help. Thanks.