I am using a recyclerview and inside its adapter I have another recyclerview.
How to prevent item change and item refresh when an item is updated.
This is creating visual glitches and wrong positioning of the items
I have tried to read directly from a database reference on the current position of the holder.
Result: https://media.giphy.com/media/j6TpXZRE6e44cMZVIP/giphy.gif
public class CommentsAdapter extends RecyclerView.Adapter<CommentsAdapter.ViewHolder>{
private Context mContext;
private List<Comments> mComments;
private List<Replies> allReplies;
public CommentsAdapter(Context mContext, List<Comments> mComments, List<Replies> allReplies )
{
this.mContext = mContext;
this.mComments = mComments;
this.allReplies = allReplies;
}
#NonNull
#Override
public CommentsAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(mContext).inflate(R.layout.all_comments_layout, viewGroup, false);
return new CommentsAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position)
{
final Comments comments = mComments.get(position);
holder.like.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CommentUps.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
{
if (dataSnapshot.child(PostKey).child(com_uid).hasChild(currentUserID)) {
CommentUps.child(PostKey).child(com_uid).child(currentUserID).removeValue();
CommentsRef.child(PostKey).child(com_uid).child("likes").setValue(comments.getLikes() - 1);
} else {
CommentUps.child(PostKey).child(com_uid).child(currentUserID).setValue(true);
CommentsRef.child(PostKey).child(com_uid).child("likes").setValue(comments.getLikes() + 1);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
});
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Replies");
//reference.orderByChild("pLikes")
reference.orderByChild(com_uid).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
holder.repliesList.clear();
for (DataSnapshot snapshot : dataSnapshot.child(PostKey).child(com_uid).getChildren())
{
Replies replies = snapshot.getValue(Replies.class);
//final String com = comment.toString();
// Log.d(new String("Comments"), com);
//for (String id : followingList)
if (replies.getComment_uid().equals(com_uid))
{
holder.repliesList.add(replies);
}
}
holder.repliesAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public int getItemCount() {
return mComments.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageButton like
List<Replies> repliesList;
RepliesAdapter repliesAdapter;
public ViewHolder(View itemView) {
super(itemView);
like = itemView.findViewById(R.id.comment_like_button);
repliesRecycler = itemView.findViewById(R.id.all_replies_recycler);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mContext);
repliesRecycler.setLayoutManager(linearLayoutManager);
repliesRecycler.setHasFixedSize(true);
repliesList = new ArrayList<>();
repliesAdapter = new RepliesAdapter(mContext, repliesList);
repliesRecycler.setAdapter(repliesAdapter);
repliesAdapter.notifyDataSetChanged();
}
// Second Method - Same Result
private void displayReplies(final String com_uid ,final String PostKey, final boolean locked) {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Replies");
reference.child(PostKey).child(com_uid).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
repliesList.clear();
if (dataSnapshot.exists()) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
final Replies replies = snapshot.getValue(Replies.class);
if (replies.getComment_uid().equals(com_uid)) {
repliesList.add(replies);
repliesAdapter.notifyDataSetChanged();
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
My replies adapter:
public class RepliesAdapter extends RecyclerView.Adapter<RepliesAdapter.ViewHolder>
{
public Context mContext;
public List<Replies> mReplies;
public RepliesAdapter(Context mContext, List<Replies> mReplies)
{
this.mContext = mContext;
this.mReplies = mReplies;
}
#NonNull
#Override
public RepliesAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(mContext).inflate(R.layout.all_replies_layout, viewGroup, false);
mAuth = FirebaseAuth.getInstance();
return new RepliesAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position)
{
final Replies replies = mReplies.get(position);
holder.myUserName.setText(replies.getUsername());
holder.myComment.setText(replies.getReply());
holder.myTime.setText(replies.getTime());
}
#Override
public int getItemCount() {
return mReplies.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView myUserName, myComment,myTime;
public ViewHolder(View itemView) {
super(itemView);
myUserName = itemView.findViewById(R.id.reply_username);
myComment = itemView.findViewById(R.id.reply_text);
myTime = itemView.findViewById(R.id.reply_time);
}
}
Related
When sending messages to firebase recycler view reading them but recycler view not updating instantly....i have tried notifyDataSetChanged() but not working.................................................................................................................................................................
MessagingActivity.java
public class MessagingActivity extends AppCompatActivity {
RecyclerView recyclerView;
ImageView ivBack, ivSend;
EditText etTypeMessage;
TextView tvName;
String Receiverphone, image, name;
CircleImageView civProfile;
DatabaseReference reference;
MessagingAdapter adapter;
ArrayList<MessagingBinding> list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messaging);
recyclerView = findViewById(R.id.rv_messagingActivity);
ivBack = findViewById(R.id.ivBack_messagingActivity);
etTypeMessage = findViewById(R.id.etTypeMessage_activityMessaging);
tvName = findViewById(R.id.tvName_activityMessaging);
civProfile = findViewById(R.id.civProfile_messagingActivity);
ivSend = findViewById(R.id.ivSend_activityMessaging);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
image = getIntent().getStringExtra("image");
name = getIntent().getStringExtra("name");
Receiverphone = getIntent().getStringExtra("phone");
tvName.setText(name);
Picasso.get().load(image).into(civProfile);
reference = FirebaseDatabase.getInstance().getReference().child("Users");
ivSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Messages messages = new Messages(etTypeMessage.getText().toString(), name, image, Singleton.obj.phone, Receiverphone);
reference.child("messages").push().setValue(messages);
etTypeMessage.setText("");
adapter.notifyDataSetChanged();
}
});
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(MessagingActivity.this);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(linearLayoutManager);
list = new ArrayList<>();
reference.child("messages").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Messages messages = dataSnapshot.getValue(Messages.class);
if (messages.getSenderphone().equals(Singleton.obj.phone) && messages.getReceiverPhone().equals(Receiverphone)) {
list.add(messages);
}
}
adapter = new MessagingAdapter(list);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
ivBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MessagingActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
}
MessagingAdapter.javastrong text
public class MessagingAdapter extends RecyclerView.Adapter {
private ArrayList<MessagingBinding> bindingList;
public MessagingAdapter(ArrayList<MessagingBinding> bindingList) {
this.bindingList = bindingList;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case (MessagingBinding.TYPE_SENDER):
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_sendermessaging, parent, false);
return new SenderViewHolder(view);
default:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_receivermessaging, parent, false);
return new ReceiverViewHodler(view);
}
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
switch (getItemViewType(position)) {
case (MessagingBinding.TYPE_SENDER):
((SenderViewHolder) holder).bindView(position);
break;
case (MessagingBinding.TYPE_RECEIVER):
((ReceiverViewHodler)holder).bindView(position);
break;
}
}
#Override
public int getItemCount() {
if (bindingList == null) {
return 0;
} else {
return bindingList.size();
}
}
#Override
public int getItemViewType(int position) {
return bindingList.get(position).getType();
}
class SenderViewHolder extends RecyclerView.ViewHolder {
TextView tvSender;
ImageView ivSender;
public SenderViewHolder(#NonNull View itemView) {
super(itemView);
tvSender = itemView.findViewById(R.id.tvSender_listItemsMessaging);
ivSender = itemView.findViewById(R.id.ivSender_listItemMessaging);
}
void bindView(int position) {
SenderMessaging sender = (SenderMessaging) bindingList.get(position);
tvSender.setText(sender.getTvSenderMsg());
ivSender.setImageResource(sender.getImg());
}
}
//-------------------------------ReceiverViewHolder----------------------------------
class ReceiverViewHodler extends RecyclerView.ViewHolder {
TextView tvReceiver;
public ReceiverViewHodler(#NonNull View itemView) {
super(itemView);
tvReceiver = itemView.findViewById(R.id.tvReceiver_listItemsMessaging);
}
void bindView(int position) {
Messages receiver = (Messages) bindingList.get(position);
tvReceiver.setText(receiver.getMessage());
}
}
}
From your code, your messages should be visible when firebase notify you with changes in your db.
Please, try next code:
MessagingActivity
public class MessagingActivity extends AppCompatActivity {
RecyclerView recyclerView;
ImageView ivBack, ivSend;
EditText etTypeMessage;
TextView tvName;
String Receiverphone, image, name;
CircleImageView civProfile;
DatabaseReference reference;
MessagingAdapter adapter;
ArrayList<MessagingBinding> list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messaging);
recyclerView = findViewById(R.id.rv_messagingActivity);
ivBack = findViewById(R.id.ivBack_messagingActivity);
etTypeMessage = findViewById(R.id.etTypeMessage_activityMessaging);
tvName = findViewById(R.id.tvName_activityMessaging);
civProfile = findViewById(R.id.civProfile_messagingActivity);
ivSend = findViewById(R.id.ivSend_activityMessaging);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
image = getIntent().getStringExtra("image");
name = getIntent().getStringExtra("name");
Receiverphone = getIntent().getStringExtra("phone");
tvName.setText(name);
Picasso.get().load(image).into(civProfile);
reference = FirebaseDatabase.getInstance().getReference().child("Users");
ivSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Messages messages = new Messages(etTypeMessage.getText().toString(), name, image, Singleton.obj.phone, Receiverphone);
reference.child("messages").push().setValue(messages);
etTypeMessage.setText("");
}
});
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(MessagingActivity.this);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(linearLayoutManager);
list = new ArrayList<>();
reference.child("messages").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Messages messages = dataSnapshot.getValue(Messages.class);
if (messages.getSenderphone().equals(Singleton.obj.phone) && messages.getReceiverPhone().equals(Receiverphone)) {
list.add(messages);
}
}
adapter = new MessagingAdapter(list);
recyclerView.setAdapter(adapter);
adapter.updateList(list);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
ivBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MessagingActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
And the Adapter:
public class MessagingAdapter extends RecyclerView.Adapter {
private ArrayList<MessagingBinding> bindingList;
public MessagingAdapter(ArrayList<MessagingBinding> bindingList) {
this.bindingList = bindingList;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case (MessagingBinding.TYPE_SENDER):
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_sendermessaging, parent, false);
return new SenderViewHolder(view);
default:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_receivermessaging, parent, false);
return new ReceiverViewHodler(view);
}
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
switch (getItemViewType(position)) {
case (MessagingBinding.TYPE_SENDER):
((SenderViewHolder) holder).bindView(position);
break;
case (MessagingBinding.TYPE_RECEIVER):
((ReceiverViewHodler)holder).bindView(position);
break;
}
}
#Override
public int getItemCount() {
if (bindingList == null) {
return 0;
} else {
return bindingList.size();
}
}
public void updateList(ArrayList<MessagingBinding> messages){
this.bindingList = messages;
this.notifyDataSetChanged();
}
#Override
public int getItemViewType(int position) {
return bindingList.get(position).getType();
}
class SenderViewHolder extends RecyclerView.ViewHolder {
TextView tvSender;
ImageView ivSender;
public SenderViewHolder(#NonNull View itemView) {
super(itemView);
tvSender = itemView.findViewById(R.id.tvSender_listItemsMessaging);
ivSender = itemView.findViewById(R.id.ivSender_listItemMessaging);
}
void bindView(int position) {
SenderMessaging sender = (SenderMessaging) bindingList.get(position);
tvSender.setText(sender.getTvSenderMsg());
ivSender.setImageResource(sender.getImg());
}
}
//-------------------------------ReceiverViewHolder----------------------------------
class ReceiverViewHodler extends RecyclerView.ViewHolder {
TextView tvReceiver;
public ReceiverViewHodler(#NonNull View itemView) {
super(itemView);
tvReceiver = itemView.findViewById(R.id.tvReceiver_listItemsMessaging);
}
void bindView(int position) {
Messages receiver = (Messages) bindingList.get(position);
tvReceiver.setText(receiver.getMessage());
}
}
}
Okay so I have RecyclerView in which I retrieve some data from Firebase realtime database and I have a SearchView which filters my database. Now I want two things
I want an OnClicListener in my activity with which I could open a fragment by clicking on of the items.
I want to apply animation to my RecyclerView every time I scroll down.
Note: The OnClickListener should also work after filtering the data.
So far I am unable to achieve this. Here is my code
Adapter Class -> AdapterClass.java
public class AdapterClass extends RecyclerView.Adapter<AdapterClass.MyViewHolder>{
ArrayList<Deal> list;
public AdapterClass(ArrayList<Deal> list)
{
this.list = list;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_holder,viewGroup,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, final int i) {
myViewHolder.id.setText(list.get(i).getDealId());
myViewHolder.desc.setText(list.get(i).getDealDisc());
}
#Override
public int getItemCount() {
return list.size();
}
static class MyViewHolder extends RecyclerView.ViewHolder{
TextView id,desc;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
id= itemView.findViewById(R.id.dealId);
desc=itemView.findViewById(R.id.description);
}
}
}
Model Class -> Deal.java
public class Deal {
private String dealDisc;
private String dealId;
private String dealImage;
private String price;
public Deal() {
}
public Deal(String dealDisc, String dealId, String dealImage, String price) {
this.dealDisc = dealDisc;
this.dealId = dealId;
this.dealImage = dealImage;
this.price = price;
}
public String getDealDisc() {
return dealDisc;
}
public void setDealDisc(String dealDisc) {
this.dealDisc = dealDisc;
}
public String getDealId() {
return dealId;
}
public void setDealId(String dealId) {
this.dealId = dealId;
}
public String getDealImage() {
return dealImage;
}
public void setDealImage(String dealImage) {
this.dealImage = dealImage;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
Main Activity -> MainActivity.java
public class MainActivity extends AppCompatActivity {
DatabaseReference ref;
ArrayList<Deal> list;
RecyclerView recyclerView;
SearchView searchView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ref= FirebaseDatabase.getInstance().getReference().child("rana");
recyclerView = findViewById(R.id.rv);
searchView=findViewById(R.id.searchView);
}
#Override
protected void onStart() {
super.onStart();
if (ref != null)
{
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists())
{
list = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren())
{
list.add(ds.getValue(Deal.class));
}
AdapterClass adapterClass = new AdapterClass(list);
recyclerView.setAdapter(adapterClass);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(MainActivity.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
if (searchView != null)
{
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
return false;
}
#Override
public boolean onQueryTextChange(String s) {
search(s);
return true;
}
});
}
}
}
private void search(String str) {
ArrayList<Deal> myList = new ArrayList<>();
for (Deal object : list)
{
if (object.getDealDisc().toLowerCase().contains(str.toLowerCase()) || object.getDealId().toLowerCase().contains(str.toLowerCase()))
{
myList.add(object);
}
}
AdapterClass adapterClass = new AdapterClass(myList);
recyclerView.setAdapter(adapterClass);
}
}
myViewHolder.id.setonclickListener()
I'm trying to print the position of RecyclerView in logcat when I click on the list of recyclerView, but it's not printing anything. Actually in this app, if I click on a position of the recyclerview, that should take me to new activity and grab all the details of that position on which I clicked.
Here is my ImageAdapter.java class
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {
private Context mContext;
private List<UserDetails> mUploads;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
public ImageAdapter(Context context, List<UserDetails> uploads) {
mContext = context;
mUploads = uploads;
}
#NonNull
#Override
public ImageViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(mContext).inflate(R.layout.user_display, viewGroup, false);
return new ImageViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull ImageViewHolder imageViewHolder, int i) {
UserDetails currentItem = mUploads.get(i);
UserDetails userDetails = mUploads.get(i);
imageViewHolder.requestId.setText("Request Id : " + userDetails.getMobileNumber());
imageViewHolder.customerName.setText(userDetails.getName());
imageViewHolder.customerMobile.setText("Mobile : " + userDetails.getMobileNumber());
imageViewHolder.customerAddress.setText(userDetails.getAddress());
}
#Override
public int getItemCount() {
return mUploads.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder {
public TextView requestId, customerName, customerAddress, customerMobile, serviceType, date;
public ImageViewHolder(#NonNull View itemView) {
super(itemView);
requestId = itemView.findViewById(R.id.requestId);
customerName = itemView.findViewById(R.id.customerName);
customerAddress = itemView.findViewById(R.id.customerAddress);
customerMobile = itemView.findViewById(R.id.customerMobile);
serviceType = itemView.findViewById(R.id.serviceType);
date = itemView.findViewById(R.id.date);
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);
}
}
}
});
}
}
}
and here is the recyclerView class
public class requestList extends AppCompatActivity implements ImageAdapter.OnItemClickListener {
RecyclerView recyclerView;
DatabaseReference databaseReference;
List<UserDetails> downloadDataArray;
ImageAdapter adapter;
ProgressBar progressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_request_list);
progressBar = findViewById(R.id.progressBar);
Toolbar toolbar = findViewById(R.id.roServiceToolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Requests");
toolbar.setNavigationIcon(R.drawable.back);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(requestList.this, customerRequests.class));
}
});
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
downloadDataArray = new ArrayList<>();
databaseReference = FirebaseDatabase.getInstance().getReference("Service Request/RO Service");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
downloadDataArray.clear();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
UserDetails userDetails = postSnapshot.getValue(UserDetails.class);
downloadDataArray.add(userDetails);
}
adapter = new ImageAdapter(requestList.this, downloadDataArray);
getSupportActionBar().setTitle("Requests" + "(" +adapter.getItemCount()+ ")");
recyclerView.setAdapter(adapter);
progressBar.setVisibility(View.INVISIBLE);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#Override
public void onItemClick(int position) {
Log.i("Position", String.valueOf(position));
}
}
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mListener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
//print log message
}
}
}
});
Because you are not assigning the value of mListener. Add this line after initialize adapter object.
adapter.setOnItemClickListener(this)
I do not know how to filter results from RecyclerView which is being displayed in Fragment.
If possible, I want to merge some of these codes into one java file.
i have searched on Google for some examples, but most of them are implemented in Activity instead.
My fragment code :
public class SearchFragment extends Fragment {
private RecyclerView recyclerView;
private AdvertiseAdapter advertiseAdapter;
private List<Advertise> advertiseList;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_search,container,false);
recyclerView = view.findViewById(R.id.searchResult_view);
new DatabaseHelper().readProperty(new DatabaseHelper.DataStatus() {
#Override
public void DataIsLoaded(List<Advertise> advertiseList, List<String> keys) {
new RecyclerViewConfig().setConfig(recyclerView,getContext(),advertiseList,keys);
}
});
return view;
}
My DatabaseHelper
public class DatabaseHelper {
private FirebaseDatabase firebaseDatabase;
private DatabaseReference reference;
private List<Advertise> property = new ArrayList<>();
public interface DataStatus{
void DataIsLoaded(List<Advertise> ads,List<String> keys);
}
public DatabaseHelper() {
firebaseDatabase = FirebaseDatabase.getInstance();
reference = firebaseDatabase.getReference("Property");
}
public void readProperty(final DataStatus dataStatus){
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
property.clear();
List<String> propertyKeys = new ArrayList<>();
for (DataSnapshot userSnapshot : dataSnapshot.getChildren()){
for (DataSnapshot propertySnapshot : userSnapshot.getChildren()){
propertyKeys.add(propertySnapshot.getKey());
Advertise advertise = propertySnapshot.getValue(Advertise.class);
property.add(advertise);
}
}
dataStatus.DataIsLoaded(property,propertyKeys);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
My RecyclerViewConfig code :
public class RecyclerViewConfig {
private Context mContext;
private PropertyAdapter propertyAdapter;
public void setConfig(RecyclerView recyclerView, Context context, List<Advertise> advertiseList, List<String> keys){
mContext = context;
propertyAdapter = new PropertyAdapter(advertiseList,keys);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(propertyAdapter);
}
class PropertyItemView extends RecyclerView.ViewHolder{
//private ImageView PropertyImage;
private TextView PropertyName;
private TextView PropertyPostal;
private TextView PropertyState;
private TextView PropertyDetail;
private String key;
public PropertyItemView(ViewGroup parent){
super(LayoutInflater.from(mContext)
.inflate(R.layout.search_view,parent,false));
//PropertyImage = itemView.findViewById(R.id.advertiseImage);
PropertyName = itemView.findViewById(R.id.advertiseName);
PropertyState = itemView.findViewById(R.id.advertiseState);
PropertyPostal = itemView.findViewById(R.id.advertisePostal);
PropertyDetail = itemView.findViewById(R.id.advertiseDetail);
}
public void bind(Advertise advertise,String key){
//PropertyImage.setImageDrawable(advertise.getProperty_imageUrl());
PropertyName.setText(advertise.getName());
PropertyState.setText(advertise.getState());
PropertyPostal.setText(advertise.getPostal());
PropertyDetail.setText(advertise.getDetail());
this.key = key;
}
}
class PropertyAdapter extends RecyclerView.Adapter<PropertyItemView>{
private List<Advertise> advertiseList;
private List<String> mkeys;
public PropertyAdapter(List<Advertise> advertiseList, List<String> mkeys) {
this.advertiseList = advertiseList;
this.mkeys = mkeys;
}
#NonNull
#Override
public PropertyItemView onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new PropertyItemView(parent);
}
#Override
public void onBindViewHolder(#NonNull PropertyItemView holder, int position) {
holder.bind(advertiseList.get(position),mkeys.get(position));
final Advertise ads = advertiseList.get(position);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent redirect = new Intent(mContext,PropertyActivity.class);
redirect.putExtra("propertyID", ads.getPropertyID());
mContext.startActivity(redirect);
}
});
}
#Override
public int getItemCount() {
return advertiseList.size();
}
public void updateList(List<String> newList){
mkeys = new ArrayList<>();
mkeys.addAll(newList);
notifyDataSetChanged();
}
}
I am currently working on a chat app. In chat activity, I wanted to show profile picture only on the first item and when I used Runnable (onItemChanged) it slowed down my recycler view very much and now it looks like I added motion blur to my recycler view and it is very very lazy.
Here is a gif of my chat activity:
https://i.gyazo.com/f0489ca7fe9ad28519061c0ff8963fb4.gif
Im not actually sure that it is Runnable that slows down my recycler view but when I remove :
if (i > 0)
if (mMessageList.get(i - 0).getFrom().equals(mMessageList.get(i).getFrom())) {
makeDPInvisible(i - 0);
}
if (invisibleIds.contains(i)) {
viewHolder.displayName.setVisibility(View.GONE);
viewHolder.profileImage.setVisibility(View.INVISIBLE);
}
and
private void makeDPInvisible(final int i) {
invisibleIds.add(i);
recyclerView.post(new Runnable(){
#Override
public void run() {
notifyItemRangeChanged(i);
}
});
}
my recycler is very smooth and without any problems...
Here is my MessaageAdapter.java
/**
* Created by Aryojj on 24/07/17.
*/
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MessageViewHolder>{
private FirebaseAuth mAuth;
private ArrayList<Integer> invisibleIds = new ArrayList<>();
private RecyclerView recyclerView;
private List<Messages> mMessageList;
private DatabaseReference mUserDatabase;
public MessageAdapter(List<Messages> mMessageList) {
this.mMessageList = mMessageList;
}
#Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.message_single_layout ,parent, false);
mAuth = FirebaseAuth.getInstance();
return new MessageViewHolder(v);
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
this.recyclerView = recyclerView;
}
public class MessageViewHolder extends RecyclerView.ViewHolder {
public TextView messageText;
public CircleImageView profileImage;
public TextView displayName;
public ImageView messageImage;
public MessageViewHolder(View view) {
super(view);
messageText = (TextView) view.findViewById(R.id.message_text_layout);
profileImage = (CircleImageView) view.findViewById(R.id.message_profile_layout);
displayName = (TextView) view.findViewById(R.id.name_text_layout);
messageImage = (ImageView) view.findViewById(R.id.message_image_layout);
}
}
#Override
public void onBindViewHolder(final MessageViewHolder viewHolder, int i) {
String message_sender_id = mAuth.getCurrentUser().getUid();
Messages c = mMessageList.get(i);
String from_user = c.getFrom();
String message_type = c.getType();
if (i > 0)
if (mMessageList.get(i - 0).getFrom().equals(mMessageList.get(i).getFrom())) {
makeDPInvisible(i - 0);
}
if (invisibleIds.contains(i)) {
viewHolder.displayName.setVisibility(View.GONE);
viewHolder.profileImage.setVisibility(View.INVISIBLE);
}
mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(from_user);
mUserDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name = dataSnapshot.child("name").getValue().toString();
String image = dataSnapshot.child("thumb_image").getValue().toString();
viewHolder.displayName.setText(name);
Picasso.with(viewHolder.profileImage.getContext()).load(image)
.placeholder(R.drawable.default_avatar).into(viewHolder.profileImage);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
if (message_type.equals("text")) {
viewHolder.messageText.setText(c.getMessage());
viewHolder.messageImage.setVisibility(View.INVISIBLE);
} else {
viewHolder.messageText.setVisibility(View.INVISIBLE);
Picasso.with(viewHolder.profileImage.getContext()).load(c.getMessage())
.networkPolicy(NetworkPolicy.OFFLINE).placeholder(R.drawable.default_avatar).into(viewHolder.messageImage);
}
}
private void makeDPInvisible(final int i) {
invisibleIds.add(i);
recyclerView.post(new Runnable(){
#Override
public void run() {
notifyItemRangeChanged(i);
}
});
}
#Override
public int getItemCount() {
return mMessageList.size();
}
}