In FirebaseRecyclerAdapter I can use the getRef(position).getKey() but I am using a RecyclerView.Adapter and I want get the key whenever the user click the checkbox. Here is my code in onBindViewHolder():
#Override
public void onBindViewHolder(#NonNull UsersViewHolders holder, final int position) {
holder.setName(mUserNameList.get(position));
holder.setDesc(mUserDescList.get(position));
holder.setImage(mUserPicList.get(position));
holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//TODO: get the key
}
});
}
Is it possible to get the key in RecyclerView.Adapter?
I manage to solved my own question just by reconstructing my code.
1. In the adapter class, I created an interface for itemClickListener
public interface RecyclerViewItemClick {
public void OnItemClickListener(UsersViewHolders holder, int position);
}
and create a global
private RecyclerViewItemClick mListener;
add it to constructor
public MessageListAdapter(RecyclerViewItemClick listener) {
this.mListener = listener;
}
2. In onBindViewHolder() I passed the holder and the position
#Override
public void onBindViewHolder(#NonNull final UsersViewHolders holder, final int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mListener.OnItemClickListener(holder, position);
}
});
}
3. In your activity, add this code. Declare a global variable for ArrayList to store the keys and call the addListenerForSingleValueEvent to your DatabaseReference
//mUserDatabase is a DatabaseReference
mUserDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot datas : dataSnapshot.getChildren()) {
String uid = datas.getKey();
//mUserKey is an ArrayList<String>
mUserKey.add(uid);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
4. Now add this to get the key for every position
mAdapter = new MyAdapter(new MyAdapter.RecyclerViewItemClick() {
#Override
public void OnItemClickListener(PickMemberAdapter.UsersViewHolders holder, int position) {
String userKey = mUserKey.get(position);
if (!holder.mCheckBox.isChecked()) {
holder.mCheckBox.setChecked(true);
Toast.makeText(MainActivity.this, userKey, Toast.LENGTH_LONG).show();
} else {
holder.mCheckBox.setChecked(false);
Toast.makeText(MainActivity.this, userKey, Toast.LENGTH_LONG).show();
}
}
});
Related
Basically the app it's just a simple to do list, but when I add new task to do, it appears on firebase, but not on my app, giving the error
"E/RecyclerView: No adapter attached; skipping layout".
I tried to fix it following the answers here on stackoverflow but none of them helped me, probably I was wrong to adapt the adjustments to my code. I'm just learning and this is my first project, I was following a tutorial to do it.
Anyway, this is the MainActivity.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonadd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
Intent a = new Intent(MainActivity.this, AggiungiPiattoAttivity.class);
startActivity(a);
}
});
//working with data
ourdoes = findViewById(R.id.ourdoes);
ourdoes.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<MyDoes>();
//get data from firebase
reference = FirebaseDatabase.getInstance(URL).getReference().child("AppLista");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//set code to retrive data and replace layout
for (DataSnapshot dataSnapshot1: dataSnapshot.getChildren())
{
MyDoes p = dataSnapshot1.getValue(MyDoes.class);
list.add(p);
}
doesAdapter = new DoesAdapter(MainActivity.this, list);
ourdoes.setAdapter(doesAdapter);
doesAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
//set code to show an error
Toast.makeText(getApplicationContext(), "No Data", Toast.LENGTH_SHORT).show();
}
});
}
This is the class where I add a new to do task:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aggiungi_piatto_attivity);
buttonaddnewpiatto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//insert data to database
reference = FirebaseDatabase.getInstance(URL).getReference().child("BoxDoese").child("Does" + doesNum);
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
dataSnapshot.getRef().child("titledoes").setValue(addnamenewpiattosetted.getText().toString());
dataSnapshot.getRef().child("descdoes").setValue(adddescnewpiattosetted.getText().toString());
dataSnapshot.getRef().child("qualcosaalpostodiunimmagine").setValue(addrecipenewpiattosetted.getText().toString());
Intent a = new Intent( AggiungiPiattoAttivity.this, MainActivity.class);
startActivity(a);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
});
This is my adapter class:
public class DoesAdapter extends RecyclerView.Adapter<DoesAdapter.MyViewHolder> {
Context context;
ArrayList<MyDoes> myDoes;
public DoesAdapter(){
}
public DoesAdapter(Context c, ArrayList<MyDoes> p ){
context = c;
myDoes=p;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_does, viewGroup, false));
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.titledoes.setText(myDoes.get(i).getTitledoes());
myViewHolder.qualcosaalpostodiunimmagine.setText(myDoes.get(i).getQualcosaalpostodiunimmagine());
myViewHolder.descdoes.setText(myDoes.get(i).getDescdoes());
}
#Override
public int getItemCount() {
return myDoes.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView titledoes, descdoes, qualcosaalpostodiunimmagine;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
titledoes = (TextView) itemView.findViewById(R.id.titledoes);
qualcosaalpostodiunimmagine = (TextView) itemView.findViewById(R.id.qualcosaalpostodiunimmagine);
descdoes = (TextView) itemView.findViewById(R.id.descdoes);
}
}
}
I also have other classes but to not put too much code I avoid to put them, they should not be relevant.
Create an empty adapter the same time you set LayoutManager for the RecyclerView: Save it as field of your class:
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
doesAdapter = new DoesAdapter(MainActivity.this, list);
recyclerView.setAdapter(DoesAdapter);
When data is ready, populate the adapter and notify:
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
/// origin code here
for (DataSnapshot dataSnapshot1: dataSnapshot.getChildren())
{
MyDoes p = dataSnapshot1.getValue(MyDoes.class);
list.add(p);
}
// reset data in adapter and not re-creating adapter:
doesAdapter.setItems(list);
doesAdapter.notifyDataSetChanged();
// instead of doesAdapter = new DoesAdapter(MainActivity.this, list);
recyclerView.setAdapter(DoesAdapter);
}
Source: https://stackoverflow.com/a/58251986/12596713
I am having this error while deleting an image from application
E/InputEventReceiver: Exception dispatching input event.
E/MessageQueue-JNI: Exception in MessageQueue callback:
handleReceiveCallback E/MessageQueue-JNI:
java.lang.IllegalArgumentException: The storage Uri could not be
parsed.
This i my code i write it for deletion
Images_Actvity.java:
public class Images_Avctivity extends AppCompatActivity implements Image_adapter.OnItemClickListener {
private RecyclerView mRecyclerView;
private Image_adapter mAdapter;
private ProgressBar mProgressCircle;
private FirebaseStorage mStorage;
private DatabaseReference mDatabaseRef;
private ValueEventListener mDBListener;
private List<Upload> mUploads;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_images__avctivity);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mProgressCircle = findViewById(R.id.progress_circle);
mUploads = new ArrayList<>();
mAdapter = new Image_adapter(Images_Avctivity.this, mUploads);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(Images_Avctivity.this);
mStorage = FirebaseStorage.getInstance();
mDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads");
mDBListener = mDatabaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mUploads.clear();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Upload upload = postSnapshot.getValue(Upload.class);
upload.setKey(postSnapshot.getKey());
mUploads.add(upload);
}
mAdapter.notifyDataSetChanged();
mProgressCircle.setVisibility(View.INVISIBLE);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(Images_Avctivity.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
mProgressCircle.setVisibility(View.INVISIBLE);
}
});
}
#Override
public void onItemClick(int position) {
Toast.makeText(this, "Normal click at position: " + position, Toast.LENGTH_SHORT).show();
}
#Override
public void onWhatEverClick(int position) {
Toast.makeText(this, "Whatever click at position: " + position, Toast.LENGTH_SHORT).show();
}
#Override
public void onDeleteClick(int position) {
Upload selectedItem = mUploads.get(position);
final String selectedKey = selectedItem.getKey();
StorageReference imageRef = mStorage.getReferenceFromUrl(selectedItem.getImageUrl());
imageRef.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
mDatabaseRef.child(selectedKey).removeValue();
Toast.makeText(Images_Avctivity.this, "Item deleted", Toast.LENGTH_SHORT).show();
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
mDatabaseRef.removeEventListener(mDBListener);
}
}
This is adpater code:
Image_adapter.java:
public class Image_adapter extends RecyclerView.Adapter<Image_adapter.ImageViewHolder> {
private Context mContext;
private List<Upload> mUploads;
private OnItemClickListener mListener;
public Image_adapter(Context context, List<Upload> uploads) {
mContext = context;
mUploads = uploads;
}
#Override
public ImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.image_item, parent, false);
return new ImageViewHolder(v);
}
#Override
public void onBindViewHolder(ImageViewHolder holder, int position) {
Upload uploadCurrent = mUploads.get(position);
holder.textViewName.setText(uploadCurrent.getName());
Picasso.with(mContext)
.load(uploadCurrent.getImageUrl())
.placeholder(R.mipmap.ic_launcher)
.fit()
.centerCrop()
.into(holder.imageView);
}
#Override
public int getItemCount() {
return mUploads.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener {
public TextView textViewName;
public ImageView imageView;
public ImageViewHolder(View itemView) {
super(itemView);
textViewName = itemView.findViewById(R.id.text_view_name);
imageView = itemView.findViewById(R.id.image_view_upload);
itemView.setOnClickListener(this);
itemView.setOnCreateContextMenuListener(this);
}
#Override
public void onClick(View v) {
if (mListener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
mListener.onItemClick(position);
}
}
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.setHeaderTitle("Select Action");
MenuItem doWhatever = menu.add(Menu.NONE, 1, 1, "Do whatever");
MenuItem delete = menu.add(Menu.NONE, 2, 2, "Delete");
doWhatever.setOnMenuItemClickListener(this);
delete.setOnMenuItemClickListener(this);
}
#Override
public boolean onMenuItemClick(MenuItem item) {
if (mListener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
switch (item.getItemId()) {
case 1:
mListener.onWhatEverClick(position);
return true;
case 2:
mListener.onDeleteClick(position);
return true;
}
}
}
return false;
}
}
public interface OnItemClickListener {
void onItemClick(int position);
void onWhatEverClick(int position);
void onDeleteClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
}
StorageReference storageReference = FirebaseStorage.getInstance().getReferenceFromUrl("https://firebasestorage.googleapis.com/v0/b/***********************-5fac-45b6-bbda-ed4e8a3a62ab");
storageReference.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
// File deleted successfully
Log.e("firebasestorage", "onSuccess: deleted file");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Uh-oh, an error occurred!
Log.e("firebasestorage", "onFailure: did not delete file");
}
});
I want to delete card in a RecyclerView after selecting it.data in the RecyclerView is JSON data
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if(response.isSuccessful()) {
JsonObject responseObject = response.body();
if (responseObject.has("data")) {
JsonArray arrayobject = responseObject.getAsJsonArray("data");
ArrayList<User_Details_Model> myorder = getGeneral(arrayobject.toString());
viewRequestControllerCallback.hitsuccess1(myorder);
Here is a good resource to detect which cardView is clicked. After clicking a cardView you can delete it:
Recyclerview-listener
public interface OnItemClickListener {
void onItemClick(ContentItem item);
}
public void bind(final ContentItem item, final OnItemClickListener listener) {
...
itemView.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
listener.onItemClick(item);
}
});
}
this is the adapter
public void onBindViewHolder(#NonNull final UserViewHolder holder, final int
position) {
final User_Details_Model product = user_details.get(position);
Log.d("######",user_details.toString());
holder.tv1.setText(product.getDriverId());
holder.tv2.setText(product.getDriverName());
holder.tv3.setText(product.getVehicleId());
holder.tv4.setText(product.getVehicleType());
holder.tv5.setText(product.getOilType());
holder.button_ok.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
int pos=holder.getAdapterPosition();
if (position==pos){
getdetails();
user_details.remove(pos);
}
}
}
I am trying to add item from one adapter into another adapter. But when I added item, doesn't appear in the another adapter's recyclerview list.
ContactDataAdapter.java
#Override
public void onBindViewHolder(final ContactDataAdapter.ViewHolder holder, int position) {
holder.titleTv.setText(arrList.get(position).toString());
holder.conIv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
CallFragment cf = new CallFragment();
//CallDataAdapter cd = new CallDataAdapter();
String t = holder.titleTv.getText().toString();
cf.addItem(t.toString());
//cd.addData(t);
Toast.makeText(view.getContext(), "Added " + t, Toast.LENGTH_SHORT).show();
}
});
}
CallFragment.java
public void addItem(String title) {
adapter.addData(title.toString());
//adapter.notifyItemRangeChanged(0,data.size());
}
CallDataAdapter.java
public void addData(String title) {
dataList.add(title);
notifyDataSetChanged();
notifyItemRangeChanged(0, dataList.size());
notifyItemInserted(pos + 1);
}
The Image that clicked added button
A list that diplay added item("asd" added from the beginning.)
First setup EventBus
Define events:
public static class MessageEvent {
public String title;
}
in CallFragment declare it
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
adapter.addData(title.toString());
};
Register in your fragment from you setup ContactDataAdapter
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
Call the event
#Override
public void onBindViewHolder(final ContactDataAdapter.ViewHolder holder, int position) {
holder.titleTv.setText(arrList.get(position).toString());
holder.conIv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
MessageEvent event=new MessageEvent();
event.title= holder.titleTv.getText().toString();
EventBus.getDefault().post(event);
//CallFragment cf = new CallFragment();
//CallDataAdapter cd = new CallDataAdapter();
//String t = holder.titleTv.getText().toString();
//cf.addItem(t.toString());
//cd.addData(t);
Toast.makeText(view.getContext(), "Added " + t, Toast.LENGTH_SHORT).show();
}
});
}
I am making a social media app, I want to add a comment section for each post posted on firebase. Now I'm having difficulties in making the comment section. I've tried the below code but it keeps posting the comments on a single row and then crash the firebase. It is not creating a separate row for a new comment. After 1st comment is added the firebase data base looks like that:
but after I add another comment the "comments" value overrides instead of creating a new child post key.
This is how I'm sending comments to firebase:
final String message=myComment.getText().toString();
if (!TextUtils.isEmpty(message))
{
DatabaseComment.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
DatabaseComment.child(mPostKey).child(mAuth.getCurrentUser().getUid()).child("comments").setValue(message);
hDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
DatabaseComment.child(mPostKey).child(mAuth.getCurrentUser().getUid()).child("othersName")
.setValue(dataSnapshot.child(mAuth.getCurrentUser().getUid()).child("name").getValue());
DatabaseComment.child(mPostKey).child(mAuth.getCurrentUser().getUid()).child("othersDP")
.setValue(dataSnapshot.child(mAuth.getCurrentUser().getUid()).child("DP").getValue());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
And this is my onStart Method where I'm making recyclerAdapter:
mAuth.addAuthStateListener(mAuthListener);
FirebaseRecyclerAdapter<Profile,ProfileViewHolder> firebaseRecyclerAdapter=new FirebaseRecyclerAdapter<Profile, ProfileViewHolder>(
Profile.class,
R.layout.commentttt_row,
ProfileViewHolder.class,
DatabaseCommenttttt
) {
#Override
protected void populateViewHolder(final ProfileViewHolder viewHolder, final Profile model, int position) {
//viewHolder.setName(model.getName());
viewHolder.setComments(model.getComments());
viewHolder.setOthersName(model.getOthersName());
viewHolder.setOthersDP(model.getOthersDP());
}
};
mProfileList.setLayoutManager(mLayoutManager);
mProfileList.setAdapter(firebaseRecyclerAdapter);
And this is my RecyclerView class:
public static class ProfileViewHolder extends RecyclerView.ViewHolder
{
View mView;
LinearLayout mLinearName;
TextView userName;
TextView mComment;
CircleImageView mSetupImageButton;
FirebaseAuth mAuth;
TextView post_name;
private String comments;
private String othersName;
private String othersDP;
public ProfileViewHolder(View itemView) {
super(itemView);
mView=itemView;
userName=(TextView) mView.findViewById(R.id.post_name);
mLinearName=(LinearLayout) mView.findViewById(R.id.layout_name);
mComment=(TextView) mView.findViewById(R.id.comment);
}
public void setImage(final Context ctx, final String image)
{
final ImageView post_image=(ImageView) mView.findViewById(R.id.post_image);
Picasso.with(ctx).load(image).networkPolicy(NetworkPolicy.OFFLINE).into(post_image, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(ctx).load(image).into(post_image);
}
});
}
public void setComments(String comments) {
TextView post_phone=(TextView) mView.findViewById(R.id.others_comments);
post_phone.setText(comments);
}
public void setOthersName(String othersName) {
TextView post_phone=(TextView) mView.findViewById(R.id.others_name);
post_phone.setText(othersName);
}
public void setOthersDP(String othersDP) {
CircleImageView mSetupImageButton = (CircleImageView) mView.findViewById(R.id.accountImageButton);
Picasso.with(mView.getContext()).load(othersDP).into(mSetupImageButton);
}
}
Assuming you have a Comment class with comments, otherDP, otherName. now add a new member userId.
final String message=myComment.getText().toString();
if (!TextUtils.isEmpty(message))
{
DatabaseComment.child(mPostKey).addValueEventListener(new
ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ArryList<Comment> comments= (ArryList<Comment>)
dataSnapshot.getValue();
Comment comment = new Comment();
comment.setName("Name");
comment.setOtherDP("OtherDP");
comment.setComment("Comment");
comment.setUserID("UserID");
comments.add(comment);
DatabaseComment.child(mPostKey).setValue(comments);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
this will create an arrylist of comments inside everypost .. one user can comment multiple time.
Edit: When I use this
final String message=myComment.getText().toString();
if (!TextUtils.isEmpty(message))
{
DatabaseComment.child(mPostKey).addValueEventListener(new
ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ArrayList<Profile> comments= (ArrayList<Profile>)
dataSnapshot.getValue();
Profile comment = new Profile();
comment.setOthersName("Name");
comment.setOthersDP("OtherDP");
comment.setComments("Comment");
comment.setUid("UserID");
comments.add(comment);
DatabaseComment.child(mPostKey).setValue(comments);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
lOGCAT GIVE ME THIS: java.lang.NullPointerException: Attempt to invoke interface method 'void android.view.IWindowSession.remove(android.view.IWindow)' on a null object reference