The realization method of the Android ListView paging function _android

Source: Internet
Author: User
Tags getdate stub

Through this small demo I learned:

1, ListView a small paging function
2, deepen the understanding of the custom control
3, the optimization of the ListView
4, the use of Baseadapter
5, Custom Adapter
6, the callback of the interface

To achieve the effect-when dragging ListView to the bottom, display a ProgressBar and a "Loading ..." textview. And after two seconds, the new data is loaded below. The directory structure of the project and the results of the program to implement are as follows:

The first is the Layout section:

To achieve this, I first created a footer_layout.xml layout file in the layout file:

<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android=
"http://schemas.android.com/apk/" Res/android "
 android:layout_width=" match_parent "
 android:layout_height=" match_parent "
 android:o" rientation= "vertical" >
 <linearlayout 
  android:id= "@+id/load_layout"
  Match_parent "
  android:layout_height=" wrap_content "
  android:orientation=" Horizontal "
  android: paddingtop= "10dip"
  android:paddingbottom= "10dip"
  android:gravity= "center"
  >
  < ProgressBar 
   android:layout_width= "wrap_content"
   android:layout_height= "Wrap_content"
   ? Android:attr/progressbarstylesmall "
   android:background=" "#ff0000"
   />
  <textview 
   Android:layout_width= "Wrap_content"
   android:layout_height= "wrap_content"
   android:text= "Loading ..."
   />
  
 </LinearLayout>

</LinearLayout>

Then a new item.xml is created to be used as a subkey for ListView:

<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android=
"http://schemas.android.com/apk/" Res/android "
 android:layout_width=" match_parent "
 android:layout_height=" match_parent "
 android:o" rientation= "vertical" >

 <textview
  android:id= "@+id/tv1" android:layout_width= "Wrap_content"
  android:layout_height= "wrap_content"
  android:text= "hahaha"/>
 <textview android:id= 
  "@+id/" TV2 "
  android:layout_width=" wrap_content "
  android:layout_height=" wrap_content "
  android:text=" Quack gaga "
 />
</LinearLayout>

Finally, a custom ListView control is added to the main layout file:

<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android"
 xmlns:tools= "http:// Schemas.android.com/tools "
 android:layout_width=" match_parent "
 android:layout_height=" Match_parent "
 >

 <com.lx.loadlistview.loadlistview
  android:id= "@+id/list"
  android:layout_width= "Match_ Parent "
  android:layout_height=" wrap_content "
  android:layout_alignparenttop=" true "
  android:layout_ Centerhorizontal= "true"
  android:cachecolorhint= "#00000000" >
 </com.lx.loadlistview.loadlistview >

</RelativeLayout>

Then in order to achieve this effect of ListView, we need a custom ListView and reference our custom ListView in the above layout file, the code is as follows:

Package Com.lx.loadListView;

Import COM.EXAMPLE.LISTVIEWLOADDEMO.R;
Import Android.content.Context;
Import Android.util.AttributeSet;
Import Android.view.LayoutInflater;
Import Android.view.View;
Import Android.widget.AbsListView;
Import Android.widget.ListView;

Import Android.widget.AbsListView.OnScrollListener;
 public class Loadlistview extends ListView implements Onscrolllistener {View footer; int lastvisiableitem;//the last visible item int totalitemcount;//The total number of the item Boolean isloading;

 Loading Iloadlistener Iloadlistener;
  Public Loadlistview (context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle);
 TODO automatically generated constructor stub initview (context);
  Public Loadlistview (context, AttributeSet attrs) {Super (context, attrs);
 TODO automatically generated constructor stub initview (context);
  Public Loadlistview {Super (context);
 TODO automatically generated constructor stub initview (context); /*** * Add bottom prompts load layout to ListView * * @param context/public voidInitview {Layoutinflater Inflater = layoutinflater.from (context);
  Footer = inflater.inflate (r.layout.footer_layout, NULL);
  Initially, the bottom layout is not visible Footer.findviewbyid (r.id.load_layout). setvisibility (View.gone);
  This.addfooterview (footer);
 This.setonscrolllistener (this); @Override public void onscrollstatechanged (Abslistview view, int scrollstate) {//TODO automatically generated method stubs//When the total item quantity equals The position of the last item and when scrolling stops if (Totalitemcount = = Lastvisiableitem && scrollstate = = Scroll_state_idle) {if (!is
    Loading) {isloading = true;
    Footer.findviewbyid (r.id.load_layout). setvisibility (view.visible);
   Load more iloadlistener.onload ();
 /** *firstvisibleitem The first visible item's position *visibleitemcount the number of visible item *totalitemcount The total number of item **/@Override public void Onscroll (Abslistview view, int firstvisibleitem, int visibleitemcount, int totalitemcount) {//TODO automatically generated The method stub This.lastvisiableitem = Firstvisibleitem + Visibleitemcount
 This.totalitemcount = Totalitemcount;
  }//loading will footer hide public void LoadComplete () {isloading=false;
 Footer.findviewbyid (r.id.load_layout). setvisibility (View.gone);
 public void Setinterface (Iloadlistener iloadlistener) {this.iloadlistener = Iloadlistener;
 }//Load more data callback interface public interface Iloadlistener {public void onLoad ();

 }

}

Our custom ListView inherits from ListView and implements the three constructs of the parent class, in order to load the layout we want into the ListView, we have customized a Initview method for finding and instantiating Footer_ Layout.xml to add it to the bottom of the ListView. Add the initialization method Initview () to the three constructed methods of the parent class, and at the end of the Initview method, call the ListView Addfooterview (View) method to add the bottom layout. Because we do not want to display this footer when ListView is just loaded, we want to set its visible to gone. To achieve the ListView pull to the bottom of the display footer, to implement the ListView Onscrolllistener interface, and implement the two methods in its parent class. In the Onscrollstatechanged () method to determine whether to scroll to the bottom part (we define a global variable lastvisibleitem=firstvisibleitem+visibleitemcount, If this value is equal to the totalitemcount, the proof is scrolled to the bottom of the ListView and whether ListView stops scrolling (Scrollstate=scroll_state_idle) at this time.

To add data to the ListView, we define an entity class Apk_entity:

Package com.lx.entity;

public class Apkentity {

 private String name;
 Private String info;
 Public String GetName () {return
  name;
 }
 public void SetName (String name) {
  this.name = name;
 }
 Public String GetInfo () {return
  info;
 }
 public void SetInfo (String info) {
  this.info = info;
 }
 
}

We then define a data adapter Myadapter for ListView, Inherit from Baseadapter, and implement four of these methods, where we primarily implement the data population:

Package com.lx.adapter;

Import java.util.ArrayList;
Import COM.EXAMPLE.LISTVIEWLOADDEMO.R;


Import com.lx.entity.ApkEntity;
Import Android.content.Context;
Import Android.view.LayoutInflater;
Import Android.view.View;
Import Android.view.ViewGroup;
Import Android.widget.BaseAdapter;

Import Android.widget.TextView;
 public class Myadapter extends Baseadapter {arraylist<apkentity> list;
 
 
 Layoutinflater Inflater; The list item is passed into the constructor and the Layoutinflater public Myadapter is initialized (context context,arraylist<apkentity> list) {this.list=
  List
 This.inflater=layoutinflater.from (context); //Get the length of the list (the program is read first when loading is displayed to the UI, and the value obtained determines how many rows listview display) @Override public int GetCount () {//TODO automatically generated method stubs Retu
 RN List.size (); //Get the data at the specified location in the list (return view according to ListView location) @Override public Object getitem (int position) {//TODO automatically generated method stub Retu
 RN List.get (position); ///According to ListView location get ID in data source collection @Override public long getitemid (int position) {//TODO automatically generated method stub return position;  //*** most important, decide ListView interface style @Override public View getview (int position, View Convertview, ViewGroup parent) {//TODO
  The automatically generated method stub//Gets the entity apkentity entity=list.get (position) from the list;
  The purpose of using Viewholder is to make the control instance Viewholder holder every time the GetView is not Findviewbyid () each time;
   Nflate Load Layout if (convertview==null) {holder=new viewholder ();
   Locate and convert the layout to view convertview=inflater.inflate (R.layout.item, NULL);
   Holder.tv_name= (TextView) Convertview.findviewbyid (R.ID.TV1);
   holder.tv_info= (TextView) Convertview.findviewbyid (R.ID.TV2);
  Convertview.settag (holder);
  }else{holder= (Viewholder) Convertview.gettag ();
  } holder.tv_name.setText (Entity.getname ());
  Holder.tv_info.setText (Entity.getinfo ());
 return convertview;
 Class viewholder{TextView Tv_name,tv_info; Use to refresh ListView public void ondatechanged When layout changes (arraylist<apkentity> list) {this.list=list;
 This.notifydatasetchanged ();
 }

}

The most important thing in this custom adapter is the GetView () method, which determines the layout of each item listview, in the GetView () method, in order to optimize the operational efficiency of ListView, Instead of Findviewbyid () to instantiate the control every time the item is created, we define a viewholder inner class that caches the instance of the control and declares the layout control in the item layout in the class. Because the GetView () method reloads the layout every time, it can become a performance bottleneck when the ListView is rolling fast. So the Convertview parameter in the GetView () method is used to cache the previously loaded layout so that it can be reused later. As you can see from the above code, if Convertview is empty, we use layoutinflate to load the layout and instantiate the controls in the item, and call the view's Settag () method. Store the Viewholder object in the Convertviewu. Thus, when the Convertview is not empty, the Gettag () method of the view is called directly, and the Viewholder is taken directly out so that all instances of the control are slow to exist in Viewholder, There is no need to Findviewbyid () the control every time.

1. Use the Convertview parameter: Avoid repeated load layout, use him to cache the previously loaded layout.

2. Use Viewholder: To avoid every time GetView () the control is instantiated, with this class to complete the control instantiation of the cache.

Then we need to complete the instantiation of Loadlistview in Mainactivity, and Mydapter instantiation, adding data to the entity classes and matching adapter and ListView to fill the data:

Package Com.example.listviewloaddemo;
Import java.util.ArrayList;
Import Java.util.HashMap;
Import java.util.List;

Import Java.util.Map;
Import Com.lx.adapter.MyAdapter;
Import com.lx.entity.ApkEntity;
Import Com.lx.loadListView.LoadListView;

Import Com.lx.loadListView.LoadListView.ILoadListener;
Import Android.os.Bundle;
Import Android.os.Handler;
Import android.app.Activity;
Import Android.util.Log;
Import Android.view.Menu;
Import Android.widget.BaseAdapter;
Import Android.widget.ListView;

Import Android.widget.SimpleAdapter;
 public class Mainactivity extends activity implements Iloadlistener {private Loadlistview LV;
 Private arraylist<apkentity> list=new arraylist<apkentity> ();
 Private Myadapter Myadapter;
  @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
  Setcontentview (R.layout.activity_main);
  GetDate ();
  
 Showlistview (list); private void GetDate () {//TODO automatically generated method stub for (int i = 0; i <10;
   i++) {apkentity entity=new apkentity ();
   Entity.setname ("hairy");
   Entity.setinfo ("I Am a pig");
  List.add (entity); Getonloaddate () {//TODO automatically generated method stub for (int i = 0; i < 2; i++) {apkentity entity=new Apk
   Entity ();
   Entity.setname ("Mao");
   Entity.setinfo ("I am a Dog");
  List.add (entity); } private void Showlistview (arraylist<apkentity> list) {if (myadapter==null) {LV = (Loadlistview) findv
   Iewbyid (r.id.list);
   Lv.setinterface (this);
   LOG.D ("Setinterface--->>", this.tostring ());
   Myadapter=new Myadapter (this, list);
  Lv.setadapter (Myadapter);
  }else{myadapter.ondatechanged (list); } @Override public void OnLoad () {//TODO) automatically generated method stubs//using the current thread to control how many seconds to get the data, and then set it to the ListView (normally no need to add, just to see the effect of the delay
  ) Handler handler=new Handler ();
    Handler.postdelayed (Runnable () {@Override public void run () {//TODO) automatically generated method stub getonloaddate ();
    Showlistview (list); Notify ListView loaded LV.LoadComplete (); 
 }, 2000);
 }

}

Mainactivity in the main need to pay attention to is the Showlistview () method, in this method we judged the adapter is empty, if the adapter is empty, then instantiate ListView, instantiate adapter and so on a series of operations, Otherwise, the ondatechanged () method called Myadapter (The Notifydatasetchanged () method of the adapter called in this method is used to update the UI when the ListView changes). Because you want to load new data when the monitor slides to the bottom of the ListView, you implement a team Mainactivoity callback in the Loadlistview class, write a callback interface Iloadlistener () in the Loadlistview, In which you implement an onload () method, implement this interface in Mainactivity, rewrite the onload () method, where you implement other methods you want to implement, such as new data loading and UI refresh display, and finally, after refreshing the new data, the footer is hidden, So execute the LoadComplete () method in Loadlistview.

At this point, the whole small demo learning basically completed, and some of the knowledge is not quite understand, such as interface callback, custom control parts, etc., but also need to deepen the practice.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.