how to get data from bottom to top from firebase? - android

I'm trying to get data from bottom to top (from the last item uploaded to the first item uploaded like Instagram) but I couldn't make this. I searched a lot and found this answer here.
I made it with firebaseRecyclerAdapter and worked fine but with custom Adapter I couldn't do it!
here is the method I used:
#Override
public ItemsRecyclerView getItem(int pos){
return super.getItem(getCount() - 1 - pos);
}

What you should be doing is reversing the recyclerview, forget about the method that you used above.
And do this when you set your recycler view:
LinearLayoutManager manager = new LinearLayoutManager(context);
manager.setReverseLayout(true);
manager.setStackFromEnd(true);
recycler_View.setLayoutManager(manager);
Possible solution:
try this:
Maybe try to reverse the list that you pass to your adapter like this:
//your list
List<model> your_list = new ArrayList()<>;
//before you pass it to the adapter do this
Collections.reverse(your_list);
//now your list is reversed, pass it to the adapter
Adapter adapter = new Adapter (your_list,.....,....);

Related

Staggered Grid LayoutManager Stack from end

I am trying to make a application that displays data in list using RecyclerView, In LinearLayoutManager there is a option to set Stack from end and reverse layout that allows for me to show the newest data on top of list. Is there anyway I can show the newest data at position 0 (at top) in staggered grid layout?
StaggeredGridLayoutManager has the method setReverseLayout.
Use it like this:
mLayoutManager = new StaggeredGridLayoutManager(getActivity());
mLayoutManager.setReverseLayout(true);
You can use GridLayoutManagaer. In constructor you can pass true/false to reverse layout or can use setReverseLayout(boolean) method. check this
You can scroll to the end after updating(inserting) you data (when it's needed)
private void updateData(#NonNull List<Item> items, boolean moveToTheEnd) {
adapter.updateItems(items);
if(moveToTheEnd) {
recyclerView.scrollToPosition(adapter.getItemCount() - 1);
}
}
The solution that worked for me, without having those spaces at the beginning, is to add this line at the beginning of your onBindViewHolder method in your adapter:
position = getItemCount()-1-position;
So your code will be something like this:
#Override
public void onBindViewHolder(#NonNull MyAdapter.ViewHolder holder, int position) {
position = getItemCount()-1-position;
holder.textView.setText(mObjects.get(position).getText());
}

Loading a new ViewHolder based on click event

Within RecyclerView, any tips on loading a different viewholder onitemclick? i'm having trouble wrapping my head around loading viewholder 2 when item is clicked in viewholder 1 at that position. both viewholder 1 and 2 are a list of cards. so say for example. vh1 contains a sample hotel image. When you click that vh2 shows you contact details of that hotel - at that position, while retaining vh1 through out the other un-clicked contents.
I did ask a question like this before and i think it was a bit vague so people suggested i change information based onitem click. The problem is vh1 and 2 are different layouts completely so this wouldn't work for what i'm working on.
is this even possible?
Thanks
You can create another adapter for your RecyclerView. Create a new Java class, call it whatever you want. In your main activity, or the activity where you're setting your adapter, you can create a function like this:
public void setNewAdapter() {
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.your_recyclerview_id);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
NewAdapter adapter = new NewAdapter(// any arguments);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
In your adapter, you can create a new instance of your activity. For example, if you're activity is called MainActivity, you can add this code in your onItemClick:
MainActivity mainActivity = new MainActivity();
mainActivity.setNewAdapter();
See if that works.

Android: Recyclerview adapter inside recyclerview adapter. How to update data of inside recylcerview?

I got a recylcerview, which has another recylcerview as an element of it. However, i am confused how to update data of the inside recylcerview. How should I do it?
I don't know if this will work for you because i don't have your code, but you can create a updateAdapter , inside of it you must refresh everything.
For example we have 2 arrayList:
private void updateAdapter() {
this.mItems = c.getArray();
this.mItemsNr = c.getNr();
//and call notifyDataSetChanged
notifyDataSetChanged();
}
mItems and MItemsNr are 2 arrayList and c is an object where i have the 2 new arrayList.So i update the 2 arrayList and hten i call notifyDataSetChenged(); to update my adapter.
Hope this could help you.

Android RecyclerView infinity scrolling: how to add more items to dataset

I have implemented my RecyclerView and even added an onscrolllistener to support infinity scrolling and now I'm stuck with a, hopefully, easy problem: How can I add the newly loaded data to the existing dataset?
My current approach: I create a new array with the length of the existing dataset + the length of the newly loaded data. I System.arraycopy my existing dataset and add the new content with a for-loop.
This works but the list is always reset (scrolls back to the top) and I assume my way to add additional content is overly complicated/wrong, though the tutorials I have looked at seem to pass over this "detail".
Update: I'm currently calling "scrollToPosition" on the UI-Thead after the data has been loaded, but I doubt this is the correct way of doing this or am I wrong?
You shouldn't be adding stuff to your dataset, you will sooner or later run out of memory. What you can do is return a big number (I used Short.MAX_VALUE) item in getItemCount inside your adapter and in the method that requests a view for postion you should do position % list.size();
It is not a truly endless RecyclerView this way, but good enough. I will paste some code tomorrow, I don't have it here now :/
I think you have to add items inside your adapter. Let`s say
class Adapter extends Recycler.Adapter<Recycler.ViewHolder>{
List<YourCustomObject> list;
public Adapter(){
list = new ArrayList<>();
}
public void addItem(YourCustomObject item){
list.add(item);
notifyItemDateSetChanged(); //This method for adapter to notice that list size have been changed
}
// Here your views
}
There is implementation of Your fragment or Activity where you retrieve data from internet.Let` say
class MainActivity extends AppCompactActivity{
Adapter adapter = new Adapter();
List<YourCustomObjects> objects;
public void onCreateView(){
//////// Something yours
}
public void onLoadMore(){
///// Your operation to retrieve data and init it to your list objects
for(YourCustomObject object : objects){
adapter.addItem(object);
}
}
}

RecyclerView change data set

I want to implement search functionality for my RecyclerView. On text changed i want to change the data that are displayed with this widget. Maybe this question has been asked before or is simple, but I don't know how the change the data that is to be shown...
My RecyclerView is defined as follows:
// 1. get a reference to recyclerView
mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView);
// 2. set layoutManger
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
// 3. create an adapter
mAdapter = new ItemsAdapter(itemsData);
// 4. set adapter
mRecyclerView.setAdapter(mAdapter);
And the data that I am showing is something like:
ItemData itemsData[] = { new ItemData("Mary Richards"),
new ItemData("Tom Brown"),
new ItemData("Lucy London")
};
So when when I want to give the adapter another set of data, another array (with one item for example), what should I do?
If you have stable ids in your adapter, you can get pretty good results (animations) if you create a new array containing the filtered items and call
recyclerView.swapAdapter(newAdapter, false);
Using swapAdapter hints RecyclerView that it can re-use view holders. (vs in setAdapter, it has to recycle all views and re-create because it does not know that the new adapter has the same ViewHolder set with the old adapter).
A better approach would be finding which items are removed and calling notifyItemRemoved(index). Don't forget to actually remove the item. This will let RecyclerView run predictive animations. Assuming you have an Adapter that internally uses an ArrayList, implementation would look like this:
// adapter code
final List<ItemData> mItems = new ArrayList(); //contains your items
public void filterOut(String filter) {
final int size = mItems.size();
for(int i = size - 1; i>= 0; i--) {
if (mItems.get(i).test(filter) == false) {
mItems.remove(i);
notifyItemRemoved(i);
}
}
}
It would perform even better if you can batch notifyItemRemoved calls and use notifyItemRangeRemoved instead. It would look sth like: (not tested)
public void filterOut(String filter) {
final int size = mItems.size();
int batchCount = 0; // continuous # of items that are being removed
for(int i = size - 1; i>= 0; i--) {
if (mItems.get(i).test(filter) == false) {
mItems.remove(i);
batchCount ++;
} else if (batchCount != 0) { // dispatch batch
notifyItemRangeRemoved(i + 1, batchCount);
batchCount = 0;
}
}
// notify for remaining
if (batchCount != 0) { // dispatch remaining
notifyItemRangeRemoved(0, batchCount);
}
}
You need to extend this code to add items that were previously filtered out but now should be visible (e.g. user deletes the filter query) but I think this one should give the basic idea.
Keep in mind that, each notify item call affects the ones after it (which is why I'm traversing the list from end to avoid it). Traversing from end also helps ArrayList's remove method performance (less items to shift).
For example, if you were traversing the list from the beginning and remove the first two items.
You should either call
notifyItemRangeRemoved(0, 2); // 2 items starting from index 0
or if you dispatch them one by one
notifyItemRemoved(0);
notifyItemRemoved(0);//because after the previous one is removed, this item is at position 0
This is my answer - thanks to Ivan Skoric from his site: http://blog.lovelyhq.com/creating-lists-with-recyclerview-in-android/
I created an extra method inside my adapter class:
public void updateList(List<Data> data) {
mData = data;
notifyDataSetChanged();
}
Then each time your data changes, you just call this method passing in your new data and your view should change to reflect it.
Just re-initialize your adapter:
mAdapter = new ItemsAdapter(newItemsData);
or if you only need to remove add a few specific items rather than a whole list:
mAdapter.notifyItemInserted(position);
or
mAdapter.notifyItemRemoved(position);
If you want to change the complete Adapter in the recycler view. you can just simply set by recycler.setAdapter(myAdapter);
It will automatically remove the old adapter from recycler view and replace it with your new adapter.
As ygit answered, swapAdapter is interesting when you have to change the whole content.
But, in my FlexibleAdapter, you can update the items with updateDataSet. You can even configure the adapter to call notifyDataSetChanged or having synchronization animations (enabled by default). That, because notifyDataSetChanged kills all the animations, but it's good to have for big lists.
Please have a look at the description, demoApp and Wiki pages: https://github.com/davideas/FlexibleAdapter

Categories

Resources