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,.....,....);
I have a listview wrapped in a SwipeRefreshLayout. The listview renders very smoothly in anytime I update it with new data. But whenever I pull down SwipeRefreshLayout to get new messages,the listview gives me a blink effect which is negative in terms of user experience. I found nothing useful to fix this issue after searching a lot on the internet.Can any one teach me how to resolve this problem.
Below is part of my code:
public void fetchMoreMsgs(){
sizeOfChatLV=chatLVArray.size();
if(lvPos==0){
toast = Toast.makeText(ma,"No more messages",Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER,0,0);
toast.show();
return;
}else {
if(lvPos-fetchStep>=0){
arrayList = chatLVArray.subList(lvPos-fetchStep, lvPos);
msgsList.addAll(0, arrayList);
chatLVArrayAdapter = new ChatLVArrayAdapter(ma, msgsList);
ma.chatListViewIMP2P.setAdapter(chatLVArrayAdapter);
ma.chatListViewIMP2P.setSelection(fetchStep);
lvPos-=fetchStep;
}else {
arrayList = chatLVArray.subList(0, lvPos);
msgsList.addAll(0, arrayList);
chatLVArrayAdapter = new ChatLVArrayAdapter(ma, msgsList);
ma.chatListViewIMP2P.setAdapter(chatLVArrayAdapter);
ma.chatListViewIMP2P.setSelection(lvPos);
lvPos=0;
}
}
}
The fetchMoreMsgs method is called when I pull down the listview(wrapped in a SwipeRefreshLayout).Any help is much appreciated!
Whenever you call setAdapter, it completely destroys every view in the ListView and then creates it anew. This is what causes your blinking effect.
Instead, your chatLVArrayAdapter should have a way to updating the underlying list and then you should call your adapter's notifyDataSetChanged() to tell ListView the data has changed.
I want to initialize a new array list in a Fragment (onCreateView), but it says (cannot resolve symbol) and I don't know why.
How to fix that? since it seems that some statements change in the onCreateView method.
Thx
Ok, I have found the solution.
I just needed to add an ArrayList , before initializing.
ArrayList articlesList = new ArrayList<Articles>();
ListView listview = (ListView) view.findViewById(R.id.list);
ArticlesAdapter adapter = new ArticlesAdapter(getActivity().getApplicationContext(), R.layout.articles, articlesList);
I try to create comments in ListView. I've comments' ArrayList linked to the ListView and I can print all the comments successfully. However, when I add another comment to my ArrayList and call notifyDataSetChanged and then try to find the view I get nullPointerException.
I guess what happens is the notifyDataSetChanged doesn't change the ListView immediately, but I couldn't find any solution to this problem.
private ArrayList<Comment> chatroomComments;
private CommentsListArrayAdapter adapter;
private ListView chatroomListView;
And this is how I try to get the view:
chatroomComments.add(comment);
adapter.notifyDataSetChanged();
View v = CommentsListArrayAdapter.positionToView
.get(chatroomComments.size() - 1);
adapter.setNewSelectedView(v);
Any ideas?
My book, "Hello Android" gives this as a way of using a custom db helper, setting up a cursor, and then setting up an adapter as follows:
Cursor cursor
CustomDatabaseHelper test = new CustomDatabaseHelper(this);
try {
cursor = getData();
showData(cursor);
} finally {
test.close();
}
With this however, everytime I need to refresh the data set, I need to keep running this block of code (which gets a bit difficult inside an onClick() for a button due to "this" not being available.
Is this the best way to refresh the data set, or should I look towards removing the .close and issue an adapter.notifyDataSetChanged()? If I do this, sometimes I get a force close as (and I can't remember at the moment) but sometimes it cannot Delete properly - I think this may be because the database is currently open and it tries to open again.
Should we also be declaring the variables for the Cursors, DatabaseHelpers and Adapter in the Class (outside of the OnCreate) so that they are accessible to all the functions?
I realise this is just poor programming at this stage, but Im trying to get some pointers as to the best way of doing things.
You should use adapter.notifyDataSetChanged(). What does the logs says when you use that?
Simply add these code before setting Adapter it's working for me:
listView.destroyDrawingCache();
listView.setVisibility(ListView.INVISIBLE);
listView.setVisibility(ListView.VISIBLE);
Or Directly you can use below method after change Data resource.
adapter.notifyDataSetChanged()
Best Way to Refresh Adapter/ListView on Android
Not only calling notifyDataSetChanged() will refresh the ListView data, setAdapter() must be called before to load the information correctly:
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
Following code works perfect for me
EfficientAdapter adp = (EfficientAdapter) QuickList.getAdapter();
adp.UpdateDataList(EfficientAdapter.MY_DATA);
adp.notifyDataSetChanged();
QuickList.invalidateViews();
QuickList.scrollBy(0, 0);
adapter.notifyDataSetChanged();
If nothing works, just create the adapter instance again with the new set of results or the updated set of results. Then you can see the new view.
XYZAdapter adbXzy = new XYZAdapter(context, 0, listData);
xyzListView.setAdapter(adbXzy);
adbXzy.notifyDataSetChanged();
If you are using LoaderManager try with this statement:
getLoaderManager().restartLoader(0, null, this);
Perhaps their problem is the moment when the search is made in the database. In his Fragment Override cycles of its Fragment.java to figure out just: try testing with the methods:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_x, container, false); //Your query and ListView code probably will be here
Log.i("FragmentX", "Step OnCreateView");// Try with it
return rootView;
}
Try it similarly put Log.i ... "onStart" and "onResume".
Finally cut the code in "onCreate" e put it in "onStart" for example:
#Override
public void onStart(){
super.onStart();
Log.i("FragmentX","Step OnStart");
dbManager = new DBManager(getContext());
Cursor cursor = dbManager.getAllNames();
listView = (ListView)getView().findViewById(R.id.lvNames);
adapter = new CustomCursorAdapter(getContext(),cursor,0);// your adapter
adapter.notifyDataSetChanged();
listView.setAdapter(adapter);
}
Just write in your Custom ArrayAdaper this code:
private List<Cart_items> customListviewList ;
refreshEvents(carts);
public void refreshEvents(List<Cart_items> events)
{
this.customListviewList.clear();
this.customListviewList.addAll(events);
notifyDataSetChanged();
}
just write in your Custom ArrayAdaper this code:
public void swapItems(ArrayList<Item> arrayList) {
this.clear();
this.addAll(arrayList);
}