These files are mainly used. MainActivity is the Activity of the interface, MyAdapter is the custom adaptation of ListView, and MyListView is the custom LIistView with the header. This is not required if you only need to pull and load the file; activity_main.xml is the interface, item. xml is only one TextView in the sublayout of ListView. listview_footer.xml is the bottom layout of listview loading, while listview_header.xml is the header layout of listview.
MainActivity. java
Package com. example. listview; import java. util. arrayList; import java. util. list; import android. annotation. suppressLint; import android. app. activity; import android. OS. asyncTask; import android. OS. bundle; import android. OS. handler; import android. view. layoutInflater; import android. view. view; import android. widget. absListView; import android. widget. absListView. onScrollListener; import android. widget. toast; import com. example. listview. myListView. onRefreshListener; public class MainActivity extends Activity implements OnScrollListener {/** ListView */private MyListView listView;/** custom Adapter */private MyAdapter adapter Adapter; /** total data */private List
List = new ArrayList
();/** Bottom layout of ListView */private View footer; private Handler handler; private int count = 0; @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main);/** configure ListView */listView = (MyListView) findViewById (R. id. listView);/** Add the bottom layout before setAdapter; otherwise, no effect */footer = LayoutInflater. from (this ). inflate (R. layout. listview_footer, null); listView. addFooterView (footer);/** applicable to listView */adapter = new MyAdapter (this, list); listView. setAdapter (adapter);/** Add a thread to set the waiting time. */handler = new Handler (); listView. setOnScrollListener (this); listView. setonRefreshListener (new OnRefreshListener () {@ Override public void onRefresh () {new AsyncTask
() {Protected Void doInBackground (Void... params) {try {Thread. sleep (1000);} catch (Exception e) {e. printStackTrace ();} // list. add ("content added after refresh"); return null ;}@ Override protected void onPostExecute (Void result) {adapter. yydatasetchanged (); listView. onRefreshComplete () ;}cmd.exe cute (null, null, null) ;}}); setData ();} /*** scroll listener at the bottom */@ Overridepublic void onScrollStateChanged (final AbsListView view, int scrollState) {/** when the scroll is stopped and at the bottom */if (scrollState = OnScrollListener. SCROLL_STATE_IDLE & (view. getLastVisiblePosition () = view. getCount ()-1) {/** in order to have the data loading wait time, if it is a network data request, you do not need to directly request the interface here. */handler. postDelayed (new Runnable () {@ Override public void run () {setData ();/** display the refreshed data from the screen. If no position is set, after the listView data is updated, it will run to the first data to start displaying */listView. setSelection (view. getCount ()-1) ;}}, 2000) ;}@ Overridepublic void onScroll (AbsListView arg0, int arg1, int arg2, int arg3) {}/ ** put data, this is not required if your data can be obtained by page. This is for paging data */@ SuppressLint ("ShowToast") private void setData () {// when the data reaches the total amount, remove the bottom layout if (count> 50) {listView. removeFooterView (footer); Toast. makeText (this, "No more data", 500 ). show (); return;} for (int I = count; I
MyListView. java
Package com. example. listview; import java. util. date; import android. content. context; import android. util. attributeSet; import android. view. layoutInflater; import android. view. motionEvent; import android. view. view; import android. view. viewGroup; import android. view. animation. linearInterpolator; import android. view. animation. rotateAnimation; import android. widget. absListView; import android. widget. absListView. O NScrollListener; import android. widget. imageView; import android. widget. linearLayout; import android. widget. listView; import android. widget. progressBar; import android. widget. textView; /*** Add a custom ListView with a refresh header in the ListView *** @ author Liu Ziwei ***/public class MyListView extends ListView implements OnScrollListener {private final static int RELEASE_To_REFRESH = 0; // status value of the drop-down process private final static int PULL_To_RE FRESH = 1; // The status value private final static int REFRESHING = 2 returned from the drop-down list; // The status value private final static int DONE = 3 being refreshed; private final static int LOADING = 4; // RATIO of actual padding distance to the offset on the Interface private final static int RATIO = 3; private LayoutInflater inflater; // private LinearLayout headerView; private TextView lvHeaderTipsTv; private TextView lvHeaderLastUpdatedTv; private ImageView lvHea DerArrowIv; private ProgressBar lvHeaderProgressBar; // defines the height of the headers drop-down and refresh. private: headerContentHeight; private: animation; private RotateAnimation reverseAnimation; private int startY; private int state; // ensure that the value of startY is recorded only once in a complete touch event. private boolean isRecored; private OnRefreshListener refreshListener; private boolean isRefreshable; public MyListView (C Ontext context) {super (context); init (context);} public MyListView (Context context, AttributeSet attrs) {super (context, attrs); init (context );} private void init (Context context) {setCacheColorHint (context. getResources (). getColor (android. r. color. transparent); inflater = LayoutInflater. from (context); headerView = (LinearLayout) inflater. inflate (R. layout. listview_header, null); lvHeaderTipsTv = (TextView) headerView. findViewById (R. id. lvHeaderTipsTv); lvHeaderLastUpdatedTv = (TextView) headerView. findViewById (R. id. lvHeaderLastUpdatedTv); lvHeaderArrowIv = (ImageView) headerView. findViewById (R. id. lvHeaderArrowIv); // set the minimum height and width of the drop-down refresh icon. setMinimumWidth (70); lvHeaderArrowIv. setMinimumHeight (50); lvHeaderProgressBar = (ProgressBar) headerView. findViewById (R. id. lvHeaderProg RessBar); measureView (headerView); headerContentHeight = headerView. getMeasuredHeight (); // set the padding, which is the height of a negative layout from the top and hides the headerView. setPadding (0,-1 * headerContentHeight, 0, 0); // re-paint the headerView. invalidate (); // Add the drop-down refreshed layout to the top of the ListView addHeaderView (headerView, null, false); // set the rolling listening event setOnScrollListener (this ); // set the animation rotation event animation = new RotateAnimation (0,-180, RotateAnimation. RELATIVE_TO _ SELF, 0.5f, RotateAnimation. RELATIVE_TO_SELF, 0.5f); animation. setInterpolator (new LinearInterpolator (); animation. setDuration (250); animation. setFillAfter (true); reverseAnimation = new RotateAnimation (-180, 0, RotateAnimation. RELATIVE_TO_SELF, 0.5f, RotateAnimation. RELATIVE_TO_SELF, 0.5f); reverseAnimation. setInterpolator (new LinearInterpolator (); reverseAnimation. setDuration (1, 200); reverseAnim Ation. setFillAfter (true); // The initial status is the status after the pull-down refresh, so it is DONE state = DONE; // whether isRefreshable is being refreshed = false ;} @ Override public void onScrollStateChanged (AbsListView view, int scrollState) {}@ Override public void onScroll (AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {}@ Override public boolean onTouchEvent (MotionEvent ev) {if (isRefreshable) {switch (ev. getAction () {Case MotionEvent. ACTION_DOWN: if (! IsRecored) {isRecored = true; startY = (int) ev. getY (); // record the current position when the finger is pressed} break; case MotionEvent. ACTION_UP: if (state! = REFRESHING & state! = LOADING) {if (state = PULL_To_REFRESH) {state = DONE; changeHeaderViewByState () ;}if (state = RELEASE_To_REFRESH) {state = REFRESHING; changeHeaderViewByState (); onLvRefresh () ;}} isRecored = false; isBack = false; break; case MotionEvent. ACTION_MOVE: int tempY = (int) ev. getY (); if (! IsRecored) {isRecored = true; startY = tempY;} if (state! = REFRESHING & isRecored & state! = LOADING) {// ensure that the current position is always in the head during the padding setting process. Otherwise, if the list exceeds the screen, when pushing, the list will scroll at the same time. // you can easily refresh the if (state = RELEASE_To_REFRESH) {setSelection (0); // push up to the extent that the screen is sufficient to cover up the head, however, it has not been pushed to the full-covered level. if (tempY-startY)/RATIO
Listview_footer.xml
Listview_header.xml
<FrameLayout android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_alignParentLeft = "true" android: layout_centerVertical = "true">
</FrameLayout>