下拉重新整理(二)

來源:互聯網
上載者:User

標籤:


先看主布局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="下拉可以重新整理!" />            <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/progress"            style="?android:attr/progressBarStyleSmall"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_toLeftOf="@id/layout"            android:layout_marginRight="20dip"            android:visibility="gone" />    </RelativeLayout></LinearLayout>

在看listview的每個item的布局

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="應用程式名稱字"                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="應用程式資訊"                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="安裝"            />    </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="應用程式描述"        android:textSize="14dip" /></LinearLayout>

以上的三個布局可以看,知道個大概,這個不是主要的


接下來看bean類

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;}}

接下來看主程代碼

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 listview;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 載入布局--只有一個listViewsetContentView(R.layout.activity_main);// 設定資料setData();//填充資料showList(apk_list);}/** * 設定資料來源 */private void setData() {apk_list = new ArrayList<ApkEntity>();for (int i = 0; i < 10; i++) {ApkEntity entity = new ApkEntity();entity.setName("預設資料");entity.setInfo("50w使用者");entity.setDes("這是一個神奇的應用");apk_list.add(entity);}}private void showList(ArrayList<ApkEntity> apk_list) {if (adapter == null) {listview = (ReFlashListView) findViewById(R.id.listview);//為本類設定監聽,然後implements IReflashListenerlistview.setInterface(this);adapter = new MyAdapter(this, apk_list);//如果適配器為null,設定適配器即可listview.setAdapter(adapter);} else {//如果適配器不為null,就更新資料來源,進行notifyDataSetChanged()adapter.onDateChange(apk_list);}}/** * 實現重新整理操作的回調方法 */@Overridepublic void onReflush () {Handler handler = new Handler();handler.postDelayed(new Runnable() {@Overridepublic void run() {// 擷取最新資料setReflashData();// 通知介面顯示showList(apk_list);// 通知listview 重新整理資料完畢!!!!!!!!!!!!!!listview.reflashComplete();}}, 2000);}private void setReflashData() {for (int i = 0; i < 2; i++) {ApkEntity entity = new ApkEntity();entity.setName("重新整理資料");entity.setDes("這是一個神奇的應用");entity.setInfo("50w使用者");apk_list.add(0, entity);}}}

接下來看適配器代碼

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;}}
接下來看自訂listview類了(裡面代碼詳細)

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.widget.AbsListView.OnScrollListener;import android.widget.ImageView;import android.widget.ListView;import android.widget.ProgressBar;import android.widget.TextView;import com.example.listviewfrashdemo1.R;/** * 隱藏頭布局--先測量父布局,擷取頭布局高度,設定padding,然後隱藏頭布局,listview在添加頭布局 * 設定監聽事件 * 判斷ontouch時間 * 設定監聽載入重新整理的資料 */public class ReFlashListView extends ListView implements OnScrollListener {View header;// 頂部布局檔案;int headerHeight;// 頂部布局檔案的高度;int firstVisibleItem;// 當前第一個可見的item的位置;int scrollState;// listview 當前滾動狀態;boolean isRemark;// 標記,當前是在listview最頂端摁下的;int startY;// 摁下時的Y值;int state;// 當前的狀態;final int NONE = 0;// 正常狀態;final int PULL = 1;// 提示下拉狀態;final int RELESE = 2;// 提示釋放狀態;final int REFLASHING = 3;// 重新整理狀態;IReflashListener iReflushListener;//重新整理資料的介面/** * 三個構造方法,並且初始化視圖 */public ReFlashListView(Context 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);}/** * 初始化介面,添加頂部布局檔案到 listview */private void initView(Context context) {LayoutInflater inflater = LayoutInflater.from(context);header = inflater.inflate(R.layout.header_layout, null);//先測量父布局,不然headerHeight為0measureView(header);//擷取頭布局檔案的高度headerHeight = header.getMeasuredHeight();Log.i("tag", "headerHeight = " + headerHeight);//隱藏頭布局檔案topPadding(-headerHeight);//listview添加頭布局this.addHeaderView(header);//設定滑動監聽this.setOnScrollListener(this);}/** * 通知父布局,佔用的寬,高; */private void measureView(View view) {ViewGroup.LayoutParams p = view.getLayoutParams();if (p == null) {p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);}/** * 因為listView不限制高度。child有多高,listView就給它多高的空間 * 但是listView是限制寬度的,所以需要getChildMeasureSpec */int width = ViewGroup.getChildMeasureSpec(0, 0, p.width);int height;//擷取itme的高度值int tempHeight = p.height;if (tempHeight > 0) {height = MeasureSpec.makeMeasureSpec(tempHeight,MeasureSpec.EXACTLY);} else {height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);}view.measure(width, height);}/** * 設定header 布局 上邊距;--站在父布局的角度看待問題 */private void topPadding(int topPadding) {header.setPadding(header.getPaddingLeft(), topPadding,header.getPaddingRight(), header.getPaddingBottom());header.invalidate();}/** * 實現介面方法 */@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方法 */@Overridepublic boolean onTouchEvent(MotionEvent ev) {switch (ev.getAction()) {/** * 如果手指按下,如果firstVisibleItem == 0就設定標記為true,代表是在最頂端按下的 * 並且擷取按下的座標Y軸距離 */case MotionEvent.ACTION_DOWN:if (firstVisibleItem == 0) {isRemark = true;startY = (int) ev.getY();}break;case MotionEvent.ACTION_MOVE:/** * 判斷移動過程操作; */onMove(ev);break;case MotionEvent.ACTION_UP:if (state == RELESE) {state = REFLASHING;// 載入最新資料;reflashViewByState();iReflushListener.onReflush();} else if (state == PULL) {state = NONE;isRemark = false;reflashViewByState();}break;}return super.onTouchEvent(ev);}/** * 當手指按下 */private void onMove(MotionEvent ev) {//如果不是在listview在最頂端時候按下的,直接返回,不做處理if (!isRemark) {return;}int tempY = (int) ev.getY();//擷取移動的距離int space = tempY - startY;//擷取最新的頭布局的padding值int topPadding = space - headerHeight;switch (state) {/** * 判斷重新整理箭頭的狀態值 */case NONE://如果稍微調動就改成狀態是--下拉可以重新整理if (space > 0) {//如果是正常狀態,就修改狀態為下拉可以重新整理state = PULL;//根據目前狀態,改變介面顯示;reflashViewByState();}break;case PULL://重繪最新的頭布局隱藏程度topPadding(topPadding);//如果比頭布局高度還大於30就直接改變狀態值if (space-headerHeight>  30&& scrollState == SCROLL_STATE_TOUCH_SCROLL) {//修改狀態為--鬆開可以重新整理state = RELESE;reflashViewByState();}break;case RELESE://重繪最新的頭布局隱藏程度topPadding(topPadding);if (space-headerHeight < 30) {//改變狀態--下拉可以重新整理state = PULL;reflashViewByState();} else if (space <= 0) {//當space<=0,即可見的item索引不是0state = NONE;//還原isRemark = false;reflashViewByState();}break;}}/** * 根據目前狀態,改變介面顯示; */private void reflashViewByState() {TextView 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(500);anim.setFillAfter(true);RotateAnimation anim1 = new RotateAnimation(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("下拉可以重新整理!");arrow.clearAnimation();arrow.setAnimation(anim1);break;case RELESE:arrow.setVisibility(View.VISIBLE);progress.setVisibility(View.GONE);tip.setText("鬆開可以重新整理!");arrow.clearAnimation();arrow.setAnimation(anim);break;case REFLASHING:topPadding(50);arrow.setVisibility(View.GONE);progress.setVisibility(View.VISIBLE);tip.setText("正在重新整理...");arrow.clearAnimation();break;}}/** * 擷取完資料; */public void reflashComplete() {//將重新整理狀態還原成正常狀態state = NONE;//還原狀態isRemark = false;reflashViewByState();TextView lastupdatetime = (TextView) header.findViewById(R.id.lastupdate_time);SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 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;}/** * 重新整理資料介面 * @author Administrator */public interface IReflashListener{public void onReflush();}}



著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

下拉重新整理(二)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.