I want display badge in latest item on recyclerview and after clicking on it, its visibility is gone. Please help me
My code is here:
public void onBindViewHolder(ViewHolder Viewholder, int position) {
SubCategory_Model_List dataAdapterOBJ = dataAdapters.get(position);
if(position==dataAdapters.size()-1){
// here goes some code
// callback.sendMessage(Message);
Viewholder.triangleLabelView.setVisibility(View.VISIBLE);
}
Picasso.with(context)
.load(dataAdapterOBJ.getImageUrl())
.placeholder(R.drawable.default_placeholder)
.into(Viewholder.imageView);
Viewholder.ImageTitleTextView.setText(dataAdapterOBJ.getImageTitle());
}
The logic written by you is fine it should work all you need to do is to add else block and write like
else {
Viewholder.triangleLabelView.setVisibility(View.GONE);
}
and just add an onclicklistener in the
viewholder.item.setOnclickListener(new View.OnClickListener{
add your visibility code over here.
please manage your logic.
})
Suppose you have a MessageModel and in this class you have some property like:
class MessageModel{
String body;
int itemId;
boolean isNew;
}
You have messageList in your adapter. So when you get new message before adding in your adapterList you have to update your new messageModel
Think in your activity/fragment class you get new message Like:
#ovveride
onGetNewMessage(MessageModel message){
message.setNew(true);
mAdapter.addItem(message);
notifyDataSetChnaged();
}
Now in your adapter class onBindViewHolder section you have to update your UI like:
if(message.isNew()){
// view will be visible
}else{
// view will be gone
}
Now Last things is to update message as old. So when you click your message you still have messageModel reference in your adapter class. add below things in your onCLick method.
message.setNew(false);
notifyItemChanged(position);
Related
Suppose I have a recyclerView Adapter which is used to populate views including imageView . When i first load adapter then recycler view items are getting displayed properly . But if i update imageView and textview resource in adapter datasource and call notifyDataSetChanged() method then only textview is getting updated and not imageView . Can anyone help me with this ? Thanks in advance .
For Example - This is the first time i add all the elements in an empty arraylist inside fragment and update using notifyDataSetChanged() method . Till now everything is fine and images are loading correctly in adapter .
Below is the getMethod()
if(remindersListResponse.code == 200)
{
if(remindersListResponse.data != null)
{
photoContactList.clear();
photoContactList.addAll(remindersListResponse.data);
photoContactsAdapter.notifyDataSetChanged();
}
}
Now if i call getMethod again on click of some button in fragment and use notifyDataSetChanged() method . Then only text gets updated in adapter items but not images instead they get disappear .
This is my adapter onBindViewHolder(...) method
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, int i) {
final PhotoContactsResponse.Result photoContactDetail = photoContactList.get(i);
viewHolder.photoContactName.setText(photoContactDetail.name);
if(photoContactDetail.image!=null && !photoContactDetail.image.isEmpty()) {
viewHolder.addPhotoText.setVisibility(View.GONE);
Picasso.with(context)
.load(Constants.WEB_SERVICE_BASE_URL_FOR_IMAGE+photoContactDetail.image)
.networkPolicy(NetworkPolicy.NO_CACHE)
.memoryPolicy(MemoryPolicy.NO_CACHE)
.into(viewHolder.photoContactImage);
}
else
{
viewHolder.addPhotoText.setVisibility(View.VISIBLE);
viewHolder.photoContactImage.setVisibility(View.GONE);
}
}
This is my model class
public static class Result{
public int id;
public String name;
public String number;
public String image;
public int index;
}
I was running into this same issue and fixed it by setting the recycle view's adapter to null, then to my adapter again. See: Force RecyclerView to redraw its items
I think you forgot to set ImageView as VISIBLE. When you hide it in else statement you should always bring it back when image is available. onBindViewHolder only binds data to view. Recycler views are reused between calls to onBindViewHolder method.
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, int i) {
final PhotoContactsResponse.Result photoContactDetail = photoContactList.get(i);
viewHolder.photoContactName.setText(photoContactDetail.name);
if(photoContactDetail.image!=null && !photoContactDetail.image.isEmpty()) {
viewHolder.addPhotoText.setVisibility(View.GONE);
viewHolder.photoContactImage.setVisibility(View.VISIBLE); // <== ADD THIS LINE
Picasso.with(context)
.load(Constants.WEB_SERVICE_BASE_URL_FOR_IMAGE+photoContactDetail.image)
.networkPolicy(NetworkPolicy.NO_CACHE)
.memoryPolicy(MemoryPolicy.NO_CACHE)
.into(viewHolder.photoContactImage);
}
else
{
viewHolder.addPhotoText.setVisibility(View.VISIBLE);
viewHolder.photoContactImage.setVisibility(View.GONE);
}
}
Does anyone knows how to access adapter imageView inside activity to hide the view. Please specify any example.
I hope this will work for you.
By using SharedPreferences we can easily hide the view from activity or fragment.
Save flag in SharedPreferences i.e true from activity.
If you are using Recyclerview then in onBindViewHolder method check condition
if(flag==true){
holder.yourView.setVisibility(View.GONE);
}else{
holder.yourView.setVisibility(View.VISIBLE);
}
Go to onBindViewHolder of the adapter and take the id of your imageview and code like this
holder.mImgVw.setVisibility(View.GONE);
You should not directly interact with the ImageView, instead you can use notifyItemChanged() to update the ImageView state in the Adapter. But, you need to slightly modify your Adapter code by adding a flag in your model data or using SparseBooleanArray as a mechanism to saving the ImageView state.
Here the example:
public class Adapter ... {
private SparseBooleanArray mSelectedItems;
private List<YourModel> mItems;
public Adapter(List<YourModel> items) {
mItems = items;
mSelectedItems = new SparseBooleanArray();
}
...
public void onBindViewHolder(....) {
int itemPosition = viewHolder.getAdapterPosition();
YourModel item = items.get(itemPosition);
boolean visible = mSelectedItems.get(itemPosition);
viewHolder.imageView.setVisibility(visible? View.VISIBLE: View.GONE);
...
}
public void setItemVisibilityByPosition(int position, boolean visible) {
mSelectedItems.put(position, visible);
notifyItemChanged(position);
}
}
You can change the image visibility with:
// Assume the mAdapter is your Adapter
mAdapter.setItemVisibilityByPosition(5, true);
I am having a RecyclerView which is populating list of objects.Each object has one image and a comment. I want to update the comment on a specific row. I dont want to refresh the whole RecyclerView's Adapter. I just want to update or refresh that specific row. How can I achieve it? Below is my implementation. Am I doing it write ?
This method is in my Adapter: UPDATED
public void updateComment(String comment,int position){
this.mList.get(position).setCommentText(comment);
notifyItemChanged(position,this.mList);
}
From my Activity I am calling the above method like this:
adapter.updateComment("Great",1);
UPDATE:
As per the suggestion by pskink. I implemented this:
#Override
public void onBindViewHolder(CellViewHolder holder, int position, List<Object> payloads) {
if(payloads.isEmpty()){
super.onBindViewHolder(holder,position,payloads);
}else{
for (Object payload : payloads) {
if (payload instanceof MyMemo) {
holder.bindComment((MyMemo) payload);
}
}
}
}
The bindComment() method in my ViewHolder:
private void bindComment(MyMemo payload) {
comment.setText(payload.getCommentText());
}
I try to update just one specific item after a "basic action" (like a tap on one item) in my recycler view, but the method notifyItemChanged seems to doesn't work as expected.
Actually, the method onBindViewHolder is correctly called, and datas that I want to change in my item is correctly done. BUT, I see nothing changing in my view. I don't understand why...
My code :
- MyFragment
private void initRecyclerView() {
_recyclerView = (RecyclerView) _rootView.findViewById(R.id.recyclerView);
_recyclerView.setHasFixedSize(true);
_layoutManager = new LinearLayoutManager(getActivity());
_recyclerView.setLayoutManager(_layoutManager);
_adapter = new MyAdapter(datas, this, getContext());
_recyclerView.setAdapter(_adapter);
}
When an item is selected, I call "_adapter.update(position)" in my fragment. And so in my adapter I've this :
-Adapter
public void updateItem(int position) {
notifyItemChanged(position);
}
After this call I can see that the method OnBindViewHolder is correctly call, but nothing is changed on the view :(
EDIT : code of onBindViewHolder :
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
MyOBject object = datas.get(position);
holder.text1.setText(object.getValue1());
holder.text2.setText(object.getValue2());
if (object.getLastTimeItemClicked() != null && object.getLastTimeItemClicked().compareTo(object.getLastTimeNewContent()) > 0) {
Log.d("test", "item clicked, content changed")
holder._backgroundItem.setCardBackgroundColor(_context.getResources().getColor(bgItemRead)); // I see this log after a tap on one item, so this code is working!
}
}
EDIT 2 : I'm using tabs, maybe there is something to manage with that ?! (In each fragments linked to each tabs, there is a recycler view etc managed by a fragment)
I have an android activity that consists of a List View and a Text View. The Text view displays information about the summed contents of the list view, if the items in the list view are updated then the Text View needs to reflect the change.
Sort of like an observer pattern but with one component reflecting the changes of many rather than the other way round.
The tasks are displayed as items in the list view and the progress can be updated using a seekbar to set the new progress level.
The following method populates the TextView so I need to call this again from inside the SeekBar onStopTrackingProgress Listener.
private void populateOverviewText() {
TextView overview = (TextView) findViewById(R.id.TaskOverview);
if (!taskArrayList.isEmpty()) {
int completion = 0;
try {
completion = taskHandler.getProjectCompletion();
overview.setText("Project Completion = " + completion);
} catch (ProjectManagementException e) {
Log.d("Exception getting Tasks List from project",
e.getMessage());
}
}
}
I realise if I want to call the method from the List Adapter then I'll need to make the method accessible but I'm not sure the best approach to do this.
Either make this method public
or you can pass activity to adapter through which you can find the button and update text, or can directly pass Button to adapter...
Using DataSetObserver
I was looking for a solution that didn't involve altering the adapter code, so the adapter could be reused in other situations.
I acheived this using a DataSetObserver
The code for creating the Observer is incredibly straight forward, I simply add a call to the method which updates the TextView inside the onChanged() method.
Attaching the Observer (Added to Activity displaying list)
final TaskAdapter taskAdapter = new TaskAdapter(this, R.id.list, taskArrayList);
/* Observer */
final DataSetObserver observer = new DataSetObserver() {
#Override
public void onChanged() {
populateOverviewText();
}
};
taskAdapter.registerDataSetObserver(observer);
Firing the OnChanged Method (Added to the SeekBar Listener inside the adapter)
public void onStopTrackingTouch(SeekBar seekBar) {
int progress = seekBar.getProgress();
int task_id = (Integer) seekBar.getTag();
TaskHandler taskHandler = new TaskHandler(DBAdapter
.getDBAdapterInstance(getContext()));
taskHandler.updateTaskProgress(task_id, progress);
mList.get(position).setProgress(progress);
//need to fire an update to the activity
notifyDataSetChanged();
}