We pretty much all know the nice technique apps like Gmail, Facebook, etc. use to dynamically load more items to the ListView then you scroll to the bottom. In this article i am going to show you the same thing over ListView and RecyclerView.
If you are unaware of ListView and RecyclerView that how to use both views then you can check my tutorials for ListView and RecyclerView.
In this tutorial, we are going to learn how to implement endless scroll listener by loading more items when user reaches end of the view i.e. bottom view.
1. Create a new project in Android Studio by navigating to File ⇒ New Android ⇒ Application Project and fill required details. By default my activity is MainActivity.java.
2. Open res ⇒ values ⇒ strings.xml and add below string values. This are the strings that i am going to use in this tutorial and there are String Array also that i’ll use for loading data over views.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">LoadItems On Scroll Demo</string> <string name="hello_world">Hello world!</string> <string name="add">Add</string> <string name="remove">Remove</string> <string name="imageview">ImageView</string> <string name="delete_image">Delete ImageView</string> <string name="loadmore">Loading more items please wait…</string> <!-- Title string array --> <string-array name="title"> <item>Taj Mahal</item> <item>Hawa Mahal</item> <item>Golden Temple</item> <item>Shore Temple</item> <item>Chhatrapati Shivaji Terminus</item> <item>Lotus Temple</item> <item>Victoria Memorial Hall</item> <item>Brihadeeswarar Temple</item> <item>Mahabodhi Temple</item> </string-array> <!-- Location string array --> <string-array name="location"> <item>Agra</item> <item>Jaipur</item> <item>Amritsar</item> <item>Bay of Bengal</item> <item>Mumbai</item> <item>New Delhi</item> <item>Kolkata</item> <item>Tamil Nadu</item> <item>Patna</item> </string-array> <!-- Year string array --> <string-array name="constructed_year"> <item>1632</item> <item>1799 AD</item> <item>1577</item> <item>700–728 AD</item> <item>May 1888</item> <item>1987</item> <item>1906</item> <item>1010 CE</item> <item>250 BCE</item> </string-array> </resources> |
3. Open res ⇒ values and create new resource file naming colors.xml for your colors and put these colors inside this xml.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="red">#ff00</color> <color name="orange">#F96A1B</color> <color name="blue">#33B5E5</color> <color name="black">#000000</color> <color name="pink">#F50057</color> <color name="cyan">#00BCD4</color> <color name="green">#4CAF50</color> <color name="yellow">#FFEB3B</color> </resources> |
4. Now create a layout naming activity_main.xml that contains a ViewPager. Since I am using ListView and RecyclerView so i will show both views in same activity using view pager tab.
If you don’t know how to make swipeable tabs then you can check my tutorial about Tabs.
1 2 3 4 5 6 |
<!-- ViewPager for tabs --> <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" /> |
5. Now after creating viewpager we have to create two more designs for our two fragments i.e ListView and RecyclerView. So create two more xml files under layout directory.
listview_fragment.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <!-- ListView --> <ListView android:id="@+id/listView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="@+id/loadItemsLayout_listView" android:background="#ffffff" > </ListView> <!-- include progress layout that will be displayed while loading more data --> <!-- initially it is hidden --> <include android:id="@+id/loadItemsLayout_listView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" layout="@layout/progress_layout" android:visibility="gone" /> </RelativeLayout> |
linearlayout_fragment.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" > <!-- Recycler View --> <android.support.v7.widget.RecyclerView android:id="@+id/linear_recyclerview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="@+id/loadItemsLayout_recyclerView" /> <!-- include progress layout that will be displayed while loading more data --> <!-- initially it is hidden --> <include android:id="@+id/loadItemsLayout_recyclerView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" layout="@layout/progress_layout" android:visibility="gone" /> </RelativeLayout> |
In above both layouts we have seen there is a include tag. This include tag including a progress_layout below ListView and RecyclerView. The progress_layout is a layout that will display then user reaches at the end of the view while scrolling.
6. In above point we had included progress_layout so now we have to create progress_layout.xml file under layout directory. This layout contains a progress bar a textview for display message title.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?xml version="1.0" encoding="utf-8"?> <!-- Progress Layout contains Progress Bar and a TextView --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#AA000000" android:gravity="center" android:padding="5dp" > <ProgressBar android:id="@+id/more_progress" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@+id/more_progress" android:padding="5dp" android:text="@string/loadmore" android:textColor="#ffffff" android:textSize="15sp" /> </RelativeLayout> |
7. We are using a custom ListView and RecyclerView. So for this we have to create a getter and setter class and custom xml files and custom adapter. If you don’t know about custom views then you can check this tutorial.
I am not going in details for these custom part.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
<?xml version="1.0" encoding="utf-8"?> <!-- ListView Custom Views --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/list_layout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#ffffff" android:padding="10dp" > <ImageView android:id="@+id/list_imageview" android:layout_width="100dp" android:layout_height="120dp" android:adjustViewBounds="true" android:contentDescription="@string/imageview" android:scaleType="centerCrop" /> <LinearLayout android:id="@+id/list_item_holder" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@+id/list_imageview" android:orientation="vertical" > <TextView android:id="@+id/list_title" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingBottom="3dp" android:paddingLeft="10dp" android:textColor="#000000" android:textSize="17sp" /> <TextView android:id="@+id/list_location" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingBottom="3dp" android:paddingLeft="10dp" android:textColor="#757575" android:textSize="14sp" /> <TextView android:id="@+id/list_dateconstructed" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="10dp" android:textColor="#757575" android:textSize="14sp" android:textStyle="bold" /> </LinearLayout> </RelativeLayout> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
package com.loaditemsonscroll_demo; public class Data_Model { // Getter and Setter model for recycler view items private String title, location, year; private int image; public Data_Model(String title, String location, String year, int image) { this.year = year; this.title = title; this.location = location; this.image = image; } public String getTitle() { return title; } public String getLocation() { return location; } public String getYear() { return year; } public int getImage() { return image; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
package com.loaditemsonscroll_demo.adapter; import java.util.ArrayList; import com.loaditemsonscroll_demo.Data_Model; import com.loaditemsonscroll_demo.R; import com.loaditemsonscroll_demo.holders.ListView_Holder; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class ListViewAdapter extends BaseAdapter { private ArrayList<Data_Model> arrayList; private Context context; public ListViewAdapter(Context context, ArrayList<Data_Model> arrayList) { this.context = context; this.arrayList = arrayList; } @Override public int getCount() { return arrayList.size(); } @Override public Object getItem(int position) { return arrayList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View view, ViewGroup parent) { ViewHolder holder = null; // Inflater for custom layout LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); if (view == null) { view = inflater.inflate(R.layout.list_customview, parent, false); holder = new ViewHolder(); holder.list_title = (TextView) view.findViewById(R.id.list_title); holder.list_location = (TextView) view .findViewById(R.id.list_location); holder.list_date = (TextView) view .findViewById(R.id.list_dateconstructed); holder.list_imageView = (ImageView) view .findViewById(R.id.list_imageview); view.setTag(holder); } else { holder = (ViewHolder) view.getTag(); } final Data_Model model = arrayList.get(position); Bitmap image = BitmapFactory.decodeResource(context.getResources(), model.getImage());// This will convert drawbale image into // bitmap // setting data over views holder.list_title.setText(model.getTitle()); holder.list_location.setText(model.getLocation()); holder.list_date.setText(model.getYear()); holder.list_imageView.setImageBitmap(image); return view; } // View Holder private class ViewHolder { public TextView list_title, list_location, list_date; public ImageView list_imageView; } } |
ListView_Holder.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
package com.loaditemsonscroll_demo.holders; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import com.loaditemsonscroll_demo.R; public class ListView_Holder extends RecyclerView.ViewHolder implements OnClickListener { // View holder for list recycler view as we used in listview public TextView list_title, list_location, list_date; public ImageView list_imageView; public RelativeLayout listLayout; private RecyclerView_OnClickListener.OnClickListener onClickListener; public ListView_Holder(View view) { super(view); // Find all views ids this.list_title = (TextView) view.findViewById(R.id.list_title); this.list_location = (TextView) view.findViewById(R.id.list_location); this.list_date = (TextView) view .findViewById(R.id.list_dateconstructed); this.list_imageView = (ImageView) view .findViewById(R.id.list_imageview); this.listLayout = (RelativeLayout) view.findViewById(R.id.list_layout); // Implement click listener over views that we need this.listLayout.setOnClickListener(this); } @Override public void onClick(View v) { // setting custom listener if (onClickListener != null) { onClickListener.OnItemClick(v, getAdapterPosition()); } } // Setter for listener public void setClickListener( RecyclerView_OnClickListener.OnClickListener onClickListener) { this.onClickListener = onClickListener; } } |
RecyclerView_OnClickListener.java
1 2 3 4 5 6 7 8 9 10 |
package com.loaditemsonscroll_demo.holders; import android.view.View; public class RecyclerView_OnClickListener { /** Interface for Item Click over Recycler View Items **/ public interface OnClickListener { public void OnItemClick(View view, int position); } } |
ListView_Recycler_Adapter.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
package com.loaditemsonscroll_demo.adapter; import java.util.ArrayList; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Toast; import com.loaditemsonscroll_demo.Data_Model; import com.loaditemsonscroll_demo.holders.ListView_Holder; import com.loaditemsonscroll_demo.holders.RecyclerView_OnClickListener.OnClickListener; import com.loaditemsonscroll_demo.R; public class ListView_Recycler_Adapter extends RecyclerView.Adapter<ListView_Holder> {// Recyclerview will extend to // recyclerview adapter private ArrayList<Data_Model> arrayList; private Context context; public ListView_Recycler_Adapter(Context context, ArrayList<Data_Model> arrayList) { this.context = context; this.arrayList = arrayList; } @Override public int getItemCount() { return (null != arrayList ? arrayList.size() : 0); } @Override public void onBindViewHolder(ListView_Holder holder, int position) { final Data_Model model = arrayList.get(position); ListView_Holder mainHolder = (ListView_Holder) holder;// holder Bitmap image = BitmapFactory.decodeResource(context.getResources(), model.getImage());// This will convert drawbale image into // bitmap // setting data over views mainHolder.list_title.setText(model.getTitle()); mainHolder.list_location.setText(model.getLocation()); mainHolder.list_date.setText(model.getYear()); mainHolder.list_imageView.setImageBitmap(image); // Implement click listener over layout mainHolder.setClickListener(new OnClickListener() { @Override public void OnItemClick(View view, int position) { switch (view.getId()) { case R.id.list_layout: // Show a toast on clicking layout Toast.makeText(context, "You have clicked " + model.getTitle(), Toast.LENGTH_LONG).show(); break; } } }); } @Override public ListView_Holder onCreateViewHolder(ViewGroup viewGroup, int viewType) { // This method will inflate the custom layout and return as viewholder LayoutInflater mInflater = LayoutInflater.from(viewGroup.getContext()); ViewGroup mainGroup = (ViewGroup) mInflater.inflate( R.layout.list_customview, viewGroup, false); ListView_Holder listHolder = new ListView_Holder(mainGroup); return listHolder; } } |
8. Come to your MainActivity.java and add the following code for implementing swipeable tabs over viewpager.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
package com.loaditemsonscroll_demo; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.FragmentTransaction; import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar.Tab; import android.support.v7.app.ActionBar.TabListener; import android.support.v7.app.AppCompatActivity; import com.loaditemsonscroll_demo.R; public class MainActivity extends AppCompatActivity implements TabListener { private static ViewPager viewPager;//View Pager for setting tabs private static ActionBar actionBar; private static FragmentManager fragmentManager;//fragment manager to work on fragments @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); setTabs(); } //initialize the view pager private void init() { viewPager = (ViewPager) findViewById(R.id.pager); fragmentManager = getSupportFragmentManager(); // Setting adapter over view pager viewPager.setAdapter(new MyAdapter(fragmentManager)); // Implementing view pager pagechangelistener to navigate between tabs viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int pos) { // Setting navigation of tabs to actionbar actionBar.setSelectedNavigationItem(pos); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } }); } private void setTabs() { // Getting actionbar actionBar = getSupportActionBar(); // Setting navigation mode to actionbar actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // Now adding a new tab to action bar and setting title, icon and // implementing listener android.support.v7.app.ActionBar.Tab tab1 = actionBar.newTab(); tab1.setText("RecyclerView"); // tab1.setIcon(R.drawable.ic_launcher); tab1.setTabListener(this); android.support.v7.app.ActionBar.Tab tab2 = actionBar.newTab(); tab2.setText("ListView"); tab2.setTabListener(this); // Now finally adding all tabs to actionbar actionBar.addTab(tab1); actionBar.addTab(tab2); } @Override public void onTabReselected(Tab arg0, FragmentTransaction arg1) { } @Override public void onTabSelected(Tab tab, FragmentTransaction arg1) { // Setting current position of tab to view pager viewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(Tab arg0, FragmentTransaction arg1) { } // My adapter i.e. custom adapter for displaying fragments over view pager private class MyAdapter extends FragmentPagerAdapter { public MyAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int i) { // Getting fragments according to selected position Fragment fragment = null; if (i == 0) { fragment = new LinearLayout_Fragment(); } if (i == 1) { fragment = new ListViewLayout_Fragment(); } // and finally returning fragments return fragment; } @Override public int getCount() { // Returning no. of counts of fragments return 2; } } } |
9. Finally we are going to implement scroll listener over both listview and recyclerview. So lets see how to implement this :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
//Declare these variables globally in class int mVisibleThreshold = 5; int mCurrentPage = 0; int mPreviousTotal = 0; boolean mLoading = true; boolean mLastPage = false; boolean userScrolled = false; // Implement scroll listener private void implementScrollListener() { listView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView arg0, int scrollState) { // If scroll state is touch scroll then set userScrolled // true if (scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) { userScrolled = true; } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // Now check if userScrolled is true and also check if // the item is end then update list view and set // userScrolled to false if (userScrolled && firstVisibleItem + visibleItemCount == totalItemCount) { userScrolled = false; updateListView(); } } }); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
//Declare these variables globally in class private boolean userScrolled = true; int pastVisiblesItems, visibleItemCount, totalItemCount; // Implement scroll listener private void implementScrollListener() { listRecyclerView .addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); // If scroll state is touch scroll then set userScrolled // true if (newState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) { userScrolled = true; } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); // Here get the child count, item count and visibleitems // from layout manager visibleItemCount = mLayoutManager.getChildCount(); totalItemCount = mLayoutManager.getItemCount(); pastVisiblesItems = mLayoutManager .findFirstVisibleItemPosition(); // Now check if userScrolled is true and also check if // the item is end then update recycler view and set // userScrolled to false if (userScrolled && (visibleItemCount + pastVisiblesItems) == totalItemCount) { userScrolled = false; updateRecyclerView(); } } }); } |
We will use this both methods in their respected classes.
10. Since i am using static items to be load on linear list that i had declared in strings.xml inside string array. For that i had created a random value generator method that will generate a random value between 0-9 and update the items accordingly. So create a new class RandomNumberGenerator.java and add the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package com.loaditemsonscroll_demo; import java.util.Random; public class RandomNumberGenerator { // Random generator method this will generate int nos. public int RandomGenerator() { Random random = new Random(); int randomNum = random.nextInt(9); return randomNum; } } |
11. Finally create two more java files for ListView and RecyclerView fragments naming ListViewLayout_Fragment.java and LinearLayout_Fragment.java respectively. In both these classes we first load data manually and when user scrolls and reached at end we will load new data and update items.
ListViewLayout_Fragment .java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
package com.loaditemsonscroll_demo; import java.util.ArrayList; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.Toast; import com.loaditemsonscroll_demo.adapter.ListViewAdapter; public class ListViewLayout_Fragment extends Fragment { private static View view; private static ListView listView;; private static ListViewAdapter adapter; private static ArrayList<Data_Model> listArrayList; // Variables for scroll listener int mVisibleThreshold = 5; int mCurrentPage = 0; int mPreviousTotal = 0; boolean mLoading = true; boolean mLastPage = false; boolean userScrolled = false; // Images int array from drawable folders private static final int[] images = { R.drawable.tajmahal, R.drawable.hawamahal, R.drawable.golden, R.drawable.shore, R.drawable.shivaji, R.drawable.lotus, R.drawable.victoria, R.drawable.brihadishwara, R.drawable.mahabodhi }; // String array for title, location,year String[] getTitle, getLocation, getYear; private static RelativeLayout bottomLayout; public ListViewLayout_Fragment() { // Empty constructor is neccessary } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view = inflater.inflate(R.layout.listview_fragment, container, false); init(); populatRecyclerView(); implementScrollListener(); return view; } // Initialize all variables and views private void init() { bottomLayout = (RelativeLayout) view .findViewById(R.id.loadItemsLayout_listView); // Get the title , location and year from string.xml in array form getTitle = getActivity().getResources().getStringArray(R.array.title); getLocation = getActivity().getResources().getStringArray( R.array.location); getYear = getActivity().getResources().getStringArray( R.array.constructed_year); // Find the id of list view listView = (ListView) view.findViewById(R.id.listView); } // Populate the listview with data private void populatRecyclerView() { listArrayList = new ArrayList<Data_Model>(); for (int i = 0; i < getTitle.length; i++) { // add the items one by one in arraylist listArrayList.add(new Data_Model(getTitle[i], getLocation[i], getYear[i], images[i])); } adapter = new ListViewAdapter(getActivity(), listArrayList); // set adapter over recyclerview listView.setAdapter(adapter); adapter.notifyDataSetChanged(); } // Implement scroll listener private void implementScrollListener() { listView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView arg0, int scrollState) { // If scroll state is touch scroll then set userScrolled // true if (scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) { userScrolled = true; } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // Now check if userScrolled is true and also check if // the item is end then update list view and set // userScrolled to false if (userScrolled && firstVisibleItem + visibleItemCount == totalItemCount) { userScrolled = false; updateListView(); } } }); } // Method for repopulating recycler view private void updateListView() { // Show Progress Layout bottomLayout.setVisibility(View.VISIBLE); // Handler to show refresh for a period of time you can use async task // while commnunicating serve new Handler().postDelayed(new Runnable() { @Override public void run() { // Loop for 3 items for (int i = 0; i < 3; i++) { int value = new RandomNumberGenerator().RandomGenerator();// Random // value // add random data to arraylist listArrayList.add(new Data_Model(getTitle[value], getLocation[value], getYear[value], images[value])); } adapter.notifyDataSetChanged();// notify adapter // Toast for task completion Toast.makeText(getActivity(), "Items Updated.", Toast.LENGTH_SHORT).show(); // After adding new data hide the view. bottomLayout.setVisibility(View.GONE); } }, 5000); } } |
LinearLayout_Fragment .java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
package com.loaditemsonscroll_demo; import java.util.ArrayList; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; import android.widget.Toast; import android.widget.AbsListView.OnScrollListener; import com.loaditemsonscroll_demo.adapter.ListView_Recycler_Adapter; public class LinearLayout_Fragment extends Fragment { private static View view; private static RecyclerView listRecyclerView; private static ArrayList<Data_Model> listArrayList; private static ListView_Recycler_Adapter adapter; // Images array for images private static final int[] images = { R.drawable.tajmahal, R.drawable.hawamahal, R.drawable.golden, R.drawable.shore, R.drawable.shivaji, R.drawable.lotus, R.drawable.victoria, R.drawable.brihadishwara, R.drawable.mahabodhi }; // String array for title, location, year String[] getTitle, getLocation, getYear; private static RelativeLayout bottomLayout; private static LinearLayoutManager mLayoutManager; // Variables for scroll listener private boolean userScrolled = true; int pastVisiblesItems, visibleItemCount, totalItemCount; public LinearLayout_Fragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view = inflater.inflate(R.layout.linearlayout_fragment, container, false); init(); populatRecyclerView(); implementScrollListener(); return view; } // Initialize the view private void init() { bottomLayout = (RelativeLayout) view .findViewById(R.id.loadItemsLayout_recyclerView); // Getting the string array from strings.xml getTitle = getActivity().getResources().getStringArray(R.array.title); getLocation = getActivity().getResources().getStringArray( R.array.location); getYear = getActivity().getResources().getStringArray( R.array.constructed_year); mLayoutManager = new LinearLayoutManager(getActivity()); listRecyclerView = (RecyclerView) view .findViewById(R.id.linear_recyclerview); listRecyclerView.setHasFixedSize(true); listRecyclerView.setLayoutManager(mLayoutManager);// for // linear // data // display // we // use // linear // layoutmanager } // populate the list view by adding data to arraylist private void populatRecyclerView() { listArrayList = new ArrayList<Data_Model>(); for (int i = 0; i < getTitle.length; i++) { listArrayList.add(new Data_Model(getTitle[i], getLocation[i], getYear[i], images[i])); } adapter = new ListView_Recycler_Adapter(getActivity(), listArrayList); listRecyclerView.setAdapter(adapter);// set adapter on recyclerview adapter.notifyDataSetChanged();// Notify the adapter } // Implement scroll listener private void implementScrollListener() { listRecyclerView .addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); // If scroll state is touch scroll then set userScrolled // true if (newState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) { userScrolled = true; } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); // Here get the child count, item count and visibleitems // from layout manager visibleItemCount = mLayoutManager.getChildCount(); totalItemCount = mLayoutManager.getItemCount(); pastVisiblesItems = mLayoutManager .findFirstVisibleItemPosition(); // Now check if userScrolled is true and also check if // the item is end then update recycler view and set // userScrolled to false if (userScrolled && (visibleItemCount + pastVisiblesItems) == totalItemCount) { userScrolled = false; updateRecyclerView(); } } }); } // Method for repopulating recycler view private void updateRecyclerView() { // Show Progress Layout bottomLayout.setVisibility(View.VISIBLE); // Handler to show refresh for a period of time you can use async task // while commnunicating serve new Handler().postDelayed(new Runnable() { @Override public void run() { // Loop for 3 items for (int i = 0; i < 3; i++) { int value = new RandomNumberGenerator().RandomGenerator();// Random // value // add random data to arraylist listArrayList.add(new Data_Model(getTitle[value], getLocation[value], getYear[value], images[value])); } adapter.notifyDataSetChanged();// notify adapter // Toast for task completion Toast.makeText(getActivity(), "Items Updated.", Toast.LENGTH_SHORT).show(); // After adding new data hide the view. bottomLayout.setVisibility(View.GONE); } }, 5000); } } |
12. Now, you are all done, run your app and you will get the output as shown in video.
Note: For gridview you have to just replace refrence variable of listview with that of gridview because same listener is used for both ListView and GridView.
Thanks.
Subscribe to us and get the latest news.
8 Comments
rick
Sunday, May 1st, 2016Hi, finally found what i wanted thanks mate you saved the day.
PS: on thing is you site did’t come on search result just a advice.
Add RecyclerView or Listview in url so that if anybody search it will come in search result and take the domain name around android if you are going to build around android tutorials.
Thanks
pradeepkumar reddy
Monday, July 11th, 2016how to import downloaded source code into android studio
Dr. Droid
Monday, July 11th, 2016Hi Pradeep,
Follow the below steps:
1. Open your Android Studio.
2. Go to File and Select Open
3. Now Go to project location and select build.gradle file and open it. Don’t open direct Project always open build.gradle file.
Thanks
shashikant
Thursday, March 2nd, 2017where did u used these
int mVisibleThreshold = 5;
int mCurrentPage = 0;
int mPreviousTotal = 0;
boolean mLoading = true;
boolean mLastPage = false;
Tadeu
Tuesday, March 7th, 2017Hi, thanks.
But the build.gradle isn’t on the zipped file. What i do?
Dr. Droid
Tuesday, March 7th, 2017Hi Tadeu,
The zipped file is in eclipse format so you need to import project as eclipse one in Android Studio it will auto generate gradle file.
Thanks
sangeeta
Wednesday, June 13th, 2018Hi,
when i extract the file i found bellow files. there is no build.gradle
assets, bin, gen, libs, res, src, .classpath, .project, AndroidManifest.xml, ic_launcher-web.png, proguard-project.txt, project-properties .
when i import in android studio i am getting unrecoverable error.
Dr. Droid
Wednesday, June 13th, 2018Hi Sangeeta,
The source code is written in Eclipse IDE so if you directly open it in Studio it wont work.
You need to migrate it to Android Studio. Check this link : https://developer.android.com/studio/intro/migrate
Thanks