I can't click the item on recyclerview, I don't know why, so can somebody help me to clear this problem?
so this in my code in MainActivity, and I call this function in onCreate :
private void showRecyclerList(){
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
UserAdapter userAdapter = new UserAdapter(this, userModel);
recyclerView.setAdapter(userAdapter);
userAdapter.setOnItemClickCallback(new UserAdapter.OnItemClickCallback() {
#Override
public void onItemClicked(UserModel data) {
Intent intent = new Intent(MainActivity.this, UserDetailActivity.class);
intent.putExtra(UserDetailActivity.EXTRA_DATA, (Parcelable) userModel);
startActivity(intent);
}
});
}
I used the Interface from OnItemClickCallback and I up it on User Adapter, and this is my UserAdapter:
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ListViewHolder> {
private Context context;
private List<UserModel> userData = new ArrayList<>();
private OnItemClickCallback onItemClickCallback;
public void setOnItemClickCallback(final OnItemClickCallback onItemClickCallback) {
this.onItemClickCallback = onItemClickCallback;
}
public static final String DATA_EXTRA = "data_extra";
public UserAdapter(Context context, List<UserModel> userData) {
this.context = context;
this.userData = userData;
}
#NonNull
#Override
public ListViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_user, parent,false);
return new ListViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ListViewHolder holder, int position) {
//UserModel user = userData.get(position);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onItemClickCallback.onItemClicked(userData.get(holder.getAdapterPosition()));
}
});
Glide.with(context)
.load(userData.get(position).getAvatarUrl())
.into(holder.imgPhoto);
holder.tvName.setText(userData.get(position).getLogin());
}
#Override
public int getItemCount() {
return userData.size();
}
public class ListViewHolder extends RecyclerView.ViewHolder
{
ImageView imgPhoto;
TextView tvName;
public ListViewHolder(View itemView) {
super(itemView);
imgPhoto = itemView.findViewById(R.id.iv_avatar);
tvName = itemView.findViewById(R.id.tv_name);
}
}
public interface OnItemClickCallback {
void onItemClicked(UserModel data);
}
and this is my error message :
java.lang.NullPointerException: Attempt to invoke interface method 'void com.dicoding.githubuserwithapi.UserAdapter$OnItemClickCallback.onItemClicked(com.dicoding.githubuserwithapi.model.UserModel)' on a null object reference
at com.dicoding.githubuserwithapi.UserAdapter$1.onClick(UserAdapter.java:60)
at android.view.View.performClick(View.java:7357)
at android.view.View.performClickInternal(View.java:7334)
at android.view.View.access$3600(View.java:808)
at android.view.View$PerformClick.run(View.java:28200)
at android.os.Handler.handleCallback(Handler.java:907)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7478)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:941)
I/Process: Sending signal. PID: 9602 SIG: 9
I have an error in UserAdapter line 60
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
**onItemClickCallback.onItemClicked(userData.get(holder.getAdapterPosition()));**
}
});
on my UserModel class, there is only the data from the user and I used Parcelable on it.
I think I can't get the position, but I don't know where can I fix it, so can u guys help me with this problem..
When creating LayoutInflater you should use parent.context.
View view = LayoutInflater.from(parent.context).inflate(R.layout.item_user, parent,false);
Why are you calling adapter's getAdapterPosition() if position is already available to you as a parameter of onBindViewHolder()?
onItemClickCallback.onItemClicked(userData.get(position));
When you're defining that click listener you're not using the data you passed to it.
userAdapter.setOnItemClickCallback(new UserAdapter.OnItemClickCallback() {
#Override
public void onItemClicked(UserModel data) {
Intent intent = new Intent(MainActivity.this, UserDetailActivity.class);
intent.putExtra(UserDetailActivity.EXTRA_DATA, (Parcelable) **userModel**);
startActivity(intent);
}
});
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Android Studio Delete Items from Recycler View and List [duplicate]
(2 answers)
Closed 2 years ago.
I am trying to remove Items from my recycler view. Every time I click on an item in my recycler view it provides me with this error.
java.lang.NullPointerException: Attempt to invoke virtual method 'void uk.edu.le.co2103.myrecipebook.RecipeListAdapter.removeItem(int, java.util.List)' on a null object reference
I have made sure that my list has been initalized and used a log to ensure that both position and the list have values in them.
List: [uk.edu.le.co2103.myrecipebook.Recipe#f4d5298, uk.edu.le.co2103.myrecipebook.Recipe#ca6aaf1]
D/MAINÂ ACTIVITY: Index: 0
Here is my Main Activity code
public class MainActivity extends AppCompatActivity implements
RecipeListAdapter.OnItemClickListener {
private static final String TAG = "MAIN ACTIVITY";
private static final int RESULT_UPDATED = 300;
private RecipeViewModel mRecipeViewModel;
public static final int NEW_WORD_ACTIVITY_REQUEST_CODE = 1;
public String Name;
public String Ingredients;
public String Method;
private RecipeListAdapter mAdapter;
private RecipeDao recDao;
Menu menu;
List<Recipe> recipesList = new ArrayList<>();
ListView search_items;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.recyclerview);
RecipeListAdapter mAdapter = new RecipeListAdapter(this);
recyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(MainActivity.this);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecipeViewModel = new ViewModelProvider(this).get(RecipeViewModel.class);
Log.d(TAG, "SIZE OF LIST: "+ recipesList);
mRecipeViewModel.getAllRecipes().observe(this, new Observer<List<Recipe>>() {
#Override
public void onChanged(#Nullable final List<Recipe> recipes) {
// Update the cached copy of the words in the adapter.
int size = mAdapter.getItemCount();
Log.d(TAG, "List of List : " + recipes);
recipesList= recipes;
mAdapter.setWords(recipes);
}
});
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, AddRecipeActivity.class);
startActivityForResult(intent, NEW_WORD_ACTIVITY_REQUEST_CODE);
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == NEW_WORD_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
ArrayList<String> rData = data.getStringArrayListExtra(AddRecipeActivity.EXTRA_REPLY);
String name = rData.get(0);
String ingredients = rData.get(1);
String method = rData.get(2);
Recipe recipe = new Recipe(name, ingredients, method);
RecipeViewModel.insert(recipe);
}
else {
Toast.makeText(
getApplicationContext(),
R.string.empty_not_saved,
Toast.LENGTH_LONG).show();
}
}
#Override
public void onItemClick(int position, View view) {
Log.d(TAG, "onItemClick Position: " + position);
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setTitle("Edit or Delete...");
alertDialog.setPositiveButton("Edit", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
recipesList.get(position); //clicked item
Intent update = new Intent(MainActivity.this, UpdateRecipeActivity.class);
update.putExtra("Name", recipesList.get(position).getName()); //
update.putExtra("Ingredients", recipesList.get(position).getIngredients());
update.putExtra("Method", recipesList.get(position).getMethod());
startActivity(update);
}
});
alertDialog.setNegativeButton("Delete", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Delete
Log.d(TAG, "List: " + recipesList);
Log.d(TAG, "Index: " + position);
int removeIndex = position;
recipesList.remove(removeIndex);
}
});
alertDialog.setNeutralButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
alertDialog.show();
}
Here is my adapter code
public class RecipeListAdapter extends
RecyclerView.Adapter<RecipeListAdapter.RecipeViewHolder> {
private static final String TAG = "ADAPTER";
private OnItemClickListener mListener;
public interface OnItemClickListener{
void onItemClick(int position, View view);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
class RecipeViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final TextView recipeItemView;
private RecipeViewHolder(View itemView) {
super(itemView);
recipeItemView = itemView.findViewById(R.id.textView);
itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (mListener != null){
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION){
mListener.onItemClick(position, v);
}
}
}
});
}
#Override
public void onClick(View view) {
mListener.onItemClick(getAdapterPosition(), view);
}
}
private final LayoutInflater mInflater;
private List<Recipe> mRecipes; // Cached copy of words
RecipeListAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
#Override
public RecipeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(R.layout.recyclerview_item, parent, false);
return new RecipeViewHolder(itemView);
}
#Override
public void onBindViewHolder(RecipeViewHolder holder, int position) {
if (mRecipes != null) {
Recipe current = mRecipes.get(position);
holder.recipeItemView.setText(current.getName());
} else {
// Covers the case of data not being ready yet.
holder.recipeItemView.setText("No Recipes");
}
}
void setWords(List<Recipe> recipes){
mRecipes = recipes;
notifyDataSetChanged();
}
public void deleteItem(final int position) {
mRecipes.remove(position);
notifyItemRemoved(position);
}
#Override
public int getItemCount() {
if (mRecipes != null)
return mRecipes.size();
else return 0;
}
public interface OnNoteListener{}
}
Here is the full error output
2020-04-02 15:27:30.553 5522-5522/uk.edu.le.co2103.myrecipebook E/AndroidRuntime: FATAL EXCEPTION: main
Process: uk.edu.le.co2103.myrecipebook, PID: 5522
java.lang.NullPointerException: Attempt to invoke virtual method 'void uk.edu.le.co2103.myrecipebook.RecipeListAdapter.deleteItem(int)' on a null object reference
at uk.edu.le.co2103.myrecipebook.MainActivity$4.onClick(MainActivity.java:133)
at androidx.appcompat.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7464)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:955)
I changed your adapter. I found some problems :
public class RecipeListAdapter extends
RecyclerView.Adapter<RecipeListAdapter.RecipeViewHolder> {
private static final String TAG = "ADAPTER";
private OnItemClickListener mListener;
public interface OnItemClickListener{
void onItemClick(int position, View view);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
class RecipeViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final TextView recipeItemView;
private RecipeViewHolder(View itemView) {
super(itemView);
recipeItemView = itemView.findViewById(R.id.textView);
itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (mListener != null){
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION){
mListener.onItemClick(position, v);
}
}
}
});
}
#Override
public void onClick(View view) {
mListener.onItemClick(getAdapterPosition(), view);
}
}
private final LayoutInflater mInflater;
private List<Recipe> mRecipes; // Cached copy of words
RecipeListAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
#Override
public RecipeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(R.layout.recyclerview_item, parent, false);
return new RecipeViewHolder(itemView);
}
#Override
public void onBindViewHolder(RecipeViewHolder holder, int position) {
if (mRecipes != null) {
Recipe current = mRecipes.get(position);
holder.recipeItemView.setText(current.getName());
} else {
// Covers the case of data not being ready yet.
holder.recipeItemView.setText("No Recipes");
}
}
void setWords(List<Recipe> recipes){
mRecipes = recipes;
notifyDataSetChanged();
}
public void deleteItem(final int position) {
mRecipes.remove(position);
notifyItemRemoved(position);
}
#Override
public int getItemCount() {
if (mRecipes != null)
return mRecipes.size();
else return 0;
}
public interface OnNoteListener{}
}
you can use it
public void deleteItem(final int position) {
recipeList.remove(position);
notifyDataSetChanged();
}
Tried using recycler view inside recycler view the first adapter works fine but the second adapter never runs
tired fixing it over and over nothing works....help
The second recycler view is retrieving data from Firebase
The Data from firebase is received but never set to the required text views.
Activity
public class ScheduleOrder extends AppCompatActivity implements IFirebaseLoadListener {
DeviceSession deviceSession;
UserSession userSession;
String Device_Id="",User_Id="";
MyItemAdapter myItemAdapter;
IFirebaseLoadListener iFirebaseLoadListener;
List<String> Name;
List<ItemData>itemData;
ItemData itemData1;
RecyclerView my_recycler_view;
DatabaseReference myData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_schedule_order);
itemData1=new ItemData();
deviceSession = new DeviceSession(getApplicationContext());
Device_Id = deviceSession.getDeviceDetails();
userSession = new UserSession(getApplicationContext());
final HashMap<String, String> user = userSession.getUserDetails();
User_Id = user.get(UserSession.User_Id);
FloatingActionButton myFab = (FloatingActionButton)findViewById(R.id.schedule_add);
myFab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(),Schedule_Order.class);
startActivity(i);
finish();
}
});
myData=FirebaseDatabase.getInstance().getReference("Cart_Schedule"+"/"+Device_Id);
iFirebaseLoadListener=this;
my_recycler_view=findViewById(R.id.my_recyclr_view);
my_recycler_view.setHasFixedSize(true);
// my_recycler_view1.setHasFixedSize(true);
my_recycler_view.setLayoutManager(new LinearLayoutManager(this));
// my_recycler_view1.setLayoutManager(new LinearLayoutManager(this));
getFirebaseData();
}
private void getFirebaseData() {
myData.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
List<ItemGroup>itemGroups=new ArrayList<>();
Name=new ArrayList<>();
for(DataSnapshot groupSnapShot:dataSnapshot.getChildren()){
ItemGroup itemGroup=new ItemGroup();
itemGroup.setD_Time(groupSnapShot.child("d_Time").getValue(true).toString());
itemGroup.setF_Amount(groupSnapShot.child("f_Amount").getValue(true).toString());
for(DataSnapshot newdatasnap:groupSnapShot.child("listItem").getChildren()){
itemData1.setA_Item_name(newdatasnap.child("a_Item_name").getValue().toString());
itemData1.setB_Quantity(newdatasnap.child("b_Quantity").getValue().toString());
itemData1.setC_Price(newdatasnap.child("b_Quantity").getValue().toString());
Name.add(newdatasnap.child("a_Item_name").getValue().toString());
Name.add(newdatasnap.child("c_Price").getValue().toString());
Name.add(newdatasnap.child("b_Quantity").getValue().toString());
Log.d("JADOO", "onDataChange: ??? "+itemData1.getA_Item_name());
Log.d("JADOO", "onDataChange: ??? "+itemData1.getB_Quantity());
Log.d("JADOO", "onDataChange: ??? "+itemData1.getC_Price());
Log.d("JADOO", "onDataChange: ??? "+Name);}
Log.d("JADOO", "onDataChange: ====================================================");
itemGroups.add(itemGroup);
Name.clear();
}
iFirebaseLoadListener.onFirebaseLoadSuccess(itemGroups);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
iFirebaseLoadListener.onFirebaseLoadFailed(databaseError.getMessage());
}
});
}
#Override
public void onFirebaseLoadSuccess(List<ItemGroup> itemGroupList) {
Log.d("JADOO", "onDataChange: Setting Adapter");
MyItemGroupAdapter adapter = new MyItemGroupAdapter(ScheduleOrder.this,itemGroupList,itemData1);
my_recycler_view.setAdapter(adapter);
}
#Override
public void onFirebaseLoadFailed(String message) {
}
}
First Adapter Java file
public class MyItemGroupAdapter extends RecyclerView.Adapter<MyItemGroupAdapter.MyViewHolder> {
private Context context;
private List<ItemGroup>dataList;
private ItemData name;
public MyItemGroupAdapter(Context context, List<ItemGroup> dataList,ItemData data) {
this.context = context;
this.dataList = dataList;
this.name=data;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView=LayoutInflater.from(context).inflate(R.layout.tempcartlayout,viewGroup,false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolder myViewHolder, int i) {
MyItemAdapter itemListAdapter = new MyItemAdapter(context,name);
myViewHolder.timee.setText(dataList.get(i).getD_Time());
myViewHolder.cost.setText(dataList.get(i).getF_Amount());
Log.d("JADOO", "onDataChange: IN MY ITEM GRP ADAPTER "+name.getA_Item_name());
myViewHolder.recycler_view_item_list.setHasFixedSize(true);
myViewHolder.recycler_view_item_list.setLayoutManager(new CustomLinearLayoutManager(context,LinearLayoutManager.VERTICAL,false));
myViewHolder.recycler_view_item_list.setAdapter(itemListAdapter);
myViewHolder.recycler_view_item_list.setNestedScrollingEnabled(false);
myViewHolder.can.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, "Button More : "+myViewHolder.timee.getText()+" -- "+myViewHolder.cost.getText(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return (dataList != null ? dataList.size() : 0);
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView timee,cost;
Button can;
RecyclerView recycler_view_item_list;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
timee=itemView.findViewById(R.id.reorder_time);
cost=itemView.findViewById(R.id.reorder_cost);
can=itemView.findViewById(R.id.button);
Log.d("JADOO", "onDataChange: VIEW HOLDER ");
recycler_view_item_list=itemView.findViewById(R.id.schedulecart);
}}}
Second Adapter File
private Context context;
private ItemData name123;
public MyItemAdapter(Context context, ItemData Item_Name) {
this.context = context;
this.name123=Item_Name;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView= LayoutInflater.from(context).inflate(R.layout.cart_list_layout,viewGroup,false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, final int i) {
Log.d("JADOO", "onBindViewHolder: IN MY ITEM ADAPTER");
ItemData itemData=new ItemData();
myViewHolder.m_name.setText(itemData.getA_Item_name());
myViewHolder.m_cost.setText(itemData.getC_Price());
myViewHolder.m_quant.setText(itemData.getB_Quantity());
}
#Override
public int getItemCount() {
return 0;
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView m_name,m_quant,m_cost;
IItemClickListener iItemClickListener;
public void setiItemClickListener(IItemClickListener iItemClickListener){
this.iItemClickListener=iItemClickListener;
}
public MyViewHolder(#NonNull View itemView) {
super(itemView);
m_name=itemView.findViewById(R.id.tv_menu_name1);
m_quant=itemView.findViewById(R.id.quantity);
m_cost=itemView.findViewById(R.id.amount);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
iItemClickListener.onItemClickListener(view,getAdapterPosition());
}}}
Error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.food.pilo, PID: 28457
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.food.pilo.ScheduleOrder.onFirebaseLoadSuccess(ScheduleOrder.java:161)
at com.food.pilo.ScheduleOrder$2.onDataChange(ScheduleOrder.java:143)
at com.google.firebase.database.Query$1.onDataChange(com.google.firebase:firebase-database##16.0.4:183)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database##16.0.4:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database##16.0.4:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database##16.0.4:55)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7156)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)```
Your return value is 0 in Second adapter. Please add arraylist to second adapter.
#Override
public int getItemCount() {
return 0;
}
I think my_recycler_view=findViewById(R.id.my_recyclr_view); or
findViewById(R.id.schedulecart); returning null please check on these lines.
I know there are questions like this, but non solving mine..
I'm trying to make 'OnItemClickListener' of 'RecyclerView' , but when I run the app it stops..
can you tell me where is the error??
Here is the code: (Note the error is in making the item clickable)
public class TeacherActivity extends AppCompatActivity {
private FirebaseAuth mAuth=FirebaseAuth.getInstance();
private FirebaseUser currentUser= mAuth.getCurrentUser();;
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private String UserId =currentUser.getUid();
private static String city;
private TeacherAdapter teacherAdapter;
public static final String EXTRA_PATH = "com.example.exercise.EXTRA_PATH";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_teacher);
setUpRecyclerView();
teacherAdapter.setOnItemClickListener(new TeacherAdapter.OnItemClickListener() {
#Override
public void onItemClick(DocumentSnapshot documentSnapshot, int position) {
String path = documentSnapshot.getReference().getPath();
Intent intent = new Intent(TeacherActivity.this, SecondActivity.class);
intent.putExtra(EXTRA_PATH, path);
startActivity(intent);
}
});
}// end of onCreate
private void setUpRecyclerView(){
Query query = db.collection("Teachers");
FirestoreRecyclerOptions < Teacher > options = new
FirestoreRecyclerOptions.Builder<Teacher>()
.setQuery(query, Teacher.class)
.build();
teacherAdapter = new TeacherAdapter(options);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true); //for performane reasons
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(teacherAdapter);
teacherAdapter.startListening();
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onStop() {
super.onStop();
teacherAdapter.stopListening();
}
}// end of class
And this is the 'adapter' of 'RecyclerView':
public class TeacherAdapter extends FirestoreRecyclerAdapter<Teacher,
TeacherAdapter.TeacherHolder> {
private OnItemClickListener listener;
public TeacherAdapter(#NonNull FirestoreRecyclerOptions<Teacher> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull TeacherHolder holder, int i, #NonNull Teacher
teacher) {
holder.tv_teacher_name.setText(teacher.getName());
holder.tv_cv.setText(teacher.getCv());
}
#NonNull
#Override
public TeacherHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.teacher_item, parent, false);
return new TeacherHolder(v);
}
class TeacherHolder extends RecyclerView.ViewHolder {
TextView tv_teacher_name;
TextView tv_cv;
public TeacherHolder(#NonNull View itemView) {
super(itemView);
tv_teacher_name = itemView.findViewById(R.id.teacher_name);
tv_cv = itemView.findViewById(R.id.tv_cv);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION && listener != null){
listener.onItemClick(getSnapshots().getSnapshot(position), position);
}
}
});
}
}
public interface OnItemClickListener{
void onItemClick(DocumentSnapshot documentSnapshot, int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
this.listener = listener;
}
}
Part of logcat:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.exercise, PID: 29966
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.exercise/com.example.exercise.TeacherActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.exercise.TeacherAdapter.setOnItemClickListener(com.example.exercise.TeacherAdapter$OnItemClickListener)' on a null object reference
You are getting the following error:
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.exercise, PID: 29966 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.exercise/com.example.exercise.TeacherActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.exercise.TeacherAdapter.setOnItemClickListener(com.example.exercise.TeacherAdapter$OnItemClickListener)' on a null object reference
Because you are calling .setOnItemClickListener() on your teacherAdapter object which is null at that point in time. To solve this, you should simply move the following block of code:
teacherAdapter.setOnItemClickListener(new TeacherAdapter.OnItemClickListener() {
#Override
public void onItemClick(DocumentSnapshot documentSnapshot, int position) {
String path = documentSnapshot.getReference().getPath();
Intent intent = new Intent(TeacherActivity.this, SecondActivity.class);
intent.putExtra(EXTRA_PATH, path);
startActivity(intent);
}
});
Right after the declaration of your adapter:
teacherAdapter = new TeacherAdapter(options);
In your setUpRecyclerView() method and your problem will be solved.
I have a RecyclerView that shows a list of student details. The issue I face is when I click on the first item it returns the data of the second item.
I believe that it has something to do with getAdapterPosition(), but I'm not sure.
In this case, it returns the Roll No. of the second student(item) when the first student is selected.
Any help is appreciated
RecyclerViewAdapter
public class StudentAdapter extends RecyclerView.Adapter<StudentAdapter.ViewHolder> {
Context context;
public List<StudentDataModel> dataModels;
public StudentDataModel dataAdapter;
public StudentAdapter(List<StudentDataModel> getDataAdapter, Context context){
super();
this.dataModels = getDataAdapter;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.student, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(final StudentAdapter.ViewHolder viewHolder, final int position) {
dataAdapter = dataModels.get(position);
viewHolder.NameStudentCard.setText(dataAdapter.getName());
viewHolder.RankStudentCard.setText(dataAdapter.getRank());
viewHolder.RollStudentCard.setText(dataAdapter.getRoll());
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
notifyDataSetChanged();
Toast.makeText(v.getContext(), "Tapped on" + dataAdapter.getRoll(), Toast.LENGTH_SHORT).show(); //Here it returns the Roll No. of the second student(item) in the recyclerView.
Intent intent = new Intent (v.getContext(), StudentDetailsActivity.class);
v.getContext().startActivity(intent);
}
});
}
class ViewHolder extends RecyclerView.ViewHolder{
public TextView NameStudentCard;
public TextView RankStudentCard;
public TextView RollStudentCard;
public ViewHolder(View itemView) {
super(itemView);
NameStudentCard=(TextView)itemView.findViewById(R.id.textViewName);
RankStudentCard=(TextView)itemView.findViewById(R.id.textViewRank);
RollStudentCard =(TextView)itemView.findViewById(R.id.textViewEmployeeID);
}
}
#Override
public int getItemCount() {
return dataModels.size();
}
}
Yes, because you are declaring object as global object. So it is getting update with last visible row's object, because onBindViewHolder() gets called for each visible row sequentially. So it will work properly only for last visible row.
So you need to declare it inside method :
comment this :
// public StudentDataModel dataAdapter;
declare it here :
#Override
public void onBindViewHolder(final StudentAdapter.ViewHolder viewHolder, final int position) {
final StudentDataModel dataAdapter = dataModels.get(position); // add this here
}
public class StudentAdapter extends RecyclerView.Adapter<StudentAdapter.ViewHolder> {
Context context;
public List<StudentDataModel> dataModels;
public StudentAdapter(List<StudentDataModel> getDataAdapter, Context context){
super();
this.dataModels = getDataAdapter;
this.context = context;
}
public StudentDataModel dataAdapter;
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.student, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(final StudentAdapter.ViewHolder viewHolder, final int position) {
dataAdapter = dataModels.get(position);
viewHolder.NameStudentCard.setText(dataAdapter.getName());
viewHolder.RankStudentCard.setText(dataAdapter.getRank());
viewHolder.RollStudentCard.setText(dataAdapter.getRoll());
}
#Override
public int getItemCount() {
return dataModels.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
public TextView NameStudentCard;
public TextView RankStudentCard;
public TextView RollStudentCard;
public ViewHolder(View itemView) {
super(itemView);
NameStudentCard=(TextView)itemView.findViewById(R.id.textViewName);
RankStudentCard=(TextView)itemView.findViewById(R.id.textViewRank);
RollStudentCard =(TextView)itemView.findViewById(R.id.textViewEmployeeID);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Tapped on" + dataModels.get(getAdapterPosition()).getRoll(), Toast.LENGTH_SHORT).show();
Intent intent = new Intent (v.getContext(), StudentDetailsActivity.class);
v.getContext().startActivity(intent);
}
});
}
}
}
Try this code..
make interface into adapter class for click handling like this way..
onItemClickListner onItemClickListner;
public void setOnItemClickListner(RecyclerViewAdpater.onItemClickListner onItemClickListner) {
this.onItemClickListner = onItemClickListner;
}
public interface onItemClickListner{
void onItemClick(String data); // pass any data;
}
#Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
// below code handle click event on recycler view item.
String data=mStringList.get(position);
holder.textView.setText(data);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onItemClickListner.onItemClick(data); //pass your data;
}
});
}
after that bind adapter into recyclerview and adapter not null then called below code..
recyclerViewAdpater.setOnItemClickListner(new RecyclerViewAdpater.onItemClickListner() {
#Override
public void onItemClick(String data) {
// perform your operation.
recyclerViewAdpater.notifyDataSetChanged();
}
});
I want to pass data from onclick recycler view main activity to other activity(exoplayer).
I created onimageclicklistener class and then I declared my onimageclicklistener in the adapter class. Then I implement that listener in main activity and implemented on image click method, now I am blank and do not know what do.
I will appreciate if someone helps.
interface class:
public interface OnImageClickListener
{
void onImageClick(String imageData);
}
adapter:
public class SongAdapter extends RecyclerView.Adapter {
private Context context;
private List<Datum> datums;
//imagelistener define
private OnImageClickListener onImageClickListener;
//3rd argument is listener
public SongAdapter(Context context, List<Datum> datums, OnImageClickListener onImageClickListener) {
this.context = context;
this.datums = datums;
this.onImageClickListener = onImageClickListener;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Datum datum = datums.get(position);
Glide.with(context).load(datums.get(position).getThumbnail()).into(holder.thumbnail);
holder.title.setText(datum.getTitle());
holder.artist.setText(datum.getArtist());
// holder.duration.setText(datum.getDuration());
holder.duration.setText(Integer.toString(datum.getDuration()));
//imageview interface pass
holder.thumbnail.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onImageClickListener.onImageClick(datum.getUrl());
}
});
}
#Override
public int getItemCount() {
return datums.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView thumbnail;
TextView title;
TextView artist;
TextView duration;
public ViewHolder(#NonNull View itemView) {
super(itemView);
thumbnail = (ImageView) itemView.findViewById(R.id.thumbnail);
title = (TextView) itemView.findViewById(R.id.title);
artist = (TextView) itemView.findViewById(R.id.artist);
duration = (TextView) itemView.findViewById(R.id.duration);
}
}
}
Mainactivity:
//imageclick listener
#Override
public void onImageClick(String imageData) {
Intent i = new Intent(MainActivity.this,exoplayer.class);
startActivity(i);
}
I want to send data to exoplayer class.
Using Intent Extras
#Override
public void onImageClick(String imageData) {
Intent i = new Intent(MainActivity.this,exoplayer.class);
intent.putExtra("YOUR_KEY_STRING", imageDate);
startActivity(i);
}
And then from exoplayer Activity, you retrieve it in the onCreate() method as follows :
String imageData = getIntent().getStringExtra("YOUR_KEY_STRING");
Using bundle
#Override
public void onImageClick(String imageData) {
Intent i = new Intent(MainActivity.this,exoplayer.class);
Bundle bundle = new Bundle();
bundle.putString("imageDataKey", imageData);
intent.putExtra("YOUR_BUNDLE_KEY", bundle);
startActivity(i);
}
And then from your exoactivity you retrieve it as follows :
if (getIntent().getExtras() != null) {
Bundle bundle = getIntent().getStringExtra("YOUR_BUNDLE_KEY");
String imageData = bundle.getString("imageDataKey");
}
Using intent we can send data
//imageclick listener
#Override
public void onImageClick(String imageData) {
Intent i = new Intent(MainActivity.this,exoplayer.class);
i.putExtra("data",imageData);
startActivity(i);
}