I have an ImageView inside a RelativeLayout.It gets images from database.I want to add scroll-event to it such that when image is scrolled I should get next and previous image based on direction of scroll.
How can I do that in android?
OnScrollListener
Interface definition for a callback to be invoked when the list or grid has been scrolled.
Example for implementing the onScrollListner as per below code -
//Here is where the magic happens
this.getListView().setOnScrollListener(new OnScrollListener(){
//useless here, skip!
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
//dumdumdum
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount)
{
//what is the bottom iten that is visible
int lastInScreen = firstVisibleItem + visibleItemCount;
//is the bottom item visible & not loading more already ? Load more !
if((lastInScreen == totalItemCount) && !(loadingMore)){
Thread thread = new Thread(null, loadMoreListItems);
thread.start();
}
}
});
Have a look at this example and you can also use this Lazy load of images in ListView also
Related
I am trying to implement sort of collpasing toolbar - but without the toolbar(instead of the toolbar it would be a dropdown element, which is essentially a RelativeLayout that has LinearLayout right beneath (the expanded items in the dropdown) that is hovering over the whole layout once the dropdown is pressed.
I thought about implementing a collapsing toolbar and putting the drop down inside the toolbar, but that probably won't be a good idea since a drop down is not a static component like an imageview for example.
I also use ActionBar in my app, so migrating to Toolbar will most likely be very time-consuming, not to mention all the technical issues that come with it.
Aside from that, I thought about detecting a movement/scrolling direction in the listview, and then hide/show the drop down, but it is very buggy when I simply hold my finger on the list view ( it goes mad and switches from up to down and vice versa very very quickly and doesn't stop until I lift the finger).
Are there any other options to implement this sort of behavior?
I'm very curious about what others propose, because I fight with that some time ago. Finnaly I'm detecting movement/scrolling direction in the listview, and then hide/show the header (as you mention). I did it like this (and I don't have bugs):
listView.setOnScrollListener(OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
final int currentFirstVisibleItem = view.getFirstVisiblePosition();
if (currentFirstVisibleItem > mLastFirstVisibleItem) header.setVisibility(View.GONE);
else if (currentFirstVisibleItem < mLastFirstVisibleItem) header.setVisibility(View.VISIBLE);
mLastFirstVisibleItem = currentFirstVisibleItem;
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
I the end I made header to show/hide with animation.
ListView has a default scrollListener. You can use it to know if it's scrolling or not. then hide the dropDown!
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView absListView, int i) {
//detect stop. have a counter then view the dropDown
}
#Override
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
//Hide dropDown
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if(mLastFirstVisibleItem<firstVisibleItem)
{
Log.i("SCROLLING DOWN","TRUE");
}
if(mLastFirstVisibleItem>firstVisibleItem)
{
Log.i("SCROLLING UP","TRUE");
}
mLastFirstVisibleItem=firstVisibleItem;
}
}
});
I'm making an app and I'm using grid view to show all of my images, the problem is I have lots of images, about 12,000, and I don't want to load all of them at the start, because lets face it, it will take forever, so I was wondering what is the best way of accessing the server to fetch more items once the gridview has reached the end.
Thanks.
To achieve load more items on scrolled to end of the gridview
gridView.setOnScrollListener(new AbsListView.OnScrollListener(){
#Override
public void onScroll(AbsListView view,
int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
//Algorithm to check if the last item is visible or not
final int lastItem = firstVisibleItem + visibleItemCount;
if(lastItem == totalItemCount){
// here you have reached end of list, load more data
fetchMoreItems();
}
}
#Override
public void onScrollStateChanged(AbsListView view,int scrollState) {
//blank, not required in your case
}
});
One way is to start the server request for an image in the adapter getView(). When the request completes, you set the retrieved bitmap on the ImageView. There is a very in-depth description of this technique on the Android Developer Blog: Multithreading For Performance | Android Developers Blog. Most servers are fast enough that the lag time to display the image is not objectionable.
However, if you want to load images before the ImageViews are displayed, here's another way you can do it with an OnScrollListener, an AsyncTask, and a list adapter for the `GridView.
Say you have a constant final int THRESHOLD = 50; and a variable lastItem that starts at zero.
When user displays your GridView the AsyncTask kicks off and retrieves the first 100 images. In the onPostExecute(), it adds the images to your adapter and calls notifyDataSetChanged(). It also adds 100 to lastItem.
So now your adapter has 100 images. The user is scrolling through images and the OnScrollListener gets called.
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
if (firstVisibleItem >= lastItem - THRESHOLD) {
new FetchImageAsyncTask().execute();
}
}
Your AsyncTask executes, lastItem is updated to 200, and your adapter gets 100 more images.
Then the user scrolls some more and it starts all over again.
By using the threshold, the user can scroll another 50 images before the end of the list, and that may be enough time to load the next 100 images.
There was some method for loading more data when scroll to the bottom.but I need a method for load data by scrolling to the top of the list in android.
like whats up and another chat application.
can you help me?
Below logic will work for loading more data when you scroll to the top of the listview.
listview.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
currentScrollState = scrollState;
if (currentVisibleItemCount > 0 && currentScrollState == SCROLL_STATE_IDLE) {
if (currentFirstVisibleItem == 0) {
// getMessages(); //write what you want to do when you scroll up to the end of listview.
}
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,int totalItemCount) {
currentFirstVisibleItem = firstVisibleItem;
currentVisibleItemCount = visibleItemCount;
currentTotalItemCount = totalItemCount;
}
});
Hope this helps.
Well telegram have the same list view and the source code is available here https://github.com/DrKLO/Telegram
Or you may want to detect the scrolling of your list view check this answer
Detecting the scrolling direction in the adapter (up/down)
hope this will help.
If Pull To Refresh is what you are looking for, please refer to this link:
https://android-arsenal.com/details/1/1909
I am building an application like techcrunch.
I am fetching data from server in JSON format and displaying the data in list view like article title,author name and image.
I have applied pagination means when user scroll more articles load in a list view. My pagination works fine but there is an issue in the scroll function as the fresh or new data loads the scroll dose not aligns with the data.
To clarify more in simple words my scroll-er goes at the top of the page when i am actually scrolling down
this is my code :
listView.setOnScrollListener(new AbsListView.OnScrollListener()
{
#Override
public void onScrollStateChanged(AbsListView absListView, int i)
{
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
int lastItem = firstVisibleItem + visibleItemCount;
if(lastItem == totalItemCount){
if (mPreLast != lastItem)
{
mPreLast = lastItem;
onStart();
}
}
}
});`
You can use:
listView.setSelectionFromTop(newPosition, 0);
With this method you can set the position to a ListView, using the first parameter as the new position on the list, and the second parameter can be used to set the distance from the top
i have gridview with two column
user can scroll vertically to see gridview items
the problem is when user scrolling is finished
the first visible row is not completely seen .i want to set top of first visible row to top of gridview so first row is comletely visible
can anyone help me?
Update:
the first item is
and the second item is
but after scroll we see
you can try this
grid.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView arg0, int scrollState) {
//this is the state when scroll finish
if(scrollState==SCROLL_STATE_IDLE)
//the first visible item is the first (even partially) visbile item
//setSelection will scroll the grid to the beginning of such item
grid.setSelection(firstVisibleItem);
}
#Override
public void onScroll(AbsListView arg0, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
I use RecyclerView, and i hope it's good for you!
mLayoutManager = new GridLayoutManager(getActivity(), 2);
mListRV= (RecyclerView).findViewById(R.id.list_rv);
mListRV.setLayoutManager(mLayoutManager);
mListRV.setOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
View v = mLayoutManager.getChildAt(0);
int offsetTop = v.getTop();
int offsetBottom = v.getBottom();
int height = (offsetBottom - offsetTop);
if(offsetTop >= -height/2) {
mListRV.smoothScrollBy(0, offsetTop);
} else {
mListRV.smoothScrollBy(0, height + offsetTop);
}
}
}
});
With this code, when you finish scroll, if the first visible item only show a part in recyclerView. It will auto scroll to show full item. You can use:
mLayoutManager.scrollToPositionWithOffset(position, offset);
But it is so fast, the user can be confused. And you will not need use customLayoutManager to edit scroll's properties.
Hope that helps for you!