Pull-down refresh (2), pull-down refresh
First look at the main layout activity_main.xml
<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" android:background="@color/white" tools:context=".MainActivity" > <com.imooc.listviewfrashdemo1.ReFlashListView android:id="@+id/listview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/white" android:cacheColorHint="#00000000" android:dividerHeight="5dip" /></RelativeLayout>
Header_layout.xml
<? 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 = "wrap_content" android: orientation = "vertical"> <RelativeLayout android: layout_width = "match_parent" android: layout_height = "wrap_content" android: paddingBottom = "10dip" android: paddingTop = "10dip"> <LinearLayout android: id = "@ + id/layout" android: layout_width = "wrap_content" Android: layout_height = "wrap_content" android: layout_centerInParent = "true" android: gravity = "center" android: orientation = "vertical"> <TextView android: id = "@ + id/tip" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: text = "pull-down list to refresh! "/> <TextView android: id =" @ + id/lastupdate_time "android: layout_width =" wrap_content "android: layout_height =" wrap_content "/> </LinearLayout> <ImageView android: id = "@ + id/arrow" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_toLeftOf = "@ id/layout" android: layout_marginRight = "20dip" android: src = "@ drawable/pull_to_refresh_arrow"/> <ProgressBar android: id = "@ + id/p Rogress "style = "? Android: attr/progressBarStyleSmall "android: layout_width =" wrap_content "android: layout_height =" wrap_content "android: layout =" @ id/layout "android: layout_marginRight =" 20dip "android: visibility = "gone"/> </RelativeLayout> </LinearLayout>
View the layout of each item in listview
Item_layout.xml
<? 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: orientation = "vertical"> <LinearLayout android: layout_width = "fill_parent" android: layout_height = "60dip" android: gravity = "center_vertical" android: background = "@ drawable/app_item_bg" android: orientation = "horizontal"> <ImageView android: id = "@ + id/item3_apkiv" android: layout_width = "50dip" android: layout_height = "50dip" android: background = "@ drawable/test_icon" android: layout_marginLeft = "10dip"/> <LinearLayout android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_weight = "1" android: layout_marginLeft = "10dip" android: orientation = "vertical"> <TextView android: id = "@ + id/item3_apkname" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: text = "app name" android: textColor = "@ color/black" android: textSize = "18dip"/> <TextView android: id = "@ + id/item3_apkinfo" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_marginTop = "5dip" android: text = "app information" android: textSize = "14dip"/> </LinearLayout> <Button android: layout_width = "60dip" android: layout_height = "30dip" android: background = "@ drawable/ic_launcher" android: id = "@ + id/item3_dlbtn" android: layout_marginRight = "10dip" android: text = "Install"/> </LinearLayout> <TextView android: id = "@ + id/item3_apkdes" android: layout_width = "fill_parent" android: layout_height = "30dip" android: layout_marginLeft = "5dip" android: layout_marginRight = "5dip" android: gravity = "center_vertical" android: text = "application description" android: textSize = "14dip"/> </LinearLayout>
The above three la s can be viewed, and you may know that this is not the main one.
Next, let's look at the bean class.
ApkEntity
package com.imooc.listviewfrashdemo1;public class ApkEntity {private String name;private String des;private String info;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDes() {return des;}public void setDes(String des) {this.des = des;}public String getInfo() {return info;}public void setInfo(String info) {this.info = info;}}
Next, let's look at the main process code.
MainActivity
Package com. imooc. listviewfrashdemo1; import java. util. arrayList; import android. app. activity; import android. OS. bundle; import android. OS. handler; import com. example. listviewfrashdemo1.R; import com. imooc. listviewfrashdemo1.ReFlashListView. IReflashListener; public class MainActivity extends Activity implements IReflashListener {ArrayList <ApkEntity> apk_list; MyAdapter adapter; ReFlashListView; @ Ove Rrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); // load the layout-only one listViewsetContentView (R. layout. activity_main); // setData (); // fill in the Data showList (apk_list);}/*** set the data source */private void setData () {apk_list = new ArrayList <ApkEntity> (); for (int I = 0; I <10; I ++) {ApkEntity entity = new ApkEntity (); entity. setName ("default data"); entity. setInfo ("50 W user"); entity. setDes ("this is A magic app "); apk_list.add (entity) ;}} private void showList (ArrayList <ApkEntity> apk_list) {if (adapter = null) {listview = (ReFlashListView) findViewById (R. id. listview); // set the listener for this class, and then implements IReflashListenerlistview. setInterface (this); adapter = new MyAdapter (this, apk_list); // If the adapter is null, set the adapter to listview. setAdapter (adapter);} else {// If the adapter is not null, update the data source and perform yydatasetchanged () adapter. onDateChange (apk _ List) ;}}/*** callback Method for refreshing operations */@ Overridepublic void onReflush () {Handler handler = new Handler (); handler. postDelayed (new Runnable () {@ Overridepublic void run () {// get the latest data setReflashData (); // showList (apk_list) is displayed on the notification page ); // notify listview to refresh data !!!!!!!!!!!!!! Listview. reflashComplete () ;}}, 2000) ;}private void setReflashData () {for (int I = 0; I <2; I ++) {ApkEntity entity = new ApkEntity (); entity. setName ("refresh data"); entity. setDes ("This is a magic application"); entity. setInfo ("50w user"); apk_list.add (0, entity );}}}
Next, let's look at the adapter code.
MyAdapter
package com.imooc.listviewfrashdemo1;import java.util.ArrayList;import com.example.listviewfrashdemo1.R;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> apk_list;LayoutInflater inflater;public MyAdapter(Context context, ArrayList<ApkEntity> apk_list) {this.apk_list = apk_list;this.inflater = LayoutInflater.from(context);}public void onDateChange(ArrayList<ApkEntity> apk_list) {this.apk_list = apk_list;this.notifyDataSetChanged();}@Overridepublic int getCount() {return apk_list.size();}@Overridepublic Object getItem(int position) {return apk_list.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ApkEntity entity = apk_list.get(position);ViewHolder holder;if (convertView == null) {holder = new ViewHolder();convertView = inflater.inflate(R.layout.item_layout, null);holder.name_tv = (TextView) convertView.findViewById(R.id.item3_apkname);holder.des_tv = (TextView) convertView.findViewById(R.id.item3_apkdes);holder.info_tv = (TextView) convertView.findViewById(R.id.item3_apkinfo);convertView.setTag(holder);}else{holder = (ViewHolder) convertView.getTag();}holder.name_tv.setText(entity.getName());holder.des_tv.setText(entity.getDes());holder.info_tv.setText(entity.getInfo());return convertView;}class ViewHolder {TextView name_tv;TextView des_tv;TextView info_tv;}}
Next, let's take a look at the custom listview class (the code inside is detailed)
ReFlashListView
Package com. imooc. listviewfrashdemo1; import java. text. simpleDateFormat; import java. util. date; import android. content. context; import android. util. attributeSet; import android. util. log; import android. view. layoutInflater; import android. view. motionEvent; import android. view. view; import android. view. viewGroup; import android. view. animation. rotateAnimation; import android. widget. absListView; import android. wid Get. absListView. onScrollListener; import android. widget. imageView; import android. widget. listView; import android. widget. progressBar; import android. widget. textView; import com. example. listviewfrashdemo1.R;/*** hide the head layout -- first measure the parent layout, obtain the head layout height, set the padding, and then hide the head layout, listview in add header Layout * Set listening event * Judge ontouch time * Set listening to load refreshed data */public class ReFlashListView extends ListView implements OnScrollListener {View header; // top layout file; in T headerHeight; // The height of the layout file on the top; int firstVisibleItem; // The Position of the first visible item; int scrollState; // The current scrolling state of the listview; boolean isRemark; // tag, which is the Y value at the top of the listview; int startY; // The Y value at the top of the listview; int state; // The current state; final int NONE = 0; // normal state; final int PULL = 1; // a drop-down status is displayed; final int RELESE = 2; // a release status prompt is displayed; final int REFLASHING = 3; // refresh status; IReflashListener iReflushListener; // The interface for refreshing data/*** three constructor methods and initializing the view */public ReFlashListView (Contex T context) {super (context); initView (context);} public ReFlashListView (Context context, AttributeSet attrs) {super (context, attrs); initView (context );} public ReFlashListView (Context context, AttributeSet attrs, int defStyle) {super (context, attrs, defStyle); initView (context);}/*** initialization interface, add the layout file on the top to listview */private void initView (Context context) {LayoutInflater inflater = LayoutInflater. from (context ); Header = inflater. inflate (R. layout. header_layout, null); // first measure the parent layout; otherwise, the headerHeight is 0 measureView (header); // obtain the headerHeight = header. getMeasuredHeight (); Log. I ("tag", "headerHeight =" + headerHeight); // hide the header layout file topPadding (-headerHeight); // Add the header layout in listview this. addHeaderView (header); // sets the sliding listener this. setOnScrollListener (this);}/*** notification parent layout, occupied width, height; */private void measureView (View view) {ViewGroup. layoutPara MS p = view. getLayoutParams (); if (p = null) {p = new ViewGroup. layoutParams (ViewGroup. layoutParams. MATCH_PARENT, ViewGroup. layoutParams. WRAP_CONTENT);}/*** because listView does not limit the height. If the child height is high, the listView will give it a high space * But the listView is limited in width, so getChildMeasureSpec */int width = ViewGroup. getChildMeasureSpec (0, 0, p. width); int height; // obtain the itme height value int tempHeight = p. height; if (tempHeight> 0) {height = MeasureSpec. makeMeasureSpec (tempHeight, MeasureSpec. EXACTLY);} else {height = MeasureSpec. makeMeasureSpec (0, MeasureSpec. UNSPECIFIED);} view. measure (width, height);}/*** sets the header layout top margin; -- stands in the corner of the parent Layout View problems */private void topPadding (int topPadding) {header. setPadding (header. getPaddingLeft (), topPadding, header. getPaddingRight (), header. getPaddingBottom (); header. invalidate ();}/*** implementation Interface Method */@ Overridepublic void onScroll (AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {this. firstVisibleItem = firstVisibleItem;} @ Overridepublic void onScrollStateChanged (AbsListView View, int scrollState) {this. scrollState = scrollState;}/*** touch Method */@ Overridepublic boolean onTouchEvent (MotionEvent ev) {switch (ev. getAction () {/*** if the finger is pressed, if firstVisibleItem = 0, the flag is set to true, * At the top of the screen and obtain the y-axis distance */case MotionEvent. ACTION_DOWN: if (firstVisibleItem = 0) {isRemark = true; startY = (int) ev. getY ();} break; case MotionEvent. ACTION_MOVE:/*** determines the operation in the movement process; */onMove (ev); break; ca Se MotionEvent. ACTION_UP: if (state = RELESE) {state = REFLASHING; // load the latest data; reflashViewByState (); iReflushListener. onReflush () ;}else if (state = PULL) {state = NONE; isRemark = false; reflashViewByState () ;}break;} return super. onTouchEvent (ev);}/*** when the finger presses */private void onMove (MotionEvent ev) {// if it is not pressed at the top of the listview, return directly, if (! IsRemark) {return;} int tempY = (int) ev. getY (); // get the moving distance int space = tempY-startY; // get the padding value of the latest header layout int topPadding = space-headerHeight; switch (state) {/*** judge the status value of the refresh arrow */case NONE: // if you move it a little bit, change it to the status -- pull down to refresh if (space> 0) {// If the status is normal, you can change the status to the drop-down list to refresh state = PULL; // you can change the interface display according to the current status; reflashViewByState () ;} break; case PULL: // re-paint the latest header layout topPadding (topPadding); // if the height of the header layout is greater than 30, the status value is changed directly if (space-headerHeight> 30 && ScrollState = SCROLL_STATE_TOUCH_SCROLL) {// modify the state to -- release to refresh state = RELESE; reflashViewByState ();} break; case RELESE: // re-paint the latest header layout degree topPadding (topPadding); if (space-headerHeight <30) {// change the status -- click the drop-down list to refresh state = PULL; reflashViewByState ();} else if (space <= 0) {// when space <= 0, that is, the visible item index is not 0 state = NONE; // restore isRemark = false; reflashViewByState ();} break;}/*** changes the interface display based on the current status. */private void reflashViewByState () {T ExtView tip = (TextView) header. findViewById (R. id. tip); ImageView arrow = (ImageView) header. findViewById (R. id. arrow); ProgressBar progress = (ProgressBar) header. findViewById (R. id. progress); RotateAnimation anim = new RotateAnimation (0,180, RotateAnimation. RELATIVE_TO_SELF, 0.5f, RotateAnimation. RELATIVE_TO_SELF, 0.5f); anim. setDuration (1, 500); anim. setFillAfter (true); RotateAnimation anim1 = new RotateAn Imation (180, 0, RotateAnimation. RELATIVE_TO_SELF, 0.5f, RotateAnimation. RELATIVE_TO_SELF, 0.5f); anim1.setDuration (500); anim1.setFillAfter (true); switch (state) {case NONE: arrow. clearAnimation (); topPadding (-headerHeight); break; case PULL: arrow. setVisibility (View. VISIBLE); progress. setVisibility (View. GONE); tip. setText ("pull down to refresh! "); Arrow. clearAnimation (); arrow. setAnimation (anim1); break; case RELESE: arrow. setVisibility (View. VISIBLE); progress. setVisibility (View. GONE); tip. setText ("release to refresh! "); Arrow. clearAnimation (); arrow. setAnimation (anim); break; case REFLASHING: topPadding (50); arrow. setVisibility (View. GONE); progress. setVisibility (View. VISIBLE); tip. setText ("refreshing... "); arrow. clearAnimation (); break;}/*** get data; */public void reflashComplete () {// restore the refresh status to normal state = NONE; // restore status isRemark = false; reflashViewByState (); TextView lastupdatetime = (TextView) header. findViewById (R. id. lastupdate_time); SimpleDateFormat format = new SimpleDateFormat ("MM dd, yyyy hh: mm: ss"); Date date = new Date (System. currentTimeMillis (); String time = format. format (date); lastupdatetime. setText (time);} public void setInterface (IReflashListener iReflushListener) {this. iReflushListener = iReflushListener;}/*** data refresh interface * @ author Administrator */public interface IReflashListener {public void onReflush ();}}
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.