【安卓笔记】下拉刷新组件的使用及实现
<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" tools:context="com.example.flushlistview.MainActivity" > <com.handmark.pulltorefresh.library.PullToRefreshListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent" android:divider="#19000000" android:dividerHeight="4dp" > </com.handmark.pulltorefresh.library.PullToRefreshListView> </RelativeLayout>
listView的item布局:
<?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" > <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#000" android:textSize="20sp" /> </LinearLayout>界面逻辑:
package com.example.flushlistview; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; import com.handmark.pulltorefresh.library.PullToRefreshBase; import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener; import com.handmark.pulltorefresh.library.PullToRefreshListView; /** * @author Rowandjj * *使用pull-to-refresh库实现下拉刷新操作 */ public class MainActivity extends Activity { private PullToRefreshListView lv; private ArrayAdapter<String> adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv = (PullToRefreshListView) findViewById(R.id.lv); List<String> list = new ArrayList<String>(); list.add("张三"); list.add("李四"); list.add("王五"); list.add("赵六"); list.add("啊啊"); list.add("呵呵"); list.add("嘻嘻"); list.add("嘿嘿"); adapter = new ArrayAdapter<String>(this, R.layout.item, R.id.tv, list); lv.setAdapter(adapter); //实现刷新接口 lv.setOnRefreshListener(new OnRefreshListener<ListView>() { @Override public void onRefresh(PullToRefreshBase<ListView> refreshView) { Date date = new Date(System.currentTimeMillis()); SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日hh时mm分ss秒",Locale.CHINA); String updateTime = format.format(date); refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(updateTime); //异步刷新 new UpdateTask().execute(); } }); } private class UpdateTask extends AsyncTask<Void, Void,List<String>> { @Override protected List<String> doInBackground(Void... params) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } List<String> newData = new ArrayList<String>(); newData.add("新数据1"); newData.add("新数据2"); newData.add("新数据3"); return newData; } @Override protected void onPostExecute(List<String> result) { adapter.addAll(result); //刷新完成 lv.onRefreshComplete(); } } }效果:
<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" tools:context="com.example.swiperefreshlayoutdemo.MainActivity" > <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/activity_main_swipe_refresh_layout" android:layout_width="match_parent" android:layout_height="wrap_content" > <ListView android:id="@+id/activity_main_listview" android:layout_width="match_parent" android:layout_height="match_parent" > </ListView> </android.support.v4.widget.SwipeRefreshLayout> </RelativeLayout>item布局:
<?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" > <TextView android:id="@+id/tv" android:layout_width="match_parent" android:layout_height="40dip" android:textColor="#000" android:gravity="center_vertical" android:textSize="18sp" /> </LinearLayout>页面逻辑:
package com.example.swiperefreshlayoutdemo; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener; import android.widget.ArrayAdapter; import android.widget.ListView; public class MainActivity extends Activity { private ListView mListView; private SwipeRefreshLayout mRefreshLayout; private ArrayAdapter<String> mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mListView = (ListView) findViewById(R.id.activity_main_listview); mRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.activity_main_swipe_refresh_layout); List<String> data = new ArrayList<String>(); for (int i = 0; i < 15; i++) { data.add("这是数据" + i); } mAdapter = new ArrayAdapter<String>(this, R.layout.item, R.id.tv, data); mListView.setAdapter(mAdapter); mRefreshLayout.setOnRefreshListener(new OnRefreshListener() { @Override public void onRefresh() { new UpdateTask().execute(); } }); } private class UpdateTask extends AsyncTask<Void, Void, List<String>> { @Override protected List<String> doInBackground(Void... params) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } List<String> newData = new ArrayList<String>(); newData.add("新数据1"); newData.add("新数据2"); newData.add("新数据3"); return newData; } @Override protected void onPostExecute(List<String> result) { mAdapter.addAll(result); //通知数据更新完毕 mRefreshLayout.setRefreshing(false); } } }效果:
package com.example.mypulltorefreshlistview.ui; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; 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.animation.Animation; import android.view.animation.AnimationUtils; 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.mypulltorefreshlistview.R; public class PullToRefreshListView extends ListView implements OnScrollListener { private static final String TAG = "PullToRefreshListView"; /** *顶部布局 */ private View mHeaderView; /** * header的高度 */ private int mHeaderHeight; /** * 当前页面已经滑到顶部 */ private boolean flag; /** * 初始滑动时的y坐标 */ private int mStartY; /** * 正常状态 */ public static final int STATE_NORMAL = 0; /** * 下拉刷新状态 */ public static final int STATE_PULL_TO_REFRESH = 1; /** * 释放刷新状态 */ public static final int STATE_RELEASE_TO_REFRESH = 2; /** * 正在刷新状态 */ public static final int STATE_REFRESH = 3; /** * 当前状态 */ private int mCurrentState; private static final int DEFAULT_LENGTH = 70; private OnRefreshListener mRefreshListener; public PullToRefreshListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } public PullToRefreshListView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public PullToRefreshListView(Context context) { super(context); init(context); } public void setOnRefreshListener(OnRefreshListener listener) { this.mRefreshListener = listener; } /** * 初始化操作 * @param context */ private void init(Context context) { //添加headerview mHeaderView = LayoutInflater.from(context).inflate(R.layout.header_layout,null); this.addHeaderView(mHeaderView); //设置滚动监听器 this.setOnScrollListener(this); //通过设置padding将hider隐藏 //注:因为此时无法获得header的高度,所以放入MessageQueue中 post(new HideHeaderAction()); } /** * 设置header的padding * @param topPadding */ private void setHeaderTopPadding(int topPadding) { if(mHeaderView != null) { mHeaderView.setPadding(mHeaderView.getPaddingLeft(),topPadding,mHeaderView.getPaddingRight(),mHeaderView.getPaddingBottom()); } } @Override public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) { if(firstVisibleItem == 0) flag = true; else flag = false; } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public boolean onTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: if(flag) { mStartY = (int) ev.getY(); } break; case MotionEvent.ACTION_MOVE: performMove(ev); break; case MotionEvent.ACTION_UP: if(mCurrentState == STATE_RELEASE_TO_REFRESH) { mCurrentState = STATE_REFRESH; updateUIByState(); //TODO 加载新数据 if(mRefreshListener == null) { throw new RuntimeException("you must call setOnRefreshListener before..."); }else { mRefreshListener.onRefresh(this); } }else if(mCurrentState == STATE_PULL_TO_REFRESH) { mCurrentState = STATE_NORMAL; flag = false; updateUIByState(); } break; } return super.onTouchEvent(ev); } private void updateUIByState() { TextView tip = (TextView) findViewById(R.id.tip); ImageView arrow = (ImageView) findViewById(R.id.arrow); ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress); Animation anim1 = AnimationUtils.loadAnimation(getContext(),R.anim.rotate_1); Animation anim2 = AnimationUtils.loadAnimation(getContext(),R.anim.rotate_2); switch (mCurrentState) { case STATE_NORMAL: setHeaderTopPadding(-mHeaderHeight); break; case STATE_PULL_TO_REFRESH: arrow.clearAnimation(); arrow.setAnimation(anim1); arrow.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); tip.setText("下拉可以刷新..."); break; case STATE_RELEASE_TO_REFRESH: arrow.clearAnimation(); arrow.setAnimation(anim2); arrow.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); tip.setText("松开可以刷新..."); break; case STATE_REFRESH: arrow.clearAnimation(); setHeaderTopPadding(mHeaderHeight); arrow.setVisibility(View.GONE); progressBar.setVisibility(View.VISIBLE); tip.setText("正在刷新..."); break; default: break; } } private void performMove(MotionEvent ev) { if(!flag) { return; } int currY = (int) ev.getY(); int deltaY = currY-mStartY; if(deltaY > mHeaderHeight+DEFAULT_LENGTH) deltaY = mHeaderHeight+DEFAULT_LENGTH; switch (mCurrentState) { case STATE_NORMAL: if(deltaY > 0) { mCurrentState = STATE_PULL_TO_REFRESH; } break; case STATE_PULL_TO_REFRESH: setHeaderTopPadding(deltaY-mHeaderHeight); updateUIByState(); if(deltaY >= mHeaderHeight+DEFAULT_LENGTH) { mCurrentState = STATE_RELEASE_TO_REFRESH; }else if(deltaY <= 0) { mCurrentState = STATE_NORMAL; } break; case STATE_RELEASE_TO_REFRESH: // setHeaderTopPadding(deltaY-mHeaderHeight); updateUIByState(); if(deltaY < mHeaderHeight+DEFAULT_LENGTH) { mCurrentState = STATE_PULL_TO_REFRESH; }else if(deltaY <= 0) { mCurrentState = STATE_NORMAL; } break; } } /** * 更新完毕时调用 */ public void refreshComplete() { TextView lastUpdateTime = (TextView) findViewById(R.id.last_update_time); SimpleDateFormat format = new SimpleDateFormat("MM-dd hh:mm",Locale.CHINA); String updateTime = format.format(new Date(System.currentTimeMillis())); lastUpdateTime.setText("更新于 "+updateTime); mCurrentState = STATE_NORMAL; updateUIByState(); } public interface OnRefreshListener { public void onRefresh(PullToRefreshListView listView); } private class HideHeaderAction implements Runnable { @Override public void run() { //获取header的高度 mHeaderHeight = mHeaderView.getMeasuredHeight();//view在被渲染前无法获得其宽高 Log.d(TAG,"Headerheight:"+mHeaderHeight); //通过设置header的padding来隐藏header setHeaderTopPadding(-mHeaderHeight); } } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。