How to sort RecyclerView item in android - android

I'm working on a android chatting application. When I called my api it returns me the chat list sorted by a user_id. But what I need to do is serialized by message_id as I want to show last message first.Here is my onBindViewHolder method in which i get the values.
public void onBindViewHolder(final MyAdapter_HomeViewHolder holder, final int position) {
holder.userNameTV.setText(data.get(position).getUserInfo().getFullName());
holder.msgBodyTV.setText(data.get(position).getBody());
holder.originator_iD.setText(data.get(position).getUserInfo().getId().toString());
//message ID. I need to serialize my recyclerView by this ID.biggest id should appear first.
holder.messageId.setText(data.get(position).getId().toString());
holder.owner_type_ET.setText("1");
holder.subject_ET.setText("Message");
}
In case of you need to see the full code, https://pastebin.com/Zxmq36Gn

try this before passing your list to the adapter (after API call and before adapter notifydatasetchanged):
Collections.sort(data, new Comparator<CustomData>() {
#Override
public int compare(CustomData lhs, CustomData rhs) {
// -1 - less than, 1 - greater than, 0 - equal, all inversed for descending
return lhs.getId() > rhs.getId() ? -1 : (lhs.customInt < rhs.customInt ) ? 1 : 0;
}
});

in Kotlin use like this after loading data in array:
myItems.sortWith(Comparator { lhs, rhs ->
// -1 - less than, 1 - greater than, 0 - equal, all inversed for descending
if (lhs.name > rhs.name) -1 else if (lhs.id < rhs.id) 1 else 0
})
After that apply:
myItemAdapter.notifyDataSetChanged()

A simpler solution for someone still stuck on the same
Collections.sort(data, new Comparator<CustomData>() {
#Override
public int compare(CustomData lhs, CustomData rhs) {
return Integer.compare( rhs.getId(),lhs.getId());
}
});
YourAdapter adapter = new YourAdapter(context, data);
//Setup Linear or Grid Layout manager
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);

Before passing the data to RecyclerView adapter
data.sort(new Comparator<Datum>() {
#Override
public int compare(Datum o1, Datum o2) {
return o1.get(position).getMessageId().compareTo(o2.get(position).getMessageId());
}
});
then pass (notify) the sorted list to the adapter.

Add this lines of code before passing to RecyclerView Adapter
Collections.sort(yourLists, new Comparator<YourList>() {
#Override
public int compare(YourList lhs, YourList rhs) {
return lhs.getId().compareTo(rhs.getId());
}
});

Collections.sort(response.body(), new Comparator<All_posts>() {
#Override
public int compare(All_posts lhs, All_posts rhs) {
if(lhs.getId() > rhs.getId()) {
return -1;
} else {
return 1;
}
}
});
"response.body" is the arraylist I got from json, this is what I pass
to the recycler view adapter,
"All_posts" is the "Model" class, the one which contains only fields;
And getId is the value I want comparison to take place on it, it's from my model class,
I wrote this before I set my adapter to my recycler view.
and after I set my adpater to my recyclerView, I wrote recyclerView.getAdapter().notifyDataSetChanged();

List<Items_Detail_model>items_model;
Collections.sort(items_model, new Comparator<Items_Detail_model>() {
#Override
public int compare(Items_Detail_model o1, Items_Detail_model o2) {
return o1.getDate().compareTo(o2.getDate());
}
});

Try this before giving list to adapter
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Collections.sort(yourList, Comparator.comparing(YourModel::getFileSize));
}

Related

Load the first item after the first item in recyclerview

I need to implement the recyclerview with functionality as to display the first item after last like circle
Suggest you to try following changes in your adapter class. Set getItemCount to return a very large value like Integer.MAX_VALUE
#Override
public int getItemCount() {
return Integer.MAX_VALUE;
}
Then to get the actual item position need a modulus operation
#Override
public void onBindViewHolder(ActionItemViewHolder holder, int position) {
position = position % SIZE_OF_LIST;
};

RecyclerView using DiffUtil, prevent to scroll bottom on change

I have a problem with my recyclerViev, specifically with the scrolling.
I have some list, which is updated in real time, some item is added, some removed, and everything is sorted by some parameter.
So the item which was initially first on the list, can have its parameter changed, which will be in different position after the sorting.
So my recyclerView is for example focusing on the initial item, and after change, when some item has "better" parameter is changing position with that initial item.
Problem is, i want to focus on the new item, with "better" parameter when I'm not scrolling, but i don't want to focusing on it when i scroll by touch(so my touch will not be interrupted by scrolling to current first item on the list).
So i don't want to force this code after every change in my recyclerView data:
recyclerView.scrollToPosition(0);
because as i said, i will be interrupted by this scroll when i am touching my recyclerView list and go down to see other items and in the same time there will be a change in my list.
Is there a way to accomplish this?
To be specific, i am using DiffCallback from the DiffUtil, to support animations when there is a change in my current recyclerView list - it compares the old list with another new list and apply all the wanted animations and notifications(item added, removed, changed position). So i never call
notifyDataSetChanged
or anything like that
Here is my DiffUtil callback:
public static class DevicesDiffCallback extends DiffUtil.Callback{
List<DeviceInfo> oldDevices;
List<DeviceInfo> newDevices;
public DevicesDiffCallback(List<NexoDeviceInfo> newDevices, List<NexoDeviceInfo> oldDevices) {
this.newDevices = newDevices;
this.oldDevices = oldDevices;
}
#Override
public int getOldListSize() {
return oldDevices != null ? oldDevices.size() : 0;
}
#Override
public int getNewListSize() {
return newDevices != null ? newDevices.size() : 0;
}
#Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return oldDevices.get(oldItemPosition).getNexoIdentifier().getSerialNumber().equals(newDevices.get(newItemPosition).getNexoIdentifier().getSerialNumber());
}
#Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return oldDevices.get(oldItemPosition).equals(newDevices.get(newItemPosition));
}
#Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
return super.getChangePayload(oldItemPosition, newItemPosition);
}
}
And i set it like this in my adapter, when i get the list of new data to be populated and replace the old data:
public void setData(List<DeviceInfo> data) {
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DevicesDiffCallback(this.mData, data), false);
diffResult.dispatchUpdatesTo(this);
mData = data;
}
I'm not sure about this answer but, I think your code to call DiffUtil is not proper. Try using this :
public void addItems(List<Recipe> recipeList) {
List<Recipe> newRecipeList = new ArrayList<>();
newRecipeList.addAll(this.recipeList);
newRecipeList.addAll(recipeList);
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new RecipeDiffUtilCallback(this.recipeList, newRecipeList));
this.recipeList.addAll(recipeList);
diffResult.dispatchUpdatesTo(this);
}

An android DiffUtils shortcoming

I find that all the information about DiffUtil on the internet is about how to use DiffUtil.
Is there any one who considers that using DiffUtil leads to large memory consuming?
If i have a list of 5000 objects(for example: post) in it, then i scroll RecyclerView and load 40 objects more. This means memory hold two lists(old list contains 5000 objects and new list contains 5040 objects) if using DiffUtil. So when loading data, the app consumes memory largely.
The way may solve this problem is that don't hold two lists. Showing as below:
DiffUtil.DiffResult recyclerViewDiff = DiffUtil.calculateDiff(new DiffUtil.Callback() {
#Override
public int getOldListSize() {
return oldelist.size();
}
#Override
public int getNewListSize() {
return oldlist.size() + increasedData.size();
}
#Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
boolean isIncreaseDataPos = newItemPosition >= oldlist.size();
newItemPosition = !isIncreaseDataPos ? newItemPosition : newItemPosition - oldlist.size();
Object newItem = !isIncreaseDataPos ? oldlist.get(newItemPosition) : increaseData.get(newItemPosition);
return oldlist.get(oldItemPosition).equals(newItem);
}
#Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return ...;
}
});
But what if i change the item in list(not add more data)? Is there any way to use DiffUtil without holding two lists to update view except using notifyItemChanged(position) by myself?

how to sort custom item bean array list in alphabetical order in android

Actually I have a list view , how can I sort list items alphabetical order how can i change positions based on name of items.
By using array list we can do but how can we do sort for bean list
Listview:
ItemsBean bean1 = new ItemsBean();
bean1.setItemnNameDisplay(items.getString("Prodname"));
bean1.setParentobjectid(items.getString("ParentObjectID"));
bean1.setObjectid(items.getString("ObjectID"));
bean1.setQuantityDisplay(items.getInt("Quantity"));
bean1.setProdnum(items.getInt("ProdNum"));
bean1.setLinenum(line);
itemsList1.add(bean1);
In ItemBean class implement Comparable interface and override compareTo() method:
class ItemsBean implements Comparable{
#Override
public int compareTo(Object o) {
ItemsBean item = (ItemsBean) o;
return this.itemnNameDisplay.compareTo(item.itemnNameDisplay);
}
}
Collections.sort(swaplistswap, new Comparator() {
public int compare(ItemsBean one, ItemsBean other) {
return one.getItemnNameDisplay().compareTo(other.getItemnNameDisplay());
// return one.getQuantityDisplay()-(other.getQuantityDisplay());
}
});

Multiple RecyclerViews and adapter data offset

I have multiple RecyclerViews using common RecyclerView.Adapter. Is there is some way to tell RecyclerView to get data from adapter using some offset? Something like 1st view gets 0-15 items from adapter, 2nd view gets 15-30 and so on.
Give the position and and the Object List to the Fragment inside your viewpager at FragmentStatePagerAdapter :
#Override
public Fragment getItem(int position) {
return YourFragment.newInstance(position,yourListOfObjects);
}
Then inside your YourFragment according to position take 15 items from the List and make a adpater, example with RxJava, but you can modify it, to work with regular Java:
int positionOfFragment;
List<Product> list;
Observable
.just(list)
.take(positionOfFragment*15)
.subscribe(new Action1<List<Product>>() {
#Override
public void call(List<Product> orders) {
ProductAdapter adapter = new ProductAdapter(orders, getActivity());
//setAdapter to RecyclerView;
}
});
You mean something like ExpandableListView?
EDITED:
Try this.
Create separate data structure for filtered data at required positions
private List<Object> data;
private List<Object> dataToShow;
public CustomAdapter(List<Object> data){
this.data = data;
this.dataToShow = new ArrayList<>(data);
}
...in all overriden methods use dataToShow field
create method to filter data
public void showDataAtPositions(int startPos, int endPos){
dataToShow.clear();
for(int index = 0; index < data.size(); index++){
if(index >=startPos && index <= endPos){
dataToShow.add(data.get(index));
}
}
notifyDataSetChanged();
}
then just call this method
adapter.showDataAtPositions(0, 15);
adapter.showDataAtPositions(16, 30);
this should work

Categories

Resources