ListView get scroll position? - android

I'm using a MergeAdapter (from Mark Murphy's excellent series of projects). You use it with a ListView. I'm trying to rebuild the contents of the adapter on a refresh (instead of refreshing "in place" and calling notifyDataSetChange()).
I'd like to get the y-scroll value of the listview so I can reset to that after I rebuild my list. This doesn't seem to be possible?
Thanks

Implement OnScrollListener for your listview.
#Override
public void onScroll(AbsListView absListView, int firstVisible, int visibleCount, int totalCount) {
//firstvisible is your first visible item in the list
}

Related

Android: ListView, min scroll position

I have 10 items in ListView.
Sometimes I dont want user to be able to see first list item.
So Second one should be like first one.
How to prevent user to scroll to the first item ?
Or maybe there is better solutions or ready API to do that ?
P.S: HeaderView not works for me
The best solution would be to simply remove (temporarily) the item from your List (or whichever collection you are using), and then re-fill the ListView with:
listView.notifyDataSetChanged();
Another thing you could do is return an empty view when your 'position == 0' so the first item would not be displayed you'd also have to call the 'notifyDataSetChanged()' method here when the condition would change.
This code will block the first item from being seen by selecting the second item on the list.
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView absListView, int i) {
}
#Override
public void onScroll(AbsListView absListView, int i, int i2, int i3) {
if (i == 0)
absListView.setSelection(1);
}
});

Get visible position of listview item

I have a custom cursor adapter to populate a list view in my fragment.
I want to set the visibility of certain elements within the list view items, depending on whether the item is the first visible one in the list or not. Is it possible to get that info in the bindView() method of the Cursor adapter?
Adapter's purpose plan:
Create views
Attaching data to them
Return the view for the ListView to use.
Conclusion: Adapter doesn't know where the view it's creating will be shown.
However, the ListView does know about this and it's probably the only way you can get this working.
Example code to get you started:
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
int previousFirst = -1;
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (previousFirst != firstVisibleItem) {
previousFirst = firstVisibleItem;
TextView textView = (TextView) view.findViewById(R.id.title);
if (textView != null) textView.setText("First: " + firstVisibleItem);
}
}
});
Problems with this code:
Once the first item changes, you need to set it's text back to the previous one.
Same goes with the view hierarchy. If you change how this view looks, after it's not the first one anymore you need to change it back.
ListView doesn't scroll upon creation. So the first item will not have the text changed until you scroll manually.
ListView doesn't include the options to customize the first visible item internally, that's why you have to use all these dirty hacks. However, it is possible :). I leave you to overcome these problems yourself.
Good luck!

How is the item view removed from listview?

I know that ListView creates only the needed view items and others are dynamically created as we scroll and the functions handling this are newView and bindView.but I can't find the function that disposes the items that go out of the view.
I use a custom CursorAdapter for my ListView.
I need that to create an ArrayList to keep the items that are currently on the view. How can I do this or does the ListView have such functionality?
If you want to know which items are currently visible in your ListView you can set an onScrollListener to the ListView.
lv.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
});
In onScroll you can get the first and last visible position (firstVisibleItem + visibleItemCount) and thus get the items from your underlying ArrayList that are currently visible.

A reversed endless listview

I am trying to do a endless listview with the Commonsware Endless Adapter (https://github.com/commonsguy/cwac-endless), which works fine by default.
What I am trying to do is a basic chat application.
New items should appear at the end and the chat history should be loadable by the endless adapter when the user scrolls to the top.
This by itself is not hard to do. If the ArrayAdapter contains the data s.t. newest items are at position 0, then simply using android:stackFromBottom in the XML declaration of the ListView will put the beginning of the list at the end.
To make sure that the 'load more' inicator is located at the top, I override getItem, getView etc. to provide it with the reversed positions (count-1-position).
My Problem: When the EndlessAdapter adds new data at the end of the List, the "load more" indicator remains visible, causing it to endlessly fetch more data until there is no more to fetch.
Expected is that it loads one batch and the user then needs to scroll down (here:up) to load further elements.
What am I missing?
Personally, I'd consider pull-to-refresh for this scenario, rather than EndlessAdapter.
That being said, if you are seeing additional rows appear, but the pending view is still there, then your modified getView() is not working properly. The additional rows appearing would indicated that notifyDataSetChanged() itself is functioning (otherwise, those rows would not show up). So, if the pending view is still shown, then getView() presumably is returning the pending view (position 0, I'd guess). In fact, I have no idea how you can get a reverse EndlessAdapter to work, as the first row should always be the pending view and should always be loading data, until you run out of data (and, in the case of a chat, that's possibly never the case).
Hence, again, I'd use pull-to-refresh, or you are going to have to switch to a different "endless" scheme that is paying attention to scroll events, rather than just waiting for the pending view to be displayed, as the trigger to fetch more data.
Do not care on notifyDataSetChanged() help.
I implemented an adapter to return Integer.MAX_VALUE as count of elements and especially calculate index in a cache.
Here is some snippet:
<ListView
android:id="#+id/logContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stackFromBottom="true" />
......
logContainer.setOnScrollListener(new OnScrollListener() {
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if ((logAdapter.getCachedCount() - (Integer.MAX_VALUE - firstVisibleItem)) <= LINES_TO_TRIGGER_PRELOAD && !logAdapter.isPreloading()) {
logAdapter.preloadAtBackground();
}
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
});
class LogAdapter extends BaseAdapter {
private ArrayList<String> logList = new ArrayList<String>();
#Override
public int getCount() {
return Integer.MAX_VALUE;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView logLineView = new TextView(LogViewDialog.this);
int idx = logList.size() - (Integer.MAX_VALUE - position);
logLineView.setText(logList.get(idx));
return logLineView;
}
.........

Android listview item update every time it is scroll back into screen

I have a listView which has its content as random generated numbers. If one item in the listView is scrolled out of the screen and then scrolled back in, the random generated number is changed (it generates a new number).
Is there any way I can prevent this from happening?
A example code is here
This is because every time your item goes off the screen and again come to front it calls getview() method. To solve this you can store all random generated numbers in an array in starting and use it to show the items.
OR
i think using view holder class (i didn't try).
Just try this code for listview implement listener and/or your getview() method calling every time on scroll up and/or down,
mListView.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// write down your code here
// i think notifyDataSetChanged() this method calling whatever u require.
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// write down your code here
}
}); // mListView.setOnScrollListener close

Categories

Resources