This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 2 years ago.
When I searched anything it did nothing but when I press button my app get crash and getting error. I don't know know what is wrong.
Main Activity
public class CriminalRecords extends Fragment {
private static final String TAG = "CriminalRecords";
private EditText msearchfield;
private ImageButton msearchbtn;
private FloatingActionButton mFab;
private RecyclerView mResultList;
private DatabaseReference mCriminalDatabase;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.frag_criminal_records, container, false);
msearchfield=view.findViewById(R.id.SearchCriminal);
msearchbtn = view.findViewById(R.id.SearchButton);
mFab = view.findViewById(R.id.AddCriminals);
mResultList = view.findViewById(R.id.Criminal_result_list);
mResultList.setHasFixedSize(true);
mResultList.setLayoutManager(new LinearLayoutManager(getContext()));
mCriminalDatabase = FirebaseDatabase.getInstance().getReference("Criminals");
mFab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent =new Intent(getContext(), Add_Criminals.class);
startActivity(intent);
}
});
msearchbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String searchText = msearchfield.getText().toString();
firebaseSearch(searchText);
}
});
return view;
}
private void firebaseSearch(String searchText) {
Query firebaseSearchQuery = mCriminalDatabase.orderByChild("name").startAt(searchText).endAt(searchText + "\uf8ff");
Log.d(TAG, "firebaseSearch: searching");
FirebaseRecyclerOptions<Criminalupload>options=new FirebaseRecyclerOptions.Builder<Criminalupload>()
.setQuery(firebaseSearchQuery,Criminalupload.class)
.build();
FirebaseRecyclerAdapter<Criminalupload, CriminalViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Criminalupload, CriminalViewHolder>(options)
{
#Override
protected void onBindViewHolder(#NonNull CriminalViewHolder holder, int position, #NonNull Criminalupload model) {
Log.d(TAG, "onBindViewHolder: BindView Active");
holder.setDetails(getActivity().getApplicationContext(),model.getName(),model.getImageid(),model.getAddress1(),model.getAddress2(),model.getAddress3(),model.getMobnum());
Log.d(TAG, "onBindViewHolder: Bindview done");
}
#NonNull
#Override
public CriminalViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return null;
}
};
firebaseRecyclerAdapter.startListening();
Log.d(TAG, "firebaseSearch: setting adapter");
mResultList.setAdapter(firebaseRecyclerAdapter);
Log.d(TAG, "firebaseSearch: addapter set");
}
//View Holder Class
public static class CriminalViewHolder extends RecyclerView.ViewHolder{
View mView;
public CriminalViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setDetails(Context ctx,String CName, String Cimg, String Addres1, String Addres2, String Addres3, Long Mob){
Log.d(TAG, "setDetails: setting details");
TextView cname = (TextView)mView.findViewById(R.id.cProfileName);
TextView caddress1 = (TextView)mView.findViewById(R.id.CriminalAddress);
TextView caddress2 = (TextView)mView.findViewById(R.id.CriminalAddress2);
TextView caddress3 = (TextView)mView.findViewById(R.id.CriminalAddress3);
TextView cmobile = (TextView)mView.findViewById(R.id.CriminalMobile);
CircleImageView cprof = (CircleImageView)mView.findViewById(R.id.cProfileImg);
cname.setText(CName);
caddress1.setText(Addres1);
caddress2.setText(Addres2);
caddress3.setText(Addres3);
cmobile.setText(Math.toIntExact(Mob));
Glide.with(ctx).load(Cimg).into(cprof);
}
}
}
Error
2020-02-22 19:57:17.804 15653-15653/com.example.crimerecords D/AndroidRuntime: Shutting down VM
2020-02-22 19:57:17.805 15653-15653/com.example.crimerecords E/AndroidRuntime:
FATAL EXCEPTION: main
Process: com.example.crimerecords, PID: 15653
java.lang.NullPointerException: Attempt to read from field 'android.view.View androidx.recyclerview.widget.RecyclerView$ViewHolder.itemView' on a null object reference
at androidx.recyclerview.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:7079)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6235)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114)
at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851)
at androidx.recyclerview.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1897)
at androidx.recyclerview.widget.RecyclerView$1.run(RecyclerView.java:414)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949)
at android.view.Choreographer.doCallbacks(Choreographer.java:761)
at android.view.Choreographer.doFrame(Choreographer.java:693)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
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)
2020-02-22 19:57:17.820 15653-15653/com.example.crimerecords I/Process: Sending signal. PID: 15653 SIG: 9
Your onCreateViewHolder method returns null, while it should return a new view holder for the data from the database.
A typical implementation would look something like this:
public CriminalViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.criminal, parent, false);
return new CriminalViewHolder(view);
}
Where R.layout.criminal is the layout that you want to use to show a node from the database.
This is all quite well covered in the FirebaseUI documentation on using the FirebaseRecyclerAdapter, so I recommend spending some time reading that.
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!
I am doing an android project, trying to work with fragment
one of my fragments has a spinner which I need a separate listener for it
when I set the listener I send an object to the constructor as I need this object I don't know why I get null all the time when I call it in the fragment while it's updated in the listener
maybe I have to use another way to pass objects, but I didnt found any
I will be appreciated if you can help me to know why [chosenTrackable] is null in the fragment all the time ?
and if there is a better way to call object between fragments and listeners
here is my code :
public class AddTracking extends Fragment {
Spinner trackableSpinner;
Context context;
HashMap <Integer, MyTrackable> myTrackables ;
MyTrackable chosenTrackable;
private static final String TAG = "AddTracking";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
context = container.getContext();
View view = inflater.inflate(R.layout.fragment_add_tracking, container, false);
myTrackables= new Model(view.getContext()).getTrackables();
//initilizing
trackableSpinner = view.findViewById(R.id.trackable_spinner);
//setup trackable spinner
ArrayAdapter trackableSpinnerAdapter = new ArrayAdapter(this.getActivity(),
android.R.layout.simple_spinner_item, new ArrayList<>(myTrackables.values()));
trackableSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
trackableSpinner.setAdapter(trackableSpinnerAdapter);
trackableSpinner.setOnItemSelectedListener( new SpinnerTrackableItemSelectedListener(this.getActivity(),chosenTrackable));
chosenTrackable = myTrackables.get(trackableSpinner.getSelectedItemPosition());
Log.d(TAG, "onCreateView: " + chosenTrackable);
return view;
}
}
listner:
public class SpinnerTrackableItemSelectedListener implements AdapterView.OnItemSelectedListener {
Context context ;
private static final String TAG = "SpinnerTrackableItemSel";
MyTrackable chosenTrackable;
public SpinnerTrackableItemSelectedListener(Context context, MyTrackable chosenTrackable) {
this.context = context;
this.chosenTrackable = chosenTrackable ;
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
chosenTrackable = (MyTrackable) parent.getAdapter().getItem(position);
Log.d(TAG, "loadTimeSpinner: " + chosenTrackable);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
I am trying to download images using Firebase Storage. I have written the following code
MainActivity.java
public class MainActivity extends AppCompatActivity {
ArrayList<Car> carListSuper;
RecyclerView rvCarList;
ProgressBar progressbar;
private CarListAdapter carListAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
carListSuper = new ArrayList<>();
Firebase myFirebaseRef = new Firebase("https://carbar-7dae7.firebaseio.com/");
rvCarList = (RecyclerView) findViewById(R.id.rvCarList);
rvCarList.setItemAnimator(new FeedItemAnimator());
progressbar = (ProgressBar) findViewById(R.id.progressCarLoad);
carListAdapter = new CarListAdapter(carListSuper,MainActivity.this);
RecyclerView.LayoutManager linearLayoutManager = new LinearLayoutManager(this);
rvCarList.setLayoutManager(linearLayoutManager);
rvCarList.setAdapter(carListAdapter);
myFirebaseRef.child("carList").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Log.i("saz",snapshot.getValue().toString());
progressbar.setVisibility(View.GONE);
carListSuper.clear();
//String jsonString = snapshot.getValue().toString();
try {
for (int i=0; i<snapshot.getChildrenCount();i++) {
//Car carList = gson.fromJson(snapshot.child(i+""), Car.class);
DataSnapshot snap = snapshot.child(i+"");
carListSuper.add(FirebaseParser.carParser(snap));
}
carListAdapter.updatelist(carListSuper);
Log.i("saz",snapshot.getValue().toString());
} catch (Exception e) {
e.printStackTrace();
}
}
#Override public void onCancelled(FirebaseError error) { }
});
}
CarListAdapter.java
public class CarListAdapter<T> extends RecyclerView.Adapter<CarListAdapter.ViewHolder> {
static int i = 0;
private static Context m_context;
List<Car> carList = null;
public static final int VIEW_TYPE_DEFAULT = 1;
public static final int VIEW_TYPE_LOADER = 2;
// Provide a suitable constructor (depends on the kind of dataset)
public CarListAdapter(List<Car> carList, Context context) {
Log.i("saz", "dealerCircularCalls: " + this.carList);
this.carList = carList;
m_context = context;
}
// Create new views (invoked by the layout manager)
#Override
public CarListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.car_item, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
public void updatelist(ArrayList<Car> list) {
ArrayList tempList = new ArrayList();
tempList.addAll(list);
Log.i("saz", "Size on notifyupdate: " + list.size());
carList.clear();
carList.addAll(tempList);
notifyDataSetChanged();
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
Log.i("saz", "position rv: " + position);
/*if (position % 2 != 0) {
holder.cv.setCardBackgroundColor(m_context.getResources().getColor(R.color.lighter_gray));
} else {
holder.cv.setCardBackgroundColor(m_context.getResources().getColor(R.color.white));
}*/
/*CarBarDb db = new CarBarDb(m_context,
CarBarDb.DATABASE_NAME, null, CarBarDb.DATABASE_VERSION);*/
Car car = carList.get(position);
holder.provider.setText("Zoomcar");
holder.carType.setText(car.getCarType());
holder.carName.setText(car.getCarName());
holder.tarrif.setText(car.getPrice_per_hour_weekday());
if (m_context!=null) {
FirebaseStorage storage = FirebaseStorage.getInstance(FirebaseApp.initializeApp(m_context));
StorageReference storageRef = storage.getReferenceFromUrl("gs://carbar-7dae7.appspot.com/");
storageRef.child("CarImages/figo.png").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Picasso.with(m_context).load(uri)
.error(R.drawable.no_image)
.into(holder.imCarImage);
}
});
}
//db.close();
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
Log.i("saz", "carList.size(): " + carList.size());
return carList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
CardView cv;
TextView provider;
TextView carName;
TextView carType;
TextView tarrif;
ImageButton imCarImage;
public ViewHolder(final View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.cvCarItem);
provider = (TextView) cv.findViewById(R.id.tvProvider);
carName = (TextView) cv.findViewById(R.id.tvCarName);
carType = (TextView) cv.findViewById(R.id.tvCarType);
tarrif = (TextView) cv.findViewById(R.id.tvTarrif);
imCarImage = (ImageButton) cv.findViewById(R.id.imgCarImage);
}
}
Still, I am getting the following error.
java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.saz.firebasetest. Make sure to call FirebaseApp.initializeApp(Context) first.
And in main activity, I initialize this adapter as
carListAdapter = new CarListAdapter(carListSuper,MainActivity.this);
I searched on this forum but did not get what is the exact issue. Please help.
Log lines:
FATAL EXCEPTION: main
Process: com.saz.firebasetest, PID: 6991
java.lang.IllegalArgumentException: Null is not a valid value for the FirebaseApp.
at com.google.android.gms.common.internal.zzac.zzb(Unknown Source)
at com.google.firebase.storage.FirebaseStorage.getInstance(Unknown Source)
at com.saz.firebasetest.controller.CarListAdapter.onBindViewHolder(CarListAdapter.java:86)
at com.saz.firebasetest.controller.CarListAdapter.onBindViewHolder(CarListAdapter.java:29)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5768)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5801)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5037)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4913)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2029)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1414)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1377)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:578)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3260)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3069)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3518)
at android.view.View.layout(View.java:16975)
at android.view.ViewGroup.layout(ViewGroup.java:5579)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:396)
at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
at android.view.View.layout(View.java:16975)
at android.view.ViewGroup.layout(ViewGroup.java:5579)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:396)
at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
at android.view.View.layout(View.java:16975)
at android.view.ViewGroup.layout(ViewGroup.java:5579)
at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:433)
at android.view.View.layout(View.java:16975)
at android.view.ViewGroup.layout(ViewGroup.java:5579)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:396)
at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
at android.view.View.layout(View.java:16975)
at android.view.ViewGroup.layout(ViewGroup.java:5579)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:2001)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1844)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1753)
at android.view.View.layout(View.java:16975)
at android.view.ViewGroup.layout(ViewGroup.java:5579)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:396)
at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:2755)
at android.view.View.layout(View.java:16975)
at android.view.ViewGroup.layout(ViewGroup.java:5579)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2552)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2255)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1321)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6737)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:894)
at android.view.Choreographer.doCallbacks(Choreographer.java:696)
at android.view.Choreographer.doFrame(Choreographer.java:631)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:880)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.
--------- beginning of system
You're mixing Firebase SDK versions.
This comes from a Firebase 2.x SDK:
Firebase myFirebaseRef = new Firebase("https://carbar-7dae7.firebaseio.com/");
But Firebase Storage is only included in Firebase 9.x.
You'll need to switch to a single Firebase SDK version. Given that you want to use Firebase Storage, that will be version 9.x.
If you follow the instructions on firebase.google.com, you can see the dependencies for the Database and Storage are:
dependencies {
// ...
compile 'com.google.firebase:firebase-database:9.6.1'
compile 'com.google.firebase:firebase-storage:9.6.1'
}
Whether you use exactly 9.6.1 doesn't matter all that much, but the versions must be the same, while you now likely include the database via compile 'com.firebase:firebase-client-android:2.5.2+'.
Seems you are doing the following:
carListAdapter = new CarListAdapter(carListSuper,MainActivity.this);
That should be the following:
In your activity
Firebase.setAndroidContext(this);
Firebase myFirebaseRef = new Firebase("https://carbar-7dae7.firebaseio.com/");
carListAdapter = new CarListAdapter(carListSuper,this);
and as a suggestion I would not do
FirebaseStorage storage = FirebaseStorage.getInstance(FirebaseApp.initializeApp(m_context));
StorageReference storageRef = storage.getReferenceFromUrl("gs://carbar-7dae7.appspot.com/");
in the onBindViewHolder method. Would do this in the constructor and make it a class variable.
Please add the below line in your adapter's constructor to initialize it not inside bindviewholder method.
FirebaseStorage storage = FirebaseStorage.getInstance(FirebaseApp.initializeApp(m_context));