I have implemented a RecyclerView with a custom adapter that adds a my own custom objects made from the my class Item. Now I am trying to add a Spinner that will have a list of Strings where when you click on an object in the Spinner drop down menu, it will change the content of the RecyclerView. Basically where each choice in the Spinner will have its own list for the RecyclerView. But when I try to add content to the Spinner, the app crashes when I try to start it. This is the code I added to onCreate(Bundle savedInstanceState) that made the app crashed:
ArrayList<String> lists = new ArrayList<>();
lists.add("firstList");
lists.add("secondList");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_dropdown_item, lists);
dropdown.setAdapter(adapter);
I thought it might be crashing because the ArrayAdpater somehow conflicts with my custom ItemAdapter, but I am not sure because I am new to using adapters. Does anyone know how I can resolve this?
If it will help I have my custom adapter here:
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ExampleViewHolder> {
private ArrayList<Item> mItemList;
private OnItemClickListener mListener;
private int selectedPosition=-1;
public interface OnItemClickListener{
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
public static class ExampleViewHolder extends RecyclerView.ViewHolder{
public TextView mTextView1;
public TextView mTextView2;
public ExampleViewHolder(#NonNull View itemView, final OnItemClickListener listener) {
super(itemView);
mTextView1 = itemView.findViewById(R.id.text1);
mTextView2 = itemView.findViewById(R.id.text2);
itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
if(listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onItemClick(position);
}
}
}
});
}
}
public ItemAdapter(ArrayList<Item> itemList) {
mItemList = itemList;
}
#NonNull
#Override
public ExampleViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.example_item, viewGroup, false);
ExampleViewHolder evh = new ExampleViewHolder(v, mListener);
return evh;
}
#Override
public void onBindViewHolder(#NonNull ExampleViewHolder exampleViewHolder, final int position) {
Item currentItem = mItemList.get(position);
exampleViewHolder.mTextView1.setText(currentItem.getText1());
exampleViewHolder.mTextView2.setText(currentItem.getText2());
if(selectedPosition==position)
exampleViewHolder.itemView.setBackgroundColor(Color.GREEN);
else
exampleViewHolder.itemView.setBackgroundColor(Color.parseColor("#ffffff"));
exampleViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MainActivity.positionOfChosenItem = position;
selectedPosition = position;
MainActivity.btnChange.setVisibility(View.VISIBLE);
MainActivity.btnDelete.setVisibility(View.VISIBLE);
MainActivity.changeAmountField.setVisibility(View.VISIBLE);
notifyDataSetChanged();
}
});
}
#Override
public int getItemCount() {
return mItemList.size();
}
EDIT: I have made sure that the variables are set to the right value like setting dropdown to the Spinner in the layout.
dropdown = findViewById(R.id.spinner);
And have set contentView to the layout, that the Spinner lies in. setContentView(R.layout.activity_main);
EDIT: Here is the error as well:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.barxqrscanner2, PID: 20357
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.barxqrscanner2/com.example.barxqrscanner2.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Spinner.setAdapter(android.widget.SpinnerAdapter)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2955)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3030)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6938)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Spinner.setAdapter(android.widget.SpinnerAdapter)' on a null object reference
at com.example.barxqrscanner2.MainActivity.buildDropDown(MainActivity.java:123)
at com.example.barxqrscanner2.MainActivity.onCreate(MainActivity.java:61)
at android.app.Activity.performCreate(Activity.java:7174)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1220)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2908)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3030)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6938)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Application terminated.
Your error (NullPointerException) is due to this line:
dropdown.setAdapter(adapter);
Your object dropdown seems to be null.
I think you forgot to instantiate this object, or you are calling setAdapter() before instantiating dropdown. But without the rest of the code, it is difficult to tell more precisely what's the real problem.
Best
Related
I have a simple adapter that uses 2 String based array lists. For some reason I am getting a NullPointerException even though I am sure the information is being passed by.
My adapter:
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder> {
private ArrayList<String> names = new ArrayList<>();
private ArrayList<String> details = new ArrayList<>();
private Context mContext;
public MovieAdapter(ArrayList<String> names, ArrayList<String> details, Context mContext) {
this.names = names;
this.details = details;
this.mContext = mContext;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.detail_view, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.name.setText(names.get(position));
holder.detail.setText(details.get(position));
}
#Override
public int getItemCount() {
return names.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView name;
private TextView detail;
private ConstraintLayout cl;
public ViewHolder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.name);
detail = itemView.findViewById(R.id.detial);
cl = itemView.findViewById(R.id.layout);
}
}
}
My REST call and recylerView initialization activity(added the REST call in case the problem is lying there):
// ArrayList<String> namesArray = new ArrayList<>(Arrays.asList("Rated:", "Released:", "Runtime:", "Genre:", , "Writer:", "Actors:", "Plot:", "Language:", "Country:"));
ArrayList<String> namesArray = new ArrayList<>();
namesArray.add("Rated:");
namesArray.add("Released:");
namesArray.add("Runtime:");
namesArray.add("Genre:");
namesArray.add("Director:");
namesArray.add("Writer:");
namesArray.add("Actors:");
namesArray.add("Plot");
namesArray.add("Language:");
namesArray.add("Country");
trazi.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Call<Movie> call;
movieApi = ApiClient.getClient().create(MovieApi.class);
if (paramYear.getText().toString().matches("")) {
call = movieApi.getDetails(key, paramName.getText().toString(), null);
} else {
call = movieApi.getDetails(key, paramName.getText().toString(), Integer.parseInt(paramYear.getText().toString()));
}
call.enqueue(new Callback<Movie>() {
#Override
public void onResponse(Call<Movie> call, Response<Movie> response) {
Toast.makeText(getApplication().getApplicationContext(), " valja", Toast.LENGTH_LONG).show();
movie = response.body();
// ArrayList<String> details = new ArrayList<>(Arrays.asList(movie.getRated(), movie.getReleased(), movie.getRuntime(), movie.getGenre(), movie.getDirector(), movie.getWriter(), movie.getActors(), movie.getPlot(), movie.getLanguage(), movie.getCountry()));
ArrayList<String> details = new ArrayList<>();
details.add(movie.getRated());
details.add(movie.getReleased());
details.add(movie.getRuntime());
details.add(movie.getGenre());
details.add(movie.getDirector());
details.add(movie.getWriter());
details.add(movie.getActors());
details.add(movie.getPlot());
details.add(movie.getLanguage());
details.add(movie.getCountry());
Picasso.get().load(movie.getPoster()).fit().centerInside().into(image);
image.setVisibility(View.VISIBLE);
title.setText(movie.getTitle());
title.setVisibility(View.VISIBLE);
recyclerView = findViewById(R.id.layout);
movieAdapter = new MovieAdapter(namesArray, details, getApplication().getApplicationContext());
recyclerView.setAdapter(movieAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplication().getApplicationContext()));
}
So
Picasso.get().load(movie.getPoster()).fit().centerInside().into(image);
and
title.setText(movie.getTitle());
work perfectly so the information is passed to the adapter and I tried to initialize array lists on two different ways just in case. Still no success. Any ideas on where the problem is?
Edit:
My error log:
2020-05-24 17:20:22.600 27595-27595/com.example.cetvrtizadatak E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.cetvrtizadatak, PID: 27595
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setAdapter(androidx.recyclerview.widget.RecyclerView$Adapter)' on a null object reference
at com.example.cetvrtizadatak.MainActivity$1$1.onResponse(MainActivity.java:115)
at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda$onResponse$0$DefaultCallAdapterFactory$ExecutorCallbackCall$1(DefaultCallAdapterFactory.java:81)
at retrofit2.-$$Lambda$DefaultCallAdapterFactory$ExecutorCallbackCall$1$3wC8FyV4pyjrzrYL5U0mlYiviZw.run(Unknown Source:6)
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:6702)
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:911)
Your NullPointerException is happening when you try to access a member of you recyclerView object, meaning that its value is probably null.
Looking at your code I can presume that the id you're passing is not of yout recyclerView but for an layout object.
Double check if in your layout xml file the id given to the recyclerView is the one you're referencing on you call to findViewById.
I have created a shopping cart via recyclerview. Each viewholder also has a + and - button to add or remove quantity. This functionality is done in the adapter and I have to notify the parent fragment of the updated total amount. This last bit is done via an interface. The problem is, I am getting the following error:
Process: com.ecomm.market, PID: 6630
java.lang.NullPointerException: Attempt to invoke interface method 'void com.ecomm.market.SelectionAdapter$OnUpdateCartListener.onUpdateCart(int)' on a null object reference
at com.ecomm.market.SelectionAdapter$ViewHolder$1.onClick(SelectionAdapter.java:103)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
The selected item and corresponding quantity are stored in a hashmap that I convert to an array to populate the recycler view cart. This is what the relevant part of my main fragment MenuFragment looks like:
// Using the adapter interface to add items to cart and adding up total amount
menuItemAdapter.setOnAddToCartListener(new MenuItemAdapter.OnAddToCartListener() {
#Override
public void onAddToCart(final HashMap selectionItemsHashMap) {
setupSelectionRecycler(menuView);
totalAmount = mapToArray(selectionItemsHashMap);
selectionAdapter = new SelectionAdapter(selectionItemArrayList, selectionItemsHashMap, totalAmount);
selectionRecycler.setAdapter(selectionAdapter);
cartItemsHashmap = selectionItemsHashMap;
selectionAdapter.setUpdateCartListener(new SelectionAdapter.OnUpdateCartListener() {
#Override
public void onUpdateCart(int updatedTotalAmount) {
String stringTotalAmount = Integer.toString(updatedTotalAmount);
Log.d(TAG, "received total:" +stringTotalAmount);
tvTotalAmount.setText("$"+ stringTotalAmount);
totalAmount = updatedTotalAmount;
}
});
}
});
}
And here is an excerpt from my adapter SelectionAdapter:
public class SelectionAdapter extends RecyclerView.Adapter<SelectionAdapter.ViewHolder> {
private static final String TAG = SelectionAdapter.class.getSimpleName();
private ArrayList<SelectionItem> selectionItemArrayList = new ArrayList<>();
public HashMap<String, Integer> selectionItemsHashMap = new HashMap<String, Integer>();
public int totalAmount;
private OnUpdateCartListener updateCartListener;
public interface OnUpdateCartListener {
void onUpdateCart(int totalAmount);
}
public void setUpdateCartListener(OnUpdateCartListener updateCartListener) {
this.updateCartListener = updateCartListener;
}
public SelectionAdapter(ArrayList<SelectionItem> selectionItemArrayList, HashMap<String, Integer> selectionItemsHashMap, int currentTotalAmount) {
this.selectionItemArrayList = selectionItemArrayList;
this.selectionItemsHashMap = selectionItemsHashMap;
this.totalAmount = currentTotalAmount;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.selection_card, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int position) {
viewHolder.tvSelectItem.setText(selectionItemArrayList.get(position).getSelectionName());
String quantity = Integer.toString(selectionItemArrayList.get(position).getSelectionQuantity());
viewHolder.tvDishQuantity.setText(quantity);
}
#Override
public int getItemCount() {
return selectionItemArrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tvSelectItem, tvDishQuantity;
ImageView addQuantity, subtractQuantity, deleteItem;
public ViewHolder(#NonNull View itemView) {
super(itemView);
tvSelectItem = itemView.findViewById(R.id.dish_selection);
tvDishQuantity = itemView.findViewById(R.id.dish_quantity);
addQuantity = itemView.findViewById(R.id.button_add);
subtractQuantity = itemView.findViewById(R.id.button_subtract);
deleteItem = itemView.findViewById(R.id.delete_item);
addQuantity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Find the name of the menu item
int position = getAdapterPosition();
String itemName = selectionItemArrayList.get(position).getSelectionName();
// Increase quantity
int currentQuantity = selectionItemsHashMap.get(itemName);
currentQuantity += 1;
// Update the hashmap with the new quantity
selectionItemsHashMap.put(itemName,currentQuantity);
//Update total amount
for (Object name: selectionItemsHashMap.keySet()) {
String key = (String) name;
if (key.equals(selectionItemArrayList.get(position).getSelectionName())) {
int eachPrice = Integer.parseInt(selectionItemArrayList.get(position).getSelectionPrice());
totalAmount += eachPrice;
}
}
// Display the new quantity
String stringCurrentQuantity = Integer.toString(currentQuantity);
tvDishQuantity.setText(stringCurrentQuantity);
//updateCartListener.onUpdateCart(totalAmount);
}
});
}
EDIT
A couple of points:
- When the cart is initially filled, I use this same code and it works fine.
- The problem occurs once the user returns to the cart and I have to repopulate it from a bundle. Everything works fine, except when the user goes straight to the cart and attempts to alter the quantity from there.
Pass interface implementation into the constructor of Adapter as follows :
public SelectionAdapter(ArrayList<SelectionItem> selectionItemArrayList, HashMap<String, Integer> selectionItemsHashMap, int currentTotalAmount,UpdateCartListener updateCartListener ) {
this.selectionItemArrayList = selectionItemArrayList;
this.selectionItemsHashMap = selectionItemsHashMap;
this.totalAmount = currentTotalAmount;
this.updateCartListener = updateCartListener
}
This will provide an implementation of your interface on the initialization of your adapter so it will be not null when you are using it for update cart.
So you try to access the listener inside the ViewHolder which is probably the cause of the crash, what the standard way is setting the OnClickListener inside your adapter
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int position) {
viewHolder.tvSelectItem.setText(selectionItemArrayList.get(position).getSelectionName());
String quantity = Integer.toString(selectionItemArrayList.get(position).getSelectionQuantity());
viewHolder.tvDishQuantity.setText(quantity);
viewHolder.addQuantity.setOnClickListener(new View.OnClickListener() {
...
}
}
You need to instantiate your updateCartListener begfore you use it. Do updateCartListener = new WhatverClassThatImplementsYourInterafce() before you use it or make your method to override Default if you are using Java 8 using the new FunctionalInterface in java.util.Function.
I guess you forget assignment the updateCartListener in your adapter.
SelectionAdapter(selectionItemArrayList, selectionItemsHashMap, totalAmount);
cartItemsHashmap = selectionItemsHashMap;
selectionAdapter.setUpdateCartListener(new SelectionAdapter.OnUpdateCartListener() {
#Override
public void onUpdateCart(int updatedTotalAmount) {
String stringTotalAmount = Integer.toString(updatedTotalAmount);
Log.d(TAG, "received total:" +stringTotalAmount);
tvTotalAmount.setText("$"+ stringTotalAmount);
totalAmount = updatedTotalAmount;
}
});
selectionRecycler.setAdapter(selectionAdapter);
I have two fragments and I am trying to update the recyclerView of the ReceiverFragment via interface. Both fragments have its own adapter (SenderAdapter and ReceiverAdapter).
I have to mention that I also have two SQLDatabase, where group.db is used to populate the SenderFragment and client.db is used to populate the ReceiverFragment.
But ReceiverFragment will only be populate if a CheckBox is ticked in the SenderAdapter.
All the communication between the fragments is ok. When I tick a CheckBox, The SenderAdapter sends a message to MainActivity and the MainActivity sends the same message to ReceiverFragment.
This is SenderFragment:
This would be the desired result.
When I use the message from interface to read the client.db, I get the nullException.
This is the ReceiverFragment:
public class ReceiverFragment extends Fragment {
View view;
private RecyclerView mClientList;
private RecyclerView.Adapter mClientListAdapter;
private RecyclerView.LayoutManager mClientListLayoutManager;
private String receivedFromSender;
ArrayList<ClientObject> clientList;
SQLiteDatabase clientListTable;
ClientRepository clientRepository;
private static String rootPath = Environment.getExternalStorageDirectory()+"/PassKeyBF/";
public ReceiverFragment() {
// Required empty public constructor
}
public String getMessageFromSender(String message){
if (message != null) {
receivedFromSender = message;
Log.i("debinf recfrag", "message from sender (function) is : " + receivedFromSender);
//Log.i("debinf recgfrag", "mContext in interface : " + mContext);
if (message != null) {
if (new File(rootPath + receivedFromSender, "client.db").isFile()) {
clientReading(message);
}
}
}
return null;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_receiver, container, false);
// If I use mContext instead of getContext(), I get rid of the context error showed below.
//mContext = getContext();
clientList = new ArrayList<>();
initializeRecyclerView();
//clientReading("-LWBPaM7RA9UOcUVty79");
return view;
}
private void clientReading(String pathToClientTable) {
if (new File(rootPath + pathToClientTable, "client.db").isFile()) {
Log.i("debinf recgfrag", "mContext in clientReading" + mContext);
ClientDatabaseHelper clientDatabaseHelper = new ClientDatabaseHelper(mContext,"client.db", rootPath+pathToClientTable+"/");
clientListTable = clientDatabaseHelper.getReadableDatabase();
clientRepository = new ClientRepository(clientListTable);
clientList = clientRepository.SearchAllClients();
Log.i("debinf recfrag", "clientList in clientReading is " + clientList.get(0).getName());
mClientListAdapter = new ReceiverAdapter(mContext,clientList);
mClientList.setAdapter(mClientListAdapter);
//mClientListAdapter.notifyDataSetChanged();
}
}
private void initializeRecyclerView() {
mClientList = (RecyclerView) view.findViewById(R.id.clientList);
mClientList.setNestedScrollingEnabled(false);
mClientList.setHasFixedSize(false);
mClientListLayoutManager = new LinearLayoutManager(mContext,LinearLayout.VERTICAL,false);
mClientList.setLayoutManager(mClientListLayoutManager);
mClientListAdapter = new ReceiverAdapter(mContext,clientList);
mClientList.setAdapter(mClientListAdapter);
}
}
This is the ReceiverAdapter
public class ReceiverAdapter extends RecyclerView.Adapter<ReceiverAdapter.ReceiverViewHolder> {
ArrayList<ClientObject> clientList;
Context mContext;
private ReceiverAdapter adapter;
public ReceiverAdapter(Context mContext, ArrayList<ClientObject> clientList) {
this.clientList = clientList;
this.mContext = mContext;
}
#NonNull
#Override
public ReceiverViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_callcenter_client, null, false);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
layoutView.setLayoutParams(lp);
ReceiverViewHolder rcv = new ReceiverViewHolder(layoutView);
return rcv;
}
#Override
public void onBindViewHolder(#NonNull ReceiverViewHolder holder, int position) {
holder.mName.setText(clientList.get(position).getName());
holder.mPhone.setText(clientList.get(position).getPhone());
}
#Override
public int getItemCount() {
return clientList.size();
}
public class ReceiverViewHolder extends RecyclerView.ViewHolder {
public TextView mName, mPhone;
//public LinearLayout mLayout;
public ReceiverViewHolder(#NonNull View itemView) {
super(itemView);
mName = (TextView) itemView.findViewById(R.id.client_name);
mPhone = (TextView) itemView.findViewById(R.id.client_phone);
//mLayout = (LinearLayout) itemView.findViewById(R.id.layoutItemClient);
}
}
}
EDIT
I changed the ReceiverFragment so that it could be more understandable.
That's the FATAL ERROR I get when I use the getContext(). I simply cannot make a connection with my SQLDatabase.
2019-01-31 15:41:45.118 22318-22318/com.example.aliton.passkeybetweenfrags E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.aliton.passkeybetweenfrags, PID: 22318
java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File android.content.Context.getDatabasePath(java.lang.String)' on a null object reference
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:352)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:322)
at com.example.aliton.passkeybetweenfrags.ReceiverFragment.clientReading(ReceiverFragment.java:104)
at com.example.aliton.passkeybetweenfrags.ReceiverFragment.getMessageFromSender(ReceiverFragment.java:53)
at com.example.aliton.passkeybetweenfrags.MainActivity.getMessage(MainActivity.java:64)
at com.example.aliton.passkeybetweenfrags.SenderAdapter$1.onCheckedChanged(SenderAdapter.java:54)
at android.widget.CompoundButton.setChecked(CompoundButton.java:171)
at android.widget.CompoundButton.toggle(CompoundButton.java:127)
at android.widget.CompoundButton.performClick(CompoundButton.java:132)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
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)
Now, when I suppress getContext() and make it static in mContext. I can make a connection with SQLDatabase, but I get this FATAL error because the ReceiverAdapter:
2019-01-31 15:35:05.541 21936-21936/com.example.aliton.passkeybetweenfrags E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.aliton.passkeybetweenfrags, PID: 21936
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
at com.example.aliton.passkeybetweenfrags.ReceiverFragment.clientReading(ReceiverFragment.java:110)
at com.example.aliton.passkeybetweenfrags.ReceiverFragment.getMessageFromSender(ReceiverFragment.java:53)
at com.example.aliton.passkeybetweenfrags.MainActivity.getMessage(MainActivity.java:64)
at com.example.aliton.passkeybetweenfrags.SenderAdapter$1.onCheckedChanged(SenderAdapter.java:54)
at android.widget.CompoundButton.setChecked(CompoundButton.java:171)
at android.widget.CompoundButton.toggle(CompoundButton.java:127)
at android.widget.CompoundButton.performClick(CompoundButton.java:132)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
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)
I can either get an error while reading the SQLDatabase (client.db) or while updating the ReceiverAdapter.
This is the link for the Main folder of the app:
https://1drv.ms/u/s!AjteqjTsJm9qgn6kODT9OJmMcY4e
This is the link to the SQLDatabase (group.db and client.db)
https://1drv.ms/u/s!AjteqjTsJm9qgn_L52cz3lDWOOWe
I finally found an answer.
The whole problem happened in the MainActivity. I was communicating from the MainActivity to the ReceiverFragment like this :
ReceiverFragment receiverFragment = new ReceiverFragment();
And sending the message like this:
#Override
public void getMessage(String message) {
receiverFragment.getMessageFromSender(message);
}
The message was been passed from MainActivity to ReceiverFragment normally, But I was getting a NullPointerException for the recyclerView of the ReceiverFragment.
The problem was solved by using the following way to deliver the message to the ReceiverFragment (answer found in this link https://www.journaldev.com/14207/android-passing-data-between-fragments):
#Override
public void getMessage(String message) {
String tag = "android:switcher:" + R.id.tabs_pager + ":" + 1;
ReceiverFragment rf = (ReceiverFragment) getSupportFragmentManager().findFragmentByTag(tag);
rf.getMessageFromSender(message);
}
The links for the code and the SQLDatabase (group.db and client.db) are still available for download.
For those who are starting in Android like me and interested in the code, please do not forget to change the delivering function in the MainActivity.
Thank you all and good luck!
It show an Null Object error.
When i am fetching an Button Value on card RecylerView
Process: com.softedge.visioneering.tfd, PID: 9884
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
at com.softedge.visioneering.tfd.adapters.MyOrdersAdapter$MyOrdersViewHolder$1.onClick(MyOrdersAdapter.java:138)
at android.view.View.performClick(View.java:5609)
This Is My Adapter and Button Code:
public class MyOrdersViewHolder extends RecyclerView.ViewHolder {
public TextView txtOrderDescription, txtOrderQuantity, txtOrderStatus, txtOrderDate, txtExpectedDate, txtCreatedBy,txtOrderStatus_Per;
String check;
public Button update_btwn;
public MyOrdersViewHolder(View convertView) {
super(convertView);
update_btwn=(Button) convertView.findViewById(R.id.status_update_button);
final FragmentManager fragmentManager = ((FragmentActivity) context).getSupportFragmentManager();
update_btwn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
id = (Integer) update_btwn.getTag();
fragmentManager.beginTransaction().replace(R.id.container, new Status_update_Fragment().newInstance()).addToBackStack(" ").commit();
//((FragmentActivity) context).getSupportFragmentManager().beginTransaction().
// remove(((FragmentActivity) context).getSupportFragmentManager().findFragmentById(R.id.container)).commit();
}
});
I want to perform an Action on Button.
Which is place in Cards RecylerView
Use setTag() in the onBindViewHolder method of your adapter:
#Override
public void onBindViewHolder(myViewHolder viewHolder, int position) {
viewHolder.mCardView.setTag(position);
}
where mCardView is defined in the myViewHolder class.
private class myViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public View mCardView;
public myViewHolder(View view) {
super(view);
mCardView = (CardView) view.findViewById(R.id.card_view);
mCardView.setOnClickListener(this);
}
}
Use getTag() in your OnClickListener implementation:
#Override
public void onClick(View view) {
int position = (int) view.getTag();
//display toast with position of cardview in recyclerview list upon click
Toast.makeText(view.getContext(),Integer.toString(position),Toast.LENGTH_SHORT).show();
}
Did you set the tag on the button?
You can either call .setTag() or in xml android:tag="".
Also, you shouldn't set the click listener in the constructor of the view holder, do it in onBindViewHolder.
I am trying to trigger an mp3 sound to buttons clicks inside a listView. The app compiles ok and generate the APK. But when starts breaks.
This is the activity:
MainActivity.java
public class MainActivity extends Activity {
MediaPlayer player;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//string data
String[] myStringArray={
"ANGUS PREMIUM DELUXE",
"ANGUS PREMIUM BACON",
"CUARTO DE LIBRA CON QUESO",
"DOBLE CUARTO DE LIBRA CON QUESO",
"McNÍFICA",
"TRIPLE MAC",
"BIG MAC",
"McFIESTA",
"HAMBURGUESA CON QUESO",
"HAMBURGUESA"
};
//adapter
ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(
this,
// android.R.layout.simple_list_item_1,
// R.layout.mylayout,
R.layout.mylayout2,
R.id.btnAddItem2,
myStringArray);
//asociate
ListView myList =
(ListView) findViewById(R.id.listView);
assert myList != null;
myList.setAdapter(myAdapter);
//sound
Button btnAddItem = (Button) findViewById(R.id.btnAddItem2);
btnAddItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//player = MediaPlayer.create(MainActivity.this, R.raw.snd_add_payment);
//player.start();
}
});
}
}
This is the layout that contain the repetitive row:
mylayout2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<Button
android:id="#+id/btnAddItem2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="test" />
</LinearLayout>
log with the crash
--------- beginning of crash
06-19 23:53:30.030 2921-2921/moalaiskirulais.com.arrayadapter E/AndroidRuntime: FATAL EXCEPTION: main
Process: moalaiskirulais.com.arrayadapter, PID: 2921
java.lang.RuntimeException: Unable to start activity ComponentInfo{moalaiskirulais.com.arrayadapter/moalaiskirulais.com.arrayadapter.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at moalaiskirulais.com.arrayadapter.MainActivity.onCreate(MainActivity.java:68)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
06-19 23:53:30.075 1565-2093/system_process W/ActivityManager: Force finishing activity moalaiskirulais.com.arrayadapter/.MainActivity
You don't have the button btnAddItem2 in your activity_main.xml.
Add this to activity_main.xml:
<include layout="#layout/mylayout2" />
I think cricket_007 is right. If you want to control views in each items of list, you must make custom class like this:
CustomArrayAdapter
public class CustomArrayAdapter extends ArrayAdapter<String> {
private ArrayList<String> yourList; // for set data to list.
private LayoutInflater inflater = null; // for access your views.
private int layoutResId;
public CustomArrayAdapter(Context c, int resId, ArrayList<String> list) {
super(c, resId);
layoutResId = resId;
yourList = list;
this.inflater = LayoutInflater.from(c);
}
#Override
public int getCount() {
return yourList.size();
}
public void setData(ArrayList<String> list) {
yourList = list;
}
#Override
public view getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View view = convertView;
if (view == null) {
view = this.inflater.inflate(layoutResId, null); // inflate your custom layout for list.
holder = new ViewHolder();
view.setTag(holder);
} else {
holder = (ViewHolder)view.getTag();
}
holder.button = (Button)view.findViewById(R.id.btnAddItem2);
holder.button.setText(yourList.get(position).getName());
holder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// make your button event.
}
});
return view;
}
static class ViewHolder {
private Button button;
}
}
Then, try to set this adapter to your listview.
MainActivity
// custom adapter
ArrayAdapter<String> myAdapter = new CustomArrayAdapter<String>(
MainActivity.this,
R.layout.mylayout2,
myStringArray);
//asociate
ListView myList =
(ListView) findViewById(R.id.listView);
assert myList != null;
myList.setAdapter(myAdapter);