I have a list of students shown on a RecyclerView and retrieving data from Firebase I want to check a checkbox if they are inside a group. It apparently works, but only in Debug mode.
Whenever I try to do a normal run it does nothing (only shows the list, but none of the checkboxes are checked).
#Override
protected void onBindViewHolder(#NonNull ListViewAdapter.ViewHolder holder, int position, #NonNull Estudiante estudiante) {
DocumentSnapshot documentSnapshot = getSnapshots().getSnapshot(holder.getAbsoluteAdapterPosition());
String id = documentSnapshot.getId();
holder.nombre.setText(estudiante.getNombre());
estudiantesFirebase = editGrupoFragment.getEstudiantesFirebase();
Log.d("estList","Estudiantes Fireb: "+ estudiantesFirebase.toString());
firestore.collection("Estudiantes")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
ArrayList<String> list = new ArrayList<>();
for (QueryDocumentSnapshot document : task.getResult()) {
list.add(document.get("nombre").toString());
}
for (int i = 0; i < estudiantesFirebase.size(); i++){
if(estudiantesFirebase.get(i).equals(holder.nombre.getText().toString())){
Log.d("estList", estudiantesFirebase.get(i) + " => " + holder.nombre.getText().toString());
//TODO: quemar algo
holder.checkBox.setChecked(true);
}
}
} else {
Log.d("estList", "Error getting documents: ", task.getException());
}
}
});
}
Apparently, the ArrayList estudiantesFirebase has no values inside. The other class I am using (to get that array) is the following:
public class EditGrupoFragment extends DialogFragment{
private FragmentEditGrupoBinding binding;
private ListviewItemBinding bindingLV;
TextView txtNombreGrupo, txtNDificultadGrupo;
Spinner spinnerDificultadEditar;
Button btnGuardarCambios;
ListViewAdapter eAdapter;
RecyclerView recyclerView;
FirebaseFirestore firestore;
SearchView searchBar;
Query query;
ArrayList<String> estudiantesFirebase = new ArrayList<>();
String NGRUPO;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments()!=null){
NGRUPO = getArguments().getString("nombre");
}
}
#SuppressLint("NotifyDataSetChanged")
#Override
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentEditGrupoBinding.inflate(inflater, container, false);
View root = binding.getRoot();
firestore = FirebaseFirestore.getInstance();
searchBar = root.findViewById(R.id.searchBar);
btnGuardarCambios = root.findViewById(R.id.btnGuardarEditGrupo);
txtNombreGrupo = root.findViewById(R.id.etEditNombreGrupo);
txtNDificultadGrupo = root.findViewById(R.id.txtNDificultadGrupo);
spinnerDificultadEditar= root.findViewById(R.id.spinnerDificultadEditar);
getGrupo();
setUpRecyclerView(root);
search_view();
return root;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
btnGuardarCambios.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String nombre = txtNombreGrupo.getText().toString();
String dificultad = spinnerDificultadEditar.getSelectedItem().toString();
//String description = txtDescriptionGrupo.getText().toString();
updateGrupo(nombre, dificultad);
}
});
}
private void getGrupo(){
firestore.collection("Temas").document(NGRUPO).get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
String nombre = documentSnapshot.getString("nombre");
String dificultad = documentSnapshot.getString("dificultad");
estudiantesFirebase = (ArrayList<String>) documentSnapshot.get("estudiantes");
txtNombreGrupo.setText(nombre);
spinnerDificultadEditar.setPrompt("Actual: "+dificultad);
//txtDescriptionGrupo.setText(grupo);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getContext(), "Error al obtener los datos", Toast.LENGTH_SHORT).show();
}
});
}
public ArrayList<String> getEstudiantesFirebase(){
return estudiantesFirebase;
}
private void updateGrupo(String nombre, String dificultad) {
Map<String, Object> map = new HashMap<>();
map.put("nombre", nombre);
map.put("dificultad", dificultad);
firestore.collection("Temas").document(NGRUPO).update(map).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
Toast.makeText(getContext(), "Tema editado", Toast.LENGTH_SHORT).show();
getDialog().dismiss();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getContext(), "Error al editar tema", Toast.LENGTH_SHORT).show();
}
});
}
#SuppressLint("NotifyDataSetChanged")
private void setUpRecyclerView(View view) {
recyclerView = view.findViewById(R.id.searchRecyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
query = firestore.collection("Estudiantes");
FirestoreRecyclerOptions<Estudiante> firestoreRecyclerOptions =
new FirestoreRecyclerOptions.Builder<Estudiante>().setQuery(query, Estudiante.class).build();
eAdapter = new ListViewAdapter(firestoreRecyclerOptions, getActivity(), getActivity().getSupportFragmentManager(),this);
eAdapter.notifyDataSetChanged();
recyclerView.setAdapter(eAdapter);
}
private void search_view() {
searchBar.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
textSearch(s);
return false;
}
#Override
public boolean onQueryTextChange(String s) {
textSearch(s);
return false;
}
});
}
private void textSearch(String s) {
FirestoreRecyclerOptions<Estudiante> firestoreRecyclerOptions =
new FirestoreRecyclerOptions.Builder<Estudiante>().setQuery(query.orderBy("nombre")
.startAt(s).endAt(s+"~"), Estudiante.class).build();
eAdapter = new ListViewAdapter(firestoreRecyclerOptions, getActivity(), getActivity().getSupportFragmentManager(),this);
eAdapter.startListening();
recyclerView.setAdapter(eAdapter);
}
#Override
public void onStart() {
super.onStart();
eAdapter.startListening();
}
#Override
public void onStop() {
super.onStop();
eAdapter.stopListening();
}
#Override
public void onResume() {
super.onResume();
int width = getResources().getDisplayMetrics().widthPixels;
int height = (getResources().getDisplayMetrics().heightPixels)/2;
getDialog().getWindow().setLayout(width, height);
}
}
Related
I'm making a chat app. I have a recycler view. I use Picasso to download the images of the user and the friend he is chatting with. To not download the image for every message, when I download the first image I just put it into a bitmap and use it every time.
PROBLEM: I can't call NotifyDataSetChanged. I have tried every possible thing I've found on the net.
ERROR :
Cannot call this method while RecyclerView is computing a layout or scrolling android.support.v7.widget.RecyclerView
I have to "manually" refresh the view so that the images are loaded. No problem for the text.
It runs with the Handler but it doesn't even go in the function (so the view isn't refreshed).
Here is my code (everything works except this notifydatasetchanged)
public class ChatActivity extends AppCompatActivity {
private RecyclerView recyclerChat;
private ListMessageAdapter adapter;
private EditText editWriteMessage;
private LinearLayoutManager linearLayoutManager;
private FirebaseAuth mAuth;
private DatabaseReference UserRef, MessageIDREF, UserMessageRef, SendMessageUser;
private List<ChatClass> ListOfChats = new ArrayList<>();
private ImageButton btnSend;
private String currentUserID, currentDateMessage, currentTimeMessage;
private CommunActivit obj = new CommunActivit();
private String FRIENDID;
private Toolbar mToolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
mAuth=FirebaseAuth.getInstance();
currentUserID = mAuth.getCurrentUser().getUid();
MessageIDREF = FirebaseDatabase.getInstance().getReference().child("Friends");
UserMessageRef = FirebaseDatabase.getInstance().getReference().child("Message").child(obj.getsIDMESSAGE());
btnSend = (ImageButton) findViewById(R.id.btnSend);
editWriteMessage = (EditText) findViewById(R.id.editWriteMessage) ;
FRIENDID = obj.getsIDFRIEND();
mToolbar = (Toolbar) findViewById(R.id.main_app_bar2);
setSupportActionBar(mToolbar);
ActionBar ab = getSupportActionBar();
final String Title = obj.getsFRIENDName();
ab.setTitle(Title);
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SendMessageToGroupChat();
editWriteMessage.setText("");
}
});
retrievedata();
/*recyclerChat = (RecyclerView)findViewById(R.id.recyclerChat);
adapter = new ListMessageAdapter(this,ListOfChats);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recyclerChat.setLayoutManager(layoutManager);
recyclerChat.setItemAnimator(new DefaultItemAnimator());
recyclerChat.setAdapter(adapter);*/
linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerChat = (RecyclerView) findViewById(R.id.recyclerChat);
recyclerChat.setLayoutManager(linearLayoutManager);
adapter = new ListMessageAdapter(this, ListOfChats);
recyclerChat.setAdapter(adapter);
/* editWriteMessage.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
recyclerChat.smoothScrollToPosition(adapter.getItemCount());
return false;
}
});*/
}
private void SendMessageToGroupChat() {
String message = editWriteMessage.getText().toString();
String messageKey = UserMessageRef.push().getKey();
if (TextUtils.isEmpty(message)) {
Toast.makeText(this, "Please write a message first", Toast.LENGTH_SHORT).show();
} else {
Calendar calendarDate = Calendar.getInstance();
SimpleDateFormat DateFormat = new SimpleDateFormat("MMM dd, yyyy");
currentDateMessage = DateFormat.format(calendarDate.getTime());
Calendar calendarTime = Calendar.getInstance();
SimpleDateFormat TimeFormat = new SimpleDateFormat("hh:mm a");
currentTimeMessage = TimeFormat.format(calendarTime.getTime());
HashMap<String, Object> groupMessageKey = new HashMap<>();
UserMessageRef.updateChildren(groupMessageKey);
SendMessageUser = UserMessageRef.child(messageKey);
HashMap<String, Object> messageInfoMap = new HashMap<>();
messageInfoMap.put("name", obj.getsUsername());
messageInfoMap.put("message", message);
messageInfoMap.put("date", currentDateMessage);
messageInfoMap.put("time", currentTimeMessage);
messageInfoMap.put("image", obj.getsUserImageLink());
SendMessageUser.updateChildren(messageInfoMap);
}
}
public void retrievedata() {
UserMessageRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) /**** HERE IS THE PROBLEM***/
{
if (dataSnapshot.exists()) {
DisplayMessages(dataSnapshot);
}
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
if (dataSnapshot.exists()) {
DisplayMessages(dataSnapshot);
}
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void DisplayMessages(DataSnapshot dataSnapshot)
{
Iterator iterator = dataSnapshot.getChildren().iterator();
while (iterator.hasNext()) {
String chatDate = (String) ((DataSnapshot) iterator.next()).getValue();
String chatImage = (String) ((DataSnapshot) iterator.next()).getValue();
String chatMessage = (String) ((DataSnapshot) iterator.next()).getValue();
String chatName = (String) ((DataSnapshot) iterator.next()).getValue();
String chatTime = (String) ((DataSnapshot) iterator.next()).getValue();
ListOfChats.add(new ChatClass(chatName, chatMessage, chatDate + " " + chatTime, chatImage));
adapter.notifyDataSetChanged();
recyclerChat.smoothScrollToPosition(adapter.getItemCount()); /**AUTO SCROLL**/
}
}
class ListMessageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private ChatClass consersation;
private List<ChatClass> List_of_chats;
private CommunActivit obj = new CommunActivit();
private Bitmap BitmapUser;
private Bitmap BitmapFriend;
public ListMessageAdapter(Context context, List<ChatClass> List_of_chats) {
this.context = context;
this.List_of_chats = List_of_chats;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == 1) {
View view = LayoutInflater.from(context).inflate(R.layout.rc_item_message_friend, parent, false);
return new ItemMessageFriendHolder(view);
} else if (viewType == 2) {
View view = LayoutInflater.from(context).inflate(R.layout.rc_item_message_user, parent, false);
return new ItemMessageUserHolder(view);
}
return null;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final int pos =position;
if (holder instanceof ItemMessageFriendHolder) {
((ItemMessageFriendHolder) holder).txtContent.setText(List_of_chats.get(position).getMessage());
if (BitmapFriend == null) {
Picasso.get().load(List_of_chats.get(position).getImageLink()).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
BitmapFriend = bitmap;
}
#Override
public void onBitmapFailed(Exception e, Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
((ItemMessageFriendHolder) holder).avata.setImageBitmap(BitmapFriend);
}
else
{
((ItemMessageFriendHolder) holder).avata.setImageBitmap(BitmapFriend);
new Handler().post(new Runnable() {
#Override
public void run() {
notifyDataSetChanged();
}
});
}
}
else
{
if (holder instanceof ItemMessageUserHolder) {
((ItemMessageUserHolder) holder).txtContent.setText(List_of_chats.get(position).getMessage());
if (BitmapUser == null) {
Picasso.get().load(List_of_chats.get(position).getImageLink()).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
BitmapUser = bitmap;
}
#Override
public void onBitmapFailed(Exception e, Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
((ItemMessageUserHolder) holder).avata.setImageBitmap(BitmapUser);
} else {
((ItemMessageUserHolder) holder).avata.setImageBitmap(BitmapUser);
new Handler().post(new Runnable() {
#Override
public void run() {
notifyDataSetChanged();
}
});
}
}
}
}
#Override
public int getItemViewType(int position) {
int viewtype = -1;
if (List_of_chats.get(position).getUsername().equals(obj.getsUsername())) {
return 2;
}
else
{
return 1;
}
}
#Override
public int getItemCount() {
return List_of_chats.size();
}
}
class ItemMessageUserHolder extends RecyclerView.ViewHolder {
public TextView txtContent;
public CircleImageView avata;
public ItemMessageUserHolder(View itemView) {
super(itemView);
txtContent = (TextView) itemView.findViewById(R.id.textContentUser);
avata = (CircleImageView) itemView.findViewById(R.id.imageView2);
}
}
class ItemMessageFriendHolder extends RecyclerView.ViewHolder {
public TextView txtContent;
public CircleImageView avata;
public ItemMessageFriendHolder(View itemView) {
super(itemView);
txtContent = (TextView) itemView.findViewById(R.id.textContentFriend);
avata = (CircleImageView) itemView.findViewById(R.id.imageView3);
}
}
It is because you're calling notifyDataSetChanged inside your onBindViewHolder like this:
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
...
((ItemMessageFriendHolder) holder).avata.setImageBitmap(BitmapFriend);
new Handler().post(new Runnable() {
#Override
public void run() {
notifyDataSetChanged();
}
});
...
}
You shouldn't force the Adapter to refresh itself before it isn't finished binding the view yet.
So, you need to remove the following code from your onBindViewHolder:
new Handler().post(new Runnable() {
#Override
public void run() {
notifyDataSetChanged();
}
});
then just call notifyDataSetChanged() when you need it. For example, when your dataset is changed.
Try this.
dialeecyclerView.post(new Runnable()
{
#Override
public void run() {
myadapter.notifyDataSetChanged();
}
});
Source - Cannot call this method while RecyclerView is computing a layout or scrolling when try remove item from recyclerview
I already retrieve the data from FireStore successfully, and i want to search list of data using SearchView, but it doesnt show anything in recyclerView when i try to search in Searchview.
Here is my code for Main Activity. I retrieve the list of data using query and show in recycler View.
public class MainActivity extends AppCompatActivity {
private final static String TAG = MainActivity.class.getSimpleName();
private RecyclerView recyclerView;
private FirebaseAuth mAuth;
private FirebaseFirestore db;
private FoodAdapter mAdapter;
SearchView searchView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth = FirebaseAuth.getInstance();
db = FirebaseFirestore.getInstance();
// Force Login
if (mAuth.getCurrentUser() == null || mAuth.getCurrentUser().getEmail().isEmpty()) {
Intent intent = new Intent(this, Login.class);
startActivity(intent);
finish();
}
recyclerView = findViewById(R.id.recycler_home);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = findViewById(R.id.search);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
getSearch(newText);
return false;
}
});
mAdapter = new FoodAdapter(new FoodAdapter.OnFoodClickListener() {
#Override
public void OnClick(FoodModel food) {
Intent intent = new Intent(MainActivity.this, FoodActivity.class);
intent.putExtra("id", food.getId());
startActivity(intent);
}
getFoodData();
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));
recyclerView.setAdapter(mAdapter);
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
getFoodData();
}
public void getSearch(String s){
mAdapter.clear();
Query que = db.collection("Food");
que.whereEqualTo("title", s);
que
.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot documentSnapshots) {
if (!documentSnapshots.isEmpty()) {
for (DocumentSnapshot docSnap : documentSnapshots.getDocuments()) {
FoodModel model = docSnap.toObject(FoodModel.class);
model.setId(docSnap.getId());
loadSticker(model);
}
}
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
});
}
public void getFoodData() {
mAdapter.clear();
Query query = db.collection(“Food”);
query
.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot documentSnapshots) {
if (!documentSnapshots.isEmpty()) {
for (DocumentSnapshot docSnap : documentSnapshots.getDocuments()) {
FoodModel model = docSnap.toObject(FoodModel.class);
model.setId(docSnap.getId());
loadSticker(model);
}
}
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
});
}
public void loadSticker(final FoodModel foodModel) {
db
.collection("beverage")
.whereEqualTo("name", foodModel.getBeverage())
.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot documentSnapshots) {
if (documentSnapshots.getDocuments().get(0).exists()) {
BeverageModel model = documentSnapshots.getDocuments().get(0).toObject(BeverageModel.class);
FoodModel newFoodModel = foodModel;
newFoodModel.setSticker(model.getSticker());
mAdapter.addItem(newFoodModel);
}
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
});
}
}
Here is the adapter code, which i apply filter for searchView. Anybody knows whats the error in my code for adapter.
public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.FoodViewHolder> {
private List<FoodModel> foodModels;
private List<FoodModel>foodModelsList;
private OnFoodClickListener listener;
public FoodAdapter(OnFoodClickListener listener) {
foodModels = new ArrayList<>();
this.foodModelsList = foodModels;
this.listener = listener;
}
#Override
public FoodViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_holder_food, parent, false);
return new FoodViewHolder(view);
}
#Override
public void onBindViewHolder(FoodViewHolder holder, int position) {
FooModel model = foodModels.get(position);
holder.title.setText(model.getTitle());
holder.description.setText(model.getDescription());
Picasso.get().load(model.getSticker()).into(holder.sticker);
}
#Override
public int getItemCount() {
return foodModels.size();
}
public void addItem(FoodModel food){
foodModels.add(food);
notifyDataSetChanged();
}
class FoodViewHolder extends RecyclerView.ViewHolder {
private TextView name, description;
private ImageView sticker;
FoodViewHolder(View itemView) {
super(itemView);
title = itemView.findViewById(R.id.tv_title);
sticker = itemView.findViewById(R.id.img_sticker);
description = itemView.findViewById(R.id.tv_description);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int position = getAdapterPosition();
listener.OnClick(foodModels.get(position));
}
});
}
}
public interface OnFoodClickListener{
void OnClick(FoodModel food);
}
}
I want to hide the current user in RequestsFragment in recyclerview. I tried to setVisibility feature. The current user's informantions are not seen to him. But there is a space still in recyclerview. How can i also delete space between other items. I mean if I have sent a request to other users I dont want to see myself at requests fragment.
public class RequestsFragment extends Fragment {
private RecyclerView recyclerView_friendRequestsList;
private View mainView;
private DatabaseReference friendRequestsDatabaseReference;
private DatabaseReference usersDatabaseReference;
private FirebaseAuth firebaseAuth;
private String current_user_id;
public RequestsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
mainView = inflater.inflate(R.layout.fragment_requests, container, false);
recyclerView_friendRequestsList = mainView.findViewById(R.id.friendRequests_list);
recyclerView_friendRequestsList.setHasFixedSize(true);
recyclerView_friendRequestsList.setLayoutManager(new LinearLayoutManager(getContext()));
firebaseAuth = FirebaseAuth.getInstance();
current_user_id = firebaseAuth.getCurrentUser().getUid();
friendRequestsDatabaseReference = FirebaseDatabase.getInstance().getReference().child("Friend Requests");
friendRequestsDatabaseReference.keepSynced(true);
usersDatabaseReference = FirebaseDatabase.getInstance().getReference().child("Users");
usersDatabaseReference.keepSynced(true);
return mainView;
}
#Override
public void onStart() {
super.onStart();
final FirebaseRecyclerAdapter<FriendRequests, RequestsFragment.FriendRequestsViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<FriendRequests, FriendRequestsViewHolder>(
FriendRequests.class,
R.layout.users_single_layout,
RequestsFragment.FriendRequestsViewHolder.class,
friendRequestsDatabaseReference
) {
#Override
protected void populateViewHolder(final FriendRequestsViewHolder viewHolder, FriendRequests model, final int position) {
final String user_id = getRef(position).getKey();
friendRequestsDatabaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.hasChild(user_id)){
usersDatabaseReference.child(user_id).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (!user_id.equals(current_user_id)) {
final String user_displayName = dataSnapshot.child("display_name").getValue().toString();
final String user_thumbImage = dataSnapshot.child("thumb_image").getValue().toString();
if (dataSnapshot.hasChild("online")) {
String userOnline = dataSnapshot.child("online").getValue().toString();
viewHolder.setUserOnline(userOnline);
}
viewHolder.setName(user_displayName);
viewHolder.setImage(user_thumbImage);
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent profileIntent = new Intent(getContext(), ProfileActivity.class);
profileIntent.putExtra("user_id", user_id);
startActivity(profileIntent);
}
});
} else {
viewHolder.mView.setVisibility(View.GONE);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
friendRequestsDatabaseReference.child(current_user_id).child(user_id).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild("request_type")) {
String request_type = dataSnapshot.child("request_type").getValue().toString();
viewHolder.setRequest_type(request_type);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
};
recyclerView_friendRequestsList.setAdapter(firebaseRecyclerAdapter);
}
public static class FriendRequestsViewHolder extends RecyclerView.ViewHolder {
View mView;
public FriendRequestsViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setName(String name) {
TextView userNameView = mView.findViewById(R.id.user_single_displayName);
userNameView.setText(name);
}
public void setRequest_type(String request_type) {
TextView userStatusView = mView.findViewById(R.id.user_single_status);
userStatusView.setText(request_type);
}
public void setImage(final String thumb_image) {
CircleImageView userImageView = mView.findViewById(R.id.user_single_image);
Picasso.get().load(thumb_image).placeholder(R.mipmap.default_avatar).into(userImageView);
}
public void setUserOnline(String online_status) {
ImageView userOnlineView = mView.findViewById(R.id.user_single_online);
if (online_status.equals("true")) {
userOnlineView.setVisibility(View.VISIBLE);
} else {
userOnlineView.setVisibility(View.INVISIBLE);
}
}
}
}
I am creating a program, where user can update post, and other user and same user can react there. For that, I have implemented the love button. So this works this way, I have saved a unique id in the DatabaseReference and other reference for uniquekey for easiness. So, whenever, the user clicks on love button, it must update the total reaction of the node by increasing it to one. The problem I am getting is, whenever I press the love button key, it doesn't call the uniqueID I need. The uniqueId I am getting from model class from viewholder is not the post I have reacted to.
public class LatestFragment extends Fragment {
private RecyclerView latestFragmentRecyclerView;
private DatabaseReference mDatabaseReference;
private FirebaseAuth mAuth;
private static Context context;
private static boolean firstTime;
private static String totalVotes;
private static String uniqueKey;
private static DatabaseReference reactionDatabaseReference;
private static DatabaseReference uniqueKeysReferences;
private static Boolean userReactState;
private static List<String> allUniqueKeys;
public LatestFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_latest,container,false);
latestFragmentRecyclerView = (RecyclerView) v.findViewById(R.id.recyclerViewForLatestFragment);
latestFragmentRecyclerView.setHasFixedSize(true);
userReactState = false;
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setReverseLayout(true);
layoutManager.setStackFromEnd(true);
latestFragmentRecyclerView.setLayoutManager(layoutManager);
mAuth = FirebaseAuth.getInstance();
mDatabaseReference = FirebaseDatabase.getInstance().getReference().child("Posts");
reactionDatabaseReference=FirebaseDatabase.getInstance().getReference().child("PostReactions");
uniqueKeysReferences = FirebaseDatabase.getInstance().getReference().child("UniqueKeys");
mDatabaseReference.keepSynced(true);
firstTime = true;
return v;
}
#Override
public void onStart() {
super.onStart();
final FirebaseRecyclerAdapter<Posts, PostViewHolder> firebaseRecyclerAdapter =
new FirebaseRecyclerAdapter<Posts, PostViewHolder>(
Posts.class, R.layout.each_post_layout, PostViewHolder.class, mDatabaseReference
) {
#Override
protected void populateViewHolder(final PostViewHolder viewHolder,final Posts model, int position) {
Context c = getActivity();
context = c;
uniqueKey = model.getUnique();
viewHolder.setUsername(model.getUsername());
viewHolder.setCaption(model.getCaption());
viewHolder.setTime(model.getTime());
viewHolder.setImage(model.getImage(),c);
viewHolder.setCurrentUserImage(model.getUserPhoto(),c);
viewHolder.imageViewIfUserClicked(model.getCurrentUserReaction(),c);
totalVotes = model.getTotalReactions();
}
};
latestFragmentRecyclerView.setAdapter(firebaseRecyclerAdapter);
}
public static class PostViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
View theRecyclingView;
private Button loveButton ;
public PostViewHolder(View itemView) {
super(itemView);
theRecyclingView = itemView;
loveButton = (Button) theRecyclingView.findViewById(R.id.loveButton);
loveButton.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if(view.getId()==loveButton.getId())
{
allUniqueKeys = new ArrayList<>();
int position = getAdapterPosition();
Log.e("UniqueKey", String.valueOf(position));
uniqueKeysReferences.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot x : dataSnapshot.getChildren()) {
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
if(firstTime==true)
{
loveButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.like_button_red,0,0,0);
firstTime = false;
int vote= Integer.valueOf(totalVotes);
vote++;
totalVotes = String.valueOf(vote);
reactionDatabaseReference.child(uniqueKey).child("TotalReactions").setValue(totalVotes).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful())
{
reactionDatabaseReference.child(uniqueKey).child("CurrentUserReaction").setValue("true").addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful())
{
}
else
{
Toast.makeText(context," Some Error Occured ",Toast.LENGTH_LONG).show();
}
}
});
}
else
{
Toast.makeText(context," Some Error Occured ",Toast.LENGTH_LONG).show();
}
}
});
}
else
{
loveButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.like_button,0,0,0);
firstTime = true;
int vote= Integer.valueOf(totalVotes);
vote--;
totalVotes = String.valueOf(vote);
reactionDatabaseReference.child(uniqueKey).child("TotalReactions").setValue(totalVotes).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful())
{
reactionDatabaseReference.child(uniqueKey).child("CurrentUserReaction").setValue("false").addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful())
{
}
else
{
Toast.makeText(context," Some Error Occured ",Toast.LENGTH_LONG).show();
}
}
});
}
else
{
Toast.makeText(context," Some Error Occured ",Toast.LENGTH_LONG).show();
}
}
});
}
}
}
public void setUsername(String username)
{
TextView mUsername= (TextView) theRecyclingView.findViewById(R.id.userWhoPostedUserName);
mUsername.setText(username);
}
public void setCaption(String caption) {
TextView mUsername= (TextView) theRecyclingView.findViewById(R.id.captionForPic);
mUsername.setText(caption);
}
public void setImage(final String image, final Context c) {
final ImageView imageView = (ImageView) theRecyclingView.findViewById(R.id.userUploadedImageView);
Picasso.with(c).load(image).networkPolicy(NetworkPolicy.OFFLINE).into(imageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(c).load(image).into(imageView);
}
});
}
public void setTime(String time) {
TextView time_of_posting = (TextView) theRecyclingView.findViewById(R.id.timeOfPosting_each_post_layout);
time_of_posting.setText(time);
}
public void setCurrentUserImage(final String userPhoto, final Context c) {
final CircleImageView imageView = (CircleImageView) theRecyclingView.findViewById(R.id.userWhoPostedCircleImageView);
Picasso.with(c).load(userPhoto).networkPolicy(NetworkPolicy.OFFLINE).into(imageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(c).load(userPhoto).into(imageView);
}
});
}
public void imageViewIfUserClicked(String currentUserReaction, final Context c) {
//reactionDatabaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
// #Override
//public void onDataChange(DataSnapshot dataSnapshot) {
// String CurrentuserReaction = dataSnapshot.child(uniqueKey).child("TotalReactions").child("CurrentUserReaction").getValue().toString();
// userReactState = Boolean.parseBoolean(CurrentuserReaction);
//}
//#Override
//public void onCancelled(DatabaseError databaseError) {
//
// }
// });
if(userReactState==false) {
loveButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.like_button,0,0,0);
}
else
{
loveButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.like_button_red,0,0,0);
}
}
}
}
I'm using a recyclerView that inflates two types of views, to be able to do a chat, everything is fine but it is not sent or received instantly
When I send a message, it is not received unless I click on my edit text,
Which is wrong, because in a chat should show instantly...
My adapter:
public class ChatRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public Context context;
public ArrayList<ChatPersonal> items = new ArrayList<>();
private String mId;
private static final int CHAT_RIGHT = 1;
private static final int CHAT_LEFT = 2;
public ChatRecyclerAdapter (Context context, ArrayList<ChatPersonal> items, String mId){
this.context = context;
this.items = items;
this.mId = mId;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = null;
RecyclerView.ViewHolder holder = null;
switch (viewType){
case CHAT_RIGHT:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_chat_right, parent, false);
holder = new ChatPersonalHolderSender(view);
break;
case CHAT_LEFT:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_chat_left, parent, false);
holder = new ChatPersonalHolder(view);
break;
}
return holder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ChatPersonal mObject = items.get(position);
int itemViewType = getItemViewType(position);
switch(itemViewType){
case CHAT_RIGHT:
((ChatPersonalHolderSender) holder).mMENSAJE.setText(mObject.getMessage());
((ChatPersonalHolderSender) holder).mHORA.setText(DateUtils.getRelativeTimeSpanString(mObject.getHour()));
break;
case CHAT_LEFT:
((ChatPersonalHolder) holder).mMENSAJE.setText(mObject.getMessage());
((ChatPersonalHolder) holder).mHORA.setText(DateUtils.getRelativeTimeSpanString(mObject.getHour()));
break;
}
}
#Override
public int getItemViewType(int position) {
if(items.get(position).getId().equals(mId)){
return CHAT_RIGHT;
}else{
return CHAT_LEFT;
}
}
#Override
public int getItemCount() {
return items.size();
}
}
And this is the relevant code of my chatClass:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
linearLayoutManager = new LinearLayoutManager(ActivityChat.this);
linearLayoutManager.setStackFromEnd(true);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setHasFixedSize(false);
adapter = new ChatRecyclerAdapter(getApplicationContext(), items, mId);
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
// send message
mSentMensaje.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String message = mEditText.getText().toString();
if (!message.isEmpty()) {
mChat.setMessage(message);
mChat.setHour(System.currentTimeMillis());
mChat.setId(mId);
if(mUser != null){
if(mUser.getIDchat() != null){
FirebaseUtils.getCHATT(mUser.getIDchat()).push().setValue(mChat).addOnSuccessListener(ActivityChat.this, new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
mRecyclerView.scrollToPosition(items.size() -1);
adapter.notifyDataSetChanged();
mEditText.setText("");
}
});
}}
// retreive message
if(mUser != null){
if(mUser.getIDchat() != null){
FirebaseUtils.getCHATT(mUser.getIDchat()).limitToFirst(50).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot != null && dataSnapshot.getValue() != null) {
try{
ChatPersonal model = dataSnapshot.getValue(ChatPersonal.class);
items.add(model);
} catch (Exception ex) {
Log.e(TAG, ex.getMessage());
}
}
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
// status
#Override
protected void onStart() {
super.onStart();
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onChanged() {
super.onChanged();
mRecyclerView.scrollToPosition(adapter.getItemCount() - 1);
}
});
}
#Override
protected void onResume() {
super.onResume();
adapter.notifyDataSetChanged();
}
#Override
protected void onPostResume() {
super.onPostResume();
adapter.notifyDataSetChanged();
}
}
If you want the data to be synced with Firebase automatically, you need to use FirebaseRecyclerAdapter
Reference: https://github.com/firebase/FirebaseUI-Android/blob/master/database/src/main/java/com/firebase/ui/database/FirebaseRecyclerAdapter.java