I am creating a recycler view in my app and fetching data from firestore for the same. In the process, I am passing some arguments to the intent which is called when an item in the recycler view is clicked.
RecyclerView recyclerView = findViewById(R.id.my_recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
adapter.setOnItemClickListener(new LearningModuleAdapter.OnItemClickListener() {
#Override
public void onItemClick(DocumentSnapshot documentSnapshot, int position) {
LearningModule learningModule = documentSnapshot.toObject(LearningModule.class);
String id=documentSnapshot.getId();
String path = documentSnapshot.getReference().getPath();
String title = (String) documentSnapshot.get("title");
System.out.println("what did i get from document snapshot? id: "+id+" path:"+path+" title:"+title);
Intent intent = new Intent(learn.this,learn_content.class);
intent.putExtra("title",title);
startActivity(intent);
}
});
The output from the print statements in above code is as follows :
what did i get from document snapshot? id: EsHW9FGjVe8A3pG4 path:LearningModules/EsHW9FGjVe8A3pG4 title:Front Load vs Top Load
The onClick method of the called activity looks like this :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_learn_view_pager);
viewPager = findViewById(R.id.pager);
progressBar = findViewById(R.id.progressBarViewPager);
Bundle extras;
extras = getIntent().getExtras();
System.out.println("captured form the first " + extras.getString("title"));
However, this piece of code throws an error NullPointerException for the print statement.
Where am I going wrong ?
Additional code:
Adapter
public class LearningModuleAdapter extends FirestoreRecyclerAdapter<LearningModule, LearningModuleAdapter.LearningModuleViewHolder> {
private OnItemClickListener listener;
public LearningModuleAdapter(#NonNull FirestoreRecyclerOptions<LearningModule> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull final LearningModuleViewHolder holder, final int position, #NonNull LearningModule model) {
holder.title.setText(model.getTitle());
// holder.img.setImageResource(model.getImg());
}
#NonNull
#Override
public LearningModuleViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType){
View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,false);
return new LearningModuleViewHolder(v);
}
public class LearningModuleViewHolder extends RecyclerView.ViewHolder {
public View view;
public TextView title;
public ImageView img;
public LearningModuleViewHolder(View v) {
super(v);
view = v;
img = itemView.findViewById(R.id.list_image);
title = itemView.findViewById(R.id.list_text_title);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("The click was captured");
int position = getAdapterPosition();
if(position!=RecyclerView.NO_POSITION && null!=listener){
listener.onItemClick(getSnapshots().getSnapshot(position),position);
}
Intent intent = new Intent(view.getContext(), learn_content.class);
view.getContext().startActivity(intent);
}
});
}
}
public interface OnItemClickListener{
void onItemClick(DocumentSnapshot documentSnapshot,int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
this.listener = listener;
}
}
Error Stacktrace
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gigforce.app/com.gigforce.app.learn_content}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
at com.gigforce.app.learn_content.onCreate(learn_content.java:45)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
You are calling startActivity twice that cause the problem.
Option - 1: Try removing inside itemView.setOnClickListener like below :
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("The click was captured");
int position = getAdapterPosition();
if(position!=RecyclerView.NO_POSITION && null!=listener){
listener.onItemClick(getSnapshots().getSnapshot(position),position);
}
//Intent intent = new Intent(view.getContext(), learn_content.class);
//view.getContext().startActivity(intent);
}
});
Option - 2: Try to start activity inside itemView.setOnClickListener and remove OnItemClickListener related code like below :
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("The click was captured");
int position = getAdapterPosition();
/*if(position!=RecyclerView.NO_POSITION && null!=listener){
listener.onItemClick(getSnapshots().getSnapshot(position),position);
}*/
Intent intent = new Intent(view.getContext(), learn_content.class);
DocumentSnapshot documentSnapshot = getSnapshots().getSnapshot(position);
String title = (String) documentSnapshot.get("title");
intent.putExtra("title",title);
view.getContext().startActivity(intent);
}
});
Try this out :
Intent i = getIntent()
if (i == null)
Log.d("***DEBUG****", "Intent was null");
else
Log.d("**** DEBUG ***", "Intent OK");
String title= i.getStringExtra("title"); //Exception points to this line
Log.d("*** DEBUG", rec + " " + title);
Also from itemview click you are not passing title see below
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("The click was captured");
int position = getAdapterPosition();
if(position!=RecyclerView.NO_POSITION && null!=listener){
listener.onItemClick(getSnapshots().getSnapshot(position),position);
}
Intent intent = new Intent(view.getContext(),
learn_content.class);
intent.putExtra("title",title); //This one
view.getContext().startActivity(intent);
}
});
My alternative solution: Instead of putting click listener on LearningModuleViewHolder class put in onCreateViewHolder, so now view will not be null.i will try to add a code here :
#NonNull
#Override
public LearningModuleViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType){
View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,false);
LearningModuleViewHolder holder = new LearningModuleViewHolder(v);
v.setOnClickListener(v -> {
System.out.println("The click was captured");
Intent intent = new Intent(parent.getContext(), learn_content.class);
parent.getContext().startActivity(intent);
});
return holder;
}
Related
I'm creating a pop-up window on button click. But, I'm getting error on getSupportFragmentManager();
public class PrizeList extends AppCompatDialogFragment {
TextView players, prizePoolList, perKill, rank1, rank2, rank3;
SeekBar seekBar;
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.prize_list_layout, null);
builder.setView(view).setTitle("Prize List")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
players = view.findViewById(R.id.players);
prizePoolList = view.findViewById(R.id.prizePoolList);
perKill = view.findViewById(R.id.perKill);
rank1 = view.findViewById(R.id.rank1);
rank2 = view.findViewById(R.id.rank2);
rank3 = view.findViewById(R.id.rank3);
seekBar = view.findViewById(R.id.seekBar);
return builder.create();
}
}
Adapter
holder.prizeList.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openDialog();
Toast.makeText(v.getContext(), "prize list clicked", Toast.LENGTH_SHORT).show();
}
});
}
private void openDialog() {
PrizeList prizeList = new PrizeList();
prizeList.show(prizeList.requireActivity().getSupportFragmentManager(), "Prize");
}
The error I'm getting,
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.luteraa.luteraaesports, PID: 6355
java.lang.NullPointerException: Attempt to invoke virtual method 'androidx.fragment.app.FragmentManager androidx.fragment.app.FragmentActivity.getSupportFragmentManager()' on a null object reference
at com.luteraa.luteraaesports.BGMICategoryAdapter.openDialog(BGMICategoryAdapter.java:93)
at com.luteraa.luteraaesports.BGMICategoryAdapter.access$000(BGMICategoryAdapter.java:25)
at com.luteraa.luteraaesports.BGMICategoryAdapter$1.onClick(BGMICategoryAdapter.java:76)
at android.view.View.performClick(View.java:7191)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View.performClickInternal(View.java:7164)
at android.view.View.access$3500(View.java:821)
at android.view.View$PerformClick.run(View.java:27856)
at android.os.Handler.handleCallback(Handler.java:914)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7551)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)
DataAdapter adapter = new DataAdapter(MainActivity.this,tasks,getSupportFragmentManager());
you can pass the parameter getSupportFragmentManager in
adapter
calling
and get the constructor in getSupportFragmentManager like this
DataAdapter(Context context, List<Task> tasklist,
FragmentManager
supportFragmentManager) {
this.context = context;
this.taskList = tasklist;
this.supportFragmentManager=supportFragmentManager;
}
After pass the object supportFragmentManager in the prizeList
show
method
PrizeList prizeList = new PrizeList();
prizeList.show(supportFragmentManager, "Prize List");
also work in my project so this help to solve your error in
supportFragmentManager
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
Before you mark this duplicate, I did view solution to other similar question but it isn't working. I am getting this error only the first time I run my app.
I am not sure why is this happening. I am calling MainActivity.adapter.notifyDataSetChanged in the Main2Activity (Edit Text Activity). The app crashes when after installing during pressing the back button in the EditText actitvity i.e. Main2Activity.java.
MainActivity:
public class MainActivity extends AppCompatActivity {
ListView notesListView;
static ArrayList<String> notesArrayList;
static ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
notesListView = (ListView) findViewById(R.id.notesListView);
notesArrayList = new ArrayList<String>();
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, notesArrayList);
notesListView.setAdapter(adapter);
Main2Activity.myDb = new DatabaseOperations(this);
if (Main2Activity.myDb != null) {
notesArrayList.clear();
Cursor result = Main2Activity.myDb.getData();
if (result.getCount() == 0) {
Log.i("Error", "error");
return;
}
while (result.moveToNext()) {
notesArrayList.add(result.getString(result.getColumnIndex("text")));
}
}
//notesArrayList.add("Akhilesh Chobey");
notesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(getApplicationContext(), Main2Activity.class);
intent.putExtra("notePosition", i);
startActivity(intent);
}
});
notesListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
return false;
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.add_button) {
notesArrayList.add("");
}
Intent intent = new Intent(getApplicationContext(), Main2Activity.class);
intent.putExtra("notePosition", notesArrayList.size() - 1);
startActivity(intent);
return true;
}
}
Main2Activity (EditText Activity):
public class Main2Activity extends AppCompatActivity implements TextWatcher {
static DatabaseOperations myDb;
EditText editNote;
int position;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
editNote = (EditText) findViewById(R.id.noteEditText);
myDb = new DatabaseOperations(Main2Activity.this);
Intent intent = getIntent();
position = intent.getIntExtra("notePosition", -1);
if(position != -1){
editNote.setText(MainActivity.notesArrayList.get(position));
}
editNote.addTextChangedListener(this);
}
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (myDb != null) {
}
}
#Override
public void afterTextChanged(Editable editable) {
}
#Override
public void onBackPressed(){
myDb.insertData(editNote.getText().toString());
MainActivity.notesArrayList.set(position, editNote.getText().toString());
MainActivity.adapter.notifyDataSetChanged();
this.finish();
}
}
Log:
07-02 18:45:40.402 17500-17500/com.akhileshchobey.mynotes
E/MessageQueue-JNI: java.lang.NullPointerException: Attempt to invoke
virtual method 'void
android.widget.ArrayAdapter.notifyDataSetChanged()' on a null object
reference at
com.akhileshchobey.mynotes.Main2Activity.onBackPressed(Main2Activity.java:70)
at android.app.Activity.onKeyUp(Activity.java:2495) at
android.view.KeyEvent.dispatch(KeyEvent.java:2695) at
android.app.Activity.dispatchKeyEvent(Activity.java:2746) at
android.support.v7.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:533)
at
android.support.v7.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:53)
at
android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.dispatchKeyEvent(AppCompatDelegateImplBase.java:254)
at
com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2221)
at
android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:3918)
at
android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3880)
at
android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449)
at
android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502)
at
android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468)
at
android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3578)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476)
at
android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3635)
at
android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449)
at
android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502)
at
android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476)
at
android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449)
at
android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502)
at
android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468)
at
android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3611)
at
android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:3772)
at
android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2244)
at
android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:1885)
at
android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1876)
at
android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2221)
at
android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141)
at android.os.MessageQueue.nativePollOnce(Native Method) at
android.os.MessageQueue.next(MessageQueue.java:143) at
android.os.Looper.loop(Looper.java:122) at
android.app.ActivityThread.main(ActivityThread.java:5264) at
java.lang.reflect.Method.invoke(Native Method) at
java.lang.reflect.Method.invoke(Method.java:372) at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:900)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:695)
ArrayAdapter.notifyDataSetChanged() is been called BUT ArrayAdapter instance is pointing to a null reference (is not initialized or wrongly initialized...)
in your case it looks like the 2nd option is the cause...
you have this in the code:
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, notesArrayList);
but you need to check the parameters in the constructor
the instance: this
the resourcesin layout: android.R.layout.simple_list_item_1 or the list: notesArrayList
at least one of those is breaking the correct initialization of the adapter, which means, after that line adapter still is null
the consecuence is: calling adapter.notifyDataSetChanged() will throw a NPE
I have Googled a number of possibilities on how to get the item which is clicked in a recycler view but none of them seem to work. The code below should work but I dont understand why its not. In android studio, the getPosition() method is crossed out. I am running out of ideas, Is there a way i can at least toast the name of the recycler view is clicked?
ViewHolder
public class ShoppingListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public CardView cv;
public TextView name;
public TextView description;
Context context;
public ShoppingListViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.cardView);
name = (TextView) itemView.findViewById(R.id.title);
description = (TextView) itemView.findViewById(R.id.description);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("RecyclerView", "onClick:" + getPosition());
}
});
}
public void bindView(int position) {
}
#Override
public void onClick(View v) {
Log.d("TAG", "onClick " + getPosition() + " " + name);
}
Adapter
public class MainShoppingListViewActivity extends AppCompatActivity {
List<Data> list = new ArrayList<>();
RecyclerView recyclerView;
ShoppingListViewAdapter adapter;
Context context;
EditText listName;
Firebase ref;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_shoppinglist_view);
Firebase.setAndroidContext(this);
ref = new Firebase("https://shoppinglistshare.firebaseio.com/");
// Getting the recycler view, using the Recycler View
recyclerView = (RecyclerView) findViewById(R.id.shopping_list_recycler_view);
// The setLayoutManager which contains the main container where the Recycler View is contained
recyclerView.setLayoutManager(new LinearLayoutManager(MainShoppingListViewActivity.this));
// Floating action bar initiated, background color is set and then onClickListener to act when the
// button is pressed to which the createDialogBox(); method is called
FloatingActionButton addFloat = (FloatingActionButton) findViewById(R.id.fab);
addFloat.setBackgroundTintList(ColorStateList.valueOf(Color
.parseColor("#3F51B5")));
addFloat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Click action
createDialogBox();
}
});
}
/*
* This method is used to add a new item to the Recycler View
*/
public void addNewShoppingListItem(String val) {
ref = new Firebase("https://shoppinglistshare.firebaseio.com/");
adapter = new ShoppingListViewAdapter(list, MainShoppingListViewActivity.this);
recyclerView.setAdapter(adapter);
adapter.addItem(new Data(val, "Created by: Me"));
ref.child("List Name: ").setValue(val);
}
/*
* This method is used to add a new item to the Recycler View
*/
public void removeShoppingListItem(String val) {
adapter = new ShoppingListViewAdapter(list, MainShoppingListViewActivity.this);
recyclerView.setAdapter(adapter);
adapter.addItem(new Data(val, "Created by: Me"));
}
/*
* This method is called inside the float action bar to create a dialog box when the floating action button is pressed.
*/
public void createDialogBox() {
// Alert Dialog Builder
AlertDialog.Builder builder = new AlertDialog.Builder(this);
// Using Layout Inflater class and assigned to a variable and using getLayout
LayoutInflater inflater = this.getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout.
// Using the view class to inflate the layout.
View rootView = inflater.inflate(R.layout.custom_alert_dialog, null);
listName = (EditText) rootView.findViewById(R.id.ShoppinglistName);
// Using the AlertDialog Builder created above as "builder" to set the view.
builder.setView(rootView)
.setPositiveButton("Create", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String val = listName.getText().toString();
if (!val.isEmpty()) {
addNewShoppingListItem(val);
} else {
Toast.makeText(MainShoppingListViewActivity.this, "Please enter a value", Toast.LENGTH_SHORT).show();
}
}
})
// Show the dialog
.show();
}
}
Logs
FATAL EXCEPTION: main
Process: familyshopshare.com.familyshopshare, PID: 17889
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
at android.widget.Toast.<init>(Toast.java:102)
at android.widget.Toast.makeText(Toast.java:259)
at familyshopshare.com.familyshopshare.ShoppingListViewHolder$1.onClick(ShoppingListViewHolder.java:33)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
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)
Made small changes, here is the solution i got. I am going to alter the onClick onto another method instead of where it is. If there are any suggestions on how i can make the code better please let me know, any advise is much appreciated :)
public class ShoppingListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public CardView cv;
public TextView name;
public TextView description;
Context context;
public ShoppingListViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.cardView);
name = (TextView) itemView.findViewById(R.id.title);
description = (TextView) itemView.findViewById(R.id.description);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Data test = new Data(name.getText().toString(), description.getText().toString());
Toast.makeText(v.getContext(), "onClick " + test.getName(), Toast.LENGTH_SHORT).show();
Log.d("RecyclerView", "onClick is this:" + getAdapterPosition());
}
});
}
#Override
public void onClick(View v) {
Toast.makeText(context, "onClick " + getAdapterPosition() + " " + name, Toast.LENGTH_SHORT).show();
}
}
There are a few ways you can do it. Personally, I like to set the listener in the onBindViewHolder inside of the adapter class(wherever you have your viewholder):
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.YourTargetObject.setOnClickListener(new View.onClickListener(){
public void onClick(View view){
//do something
}
});
}
I'd like to be able to send an object from parsed JSON data displayed on a RecyclerView to a new activity on click. Below is the relevant code:
I've tried a few solutions but I don't get any results. I've been getting this error:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
at athena.sentineljs.com.athena.RVNewsAdapter$NewsViewHolder.onClick(RVNewsAdapter.java:55)
RVNewsAdapter:
public class RVNewsAdapter extends RecyclerView.Adapter<RVNewsAdapter.NewsViewHolder> {
public static final String KEY_LINK = "link";
public static class NewsViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
private static final String TAG = "Hello";
CardView cv;
TextView date;
TextView link;
TextView title;
TextView today;
List<News> news;
public NewsViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.cv);
date = (TextView) itemView.findViewById(R.id.date);
link = (TextView) itemView.findViewById(R.id.link);
title = (TextView) itemView.findViewById(R.id.heading);
today = (TextView) itemView.findViewById(R.id.today);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
Context context = view.getContext();
Intent intent;
intent = new Intent(context, Details.class);
intent.putExtra("LINK", news.toString());
context.startActivity(intent);
}
}
List<News> news;
RVNewsAdapter(List<News> news) {
this.news = news;
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public RVNewsAdapter.NewsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.itemnewsfeed, viewGroup, false);
NewsViewHolder nvh = new NewsViewHolder(v);
return nvh;
}
#Override
public void onBindViewHolder(NewsViewHolder newsViewHolder, int i) {
newsViewHolder.date.setText(news.get(i).date);
newsViewHolder.link.setText(news.get(i).link);
newsViewHolder.title.setText(news.get(i).title);
newsViewHolder.today.setText(news.get(i).today);
}
#Override
public int getItemCount() {
if (news != null) {
return news.size();
}
return 0;
}
}
Details activity:
public class Details extends AppCompatActivity {
private static final String TAG_LINK = "link";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Intent in = getIntent();
// Get JSON values from previous intent
String link = in.getStringExtra("link");
// Displaying all values on the screen
TextView lblLink = (TextView) findViewById(R.id.link);
lblLink.setText(link);
Log.d("Details", "Data not shown");
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
}
You should send the news object like this
#Override
public void onClick(View view) {
Context context = view.getContext();
Intent intent = new Intent(context, Details.class);
int clickPosition = getAdapterPosition(); // get position of clicked item
News newObject = news.get(clickPosition); // get clicked new object from news(news is an ArrayList)
intent.putExtra("LINK", newObject);
context.startActivity(intent);
}
Also for pass the object via Intent correctly please see this answer
I want to show popupMenu onLongClick in Android, so I write:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
listView = (ListView) findViewById(R.id.listView);
adapter = new MyAdapter(getApplicationContext());
}
#Override
protected void onResume() {
super.onResume();
connectToDatabase();
}
private void connectToDatabase() {
//Create database
listView.setAdapter(adapter);
}
My Adapter:
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
final MyHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_row, null);
holder = new MyHolder();
holder.vocabs = (TextView) convertView.findViewById(R.id.textViewVocabs);
holder.points = (TextView) convertView.findViewById(R.id.textViewPoints);
holder.tick = (ImageButton) convertView.findViewById(R.id.tick);
holder.cross = (ImageButton) convertView.findViewById(R.id.cross);
convertView.setTag(holder);
} else {
holder = (MyHolder) convertView.getTag();
}
holder.id = id.get(position);
holder.vocabs.setText(vocabs.get(position));
holder.points.setText(points.get(position) + "");
holder.tick.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Toast.makeText(parent.getContext(), "Yes... :D ... You learn it :D", Toast.LENGTH_SHORT).show();
points.set(position, points.get(position) + 1);
database.execSQL("UPDATE VOCABS SET POINTS=" + points.get(position) + " WHERE ID=" + id.get(position) + ";");
notifyDataSetChanged();
}
});
holder.cross.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Toast.makeText(parent.getContext(), "Yes... :D ... You learn it :D", Toast.LENGTH_SHORT).show();
if (points.get(position) != 0) {
points.set(position, points.get(position) - 1);
database.execSQL("UPDATE VOCABS SET POINTS=" + points.get(position) + " WHERE ID=" + id.get(position) + ";");
}
notifyDataSetChanged();
}
});
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(parent.getContext(), means.get(position), Toast.LENGTH_LONG).show();
}
});
final View finalConvertView = convertView;
convertView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
//popup-menu for delete item.
PopupMenu popupMenu = new PopupMenu(parent.getContext(),finalConvertView);
popupMenu.getMenuInflater().inflate(R.menu.popup_menu, popupMenu.getMenu());
popupMenu.show();
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getTitle().equals("Delete")) {
database.execSQL("DELETE FROM VOCABS WHERE ID=" + holder.id + ";");
id.remove(position);
vocabs.remove(position);
means.remove(position);
points.remove(position);
notifyDataSetChanged();
}
return false;
}
});
//Toast.makeText(parent.getContext(), "onLongClickFunction! " + position, Toast.LENGTH_LONG).show();
return false;
}
});
return convertView;
}
I work with Itellij IDEA 13.1.4. I add appcompat to supports popup_Menu on APIs older than 11. now when I run application, Everythings are ok. but when Long Click on an item in the listView get below Error:
04-01 15:50:29.749 17078-17078/net.motameni.apps.vocabs_box E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: net.motameni.apps.vocabs_box, PID: 17078
java.lang.RuntimeException: Failed to resolve attribute at index 6
at android.content.res.TypedArray.getLayoutDimension(TypedArray.java:603)
at android.view.ViewGroup$LayoutParams.setBaseAttributes(ViewGroup.java:6423)
at android.view.ViewGroup$MarginLayoutParams.<init>(ViewGroup.java:6591)
at android.widget.FrameLayout$LayoutParams.<init>(FrameLayout.java:735)
at android.widget.FrameLayout.generateLayoutParams(FrameLayout.java:679)
at android.widget.FrameLayout.generateLayoutParams(FrameLayout.java:62)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.support.v7.internal.view.menu.MenuPopupHelper$MenuAdapter.getView(MenuPopupHelper.java:370)
at android.support.v7.internal.view.menu.MenuPopupHelper.measureContentWidth(MenuPopupHelper.java:219)
at android.support.v7.internal.view.menu.MenuPopupHelper.tryShow(MenuPopupHelper.java:153)
at android.support.v7.internal.view.menu.MenuPopupHelper.show(MenuPopupHelper.java:125)
at android.support.v7.widget.PopupMenu.show(PopupMenu.java:193)
at net.motameni.apps.vocabs_box.MainActivity$MyAdapter$4.onLongClick(MainActivity.java:154)
at android.view.View.performLongClick(View.java:4795)
at android.view.View$CheckForLongPress.run(View.java:19723)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
What is wrong???
I suspect you're not getting the correct view when calling PopupMenu constructor.
Change code FROM:
PopupMenu popupMenu = new PopupMenu(parent.getContext(),finalConvertView);
TO:
PopupMenu popupMenu = new PopupMenu(parent.getContext(), v);
I admit maybe it is the same view but depending on the layout design. The suggested code under TO is more accurate. The View parameter v points to a certain row item in ListView.
Please post your menu xml R.menu.popup_menu also.