Welcome

首页 / 移动开发 / Android / Android学习教程之下拉刷新实现代码(11)

本文实例为大家分享了Android下拉刷新的具体代码,供大家参考,具体内容如下
MainActivity.java代码:
package siso.refreshablev;import android.app.Activity;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.widget.TextView;import refreshableview.RefreshableView;import refreshableview.refreshablehelper.RefreshableHelper;public class MainActivity extends Activity implements View.OnClickListener { private static final String TAG = MainActivity.class.getSimpleName(); private RefreshableView refreshableView; /** * Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); findViewById(R.id.main_tv).setOnClickListener(this); refreshableView = (RefreshableView) findViewById(R.id.main_refresh_view); refreshableView.setRefreshableHelper(new RefreshableHelper() {@Overridepublic View onInitRefreshHeaderView() {return LayoutInflater.from(MainActivity.this).inflate(R.layout.refresh_head, null);}@Overridepublic boolean onInitRefreshHeight(int originRefreshHeight) {refreshableView.setRefreshNormalHeight(refreshableView.getOriginRefreshHeight() / 3);refreshableView.setRefreshingHeight(refreshableView.getOriginRefreshHeight());refreshableView.setRefreshArrivedStateHeight(refreshableView.getOriginRefreshHeight());return false;}@Overridepublic void onRefreshStateChanged(View refreshView, int refreshState) {TextView tv = (TextView) refreshView.findViewById(R.id.refresh_head_tv);switch (refreshState) { case RefreshableView.STATE_REFRESH_NORMAL: tv.setText("正常状态"); break; case RefreshableView.STATE_REFRESH_NOT_ARRIVED: tv.setText("往下拉可以刷新"); break; case RefreshableView.STATE_REFRESH_ARRIVED: tv.setText("放手可以刷新"); break; case RefreshableView.STATE_REFRESHING: tv.setText("正在刷新"); new Thread(new Runnable() { @Override public void run() { try {Thread.sleep(1000l);runOnUiThread(new Runnable() {@Overridepublic void run() { refreshableView.onCompleteRefresh();}}); } catch (InterruptedException e) {Log.e(TAG, "_", e); } }} ).start(); break;}} }); } @Override public void onClick(View v) { switch (v.getId()) {case R.id.main_tv:Log.d(TAG, "content clicked");startActivity(new Intent(this, RefreshableListActivity.class));break; } }}
RefreshableListActivity.java代码:
package siso.refreshablev;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.widget.ArrayAdapter;import android.widget.TextView;import java.util.ArrayList;import java.util.List;import refreshableview.RefreshableListView;import refreshableview.RefreshableView;import refreshableview.refreshablehelper.RefreshableHelper;public class RefreshableListActivity extends Activity { private static final String TAG = RefreshableListActivity.class.getSimpleName(); RefreshableListView lv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.refreshable_list); lv = (RefreshableListView) findViewById(R.id.refreshable_lv); lv.setRefreshableHelper(new RefreshableHelper() {@Overridepublic View onInitRefreshHeaderView() {return LayoutInflater.from(RefreshableListActivity.this).inflate(R.layout.refresh_head, null);}@Overridepublic boolean onInitRefreshHeight(int originRefreshHeight) {lv.setRefreshNormalHeight(lv.getOriginRefreshHeight() / 3);lv.setRefreshingHeight(lv.getOriginRefreshHeight());lv.setRefreshArrivedStateHeight(lv.getOriginRefreshHeight());return false;}@Overridepublic void onRefreshStateChanged(View refreshView, int refreshState) {TextView tv = (TextView) refreshView.findViewById(R.id.refresh_head_tv);switch (refreshState) { case RefreshableView.STATE_REFRESH_NORMAL: tv.setText("正常状态"); break; case RefreshableView.STATE_REFRESH_NOT_ARRIVED: tv.setText("往下拉可以刷新"); break; case RefreshableView.STATE_REFRESH_ARRIVED: tv.setText("放手可以刷新"); break; case RefreshableView.STATE_REFRESHING: tv.setText("正在刷新"); new Thread(new Runnable() { @Override public void run() { try {Thread.sleep(1000l);runOnUiThread(new Runnable() {@Overridepublic void run() { lv.onCompleteRefresh();}}); } catch (InterruptedException e) {Log.e(TAG, "_", e); } }} ).start(); break;}} }); List<String> data = new ArrayList<String>(); for (int i = 0; i < 30; i++) {data.add("item_" + i); } ArrayAdapter adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data); lv.setAdapter(adapter); adapter.notifyDataSetChanged(); }}
NestScrollView.java代码:
package refreshableview;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.ViewParent;import android.widget.ScrollView;public class NestScrollView extends ScrollView { private static final String TAG = NestScrollView.class.getSimpleName(); public NestScrollView(Context context) { super(context); } public NestScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public NestScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.d(TAG, "___[dispatchTouchEvent]ev action: " + ev.getAction()); return super.dispatchTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { super.onInterceptTouchEvent(ev); Log.d(TAG, "___[onInterceptTouchEvent]ev action: " + ev.getAction()); if (MotionEvent.ACTION_MOVE == ev.getAction()) {return true; } return false; } float lastDownY; @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); switch (event.getAction()) {case MotionEvent.ACTION_DOWN:lastDownY = event.getY();parentRequestDisallowInterceptTouchEvent(true); // 保证事件可往下传递Log.d(TAG, "___Down");return true;//break;case MotionEvent.ACTION_MOVE:Log.d(TAG, "___move, this.getScrollY(): " + this.getScrollY());boolean isTop = event.getY() - lastDownY > 0 && this.getScrollY() == 0;if (isTop) { // 允许父控件拦截,即不允许父控件拦截设为false parentRequestDisallowInterceptTouchEvent(false); return false;} else { // 不允许父控件拦截,即不允许父控件拦截设为true parentRequestDisallowInterceptTouchEvent(true); return true;}//break;case MotionEvent.ACTION_UP:Log.d(TAG, "___up, this.getScrollY(): " + this.getScrollY());parentRequestDisallowInterceptTouchEvent(true); // 保证事件可往下传递break;case MotionEvent.ACTION_CANCEL:Log.d(TAG, "___cancel");break; } return false; } /** * 是否允许父控件拦截事件 * @param disallowIntercept */ private void parentRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { ViewParent vp = getParent(); if (null == vp) {return; } vp.requestDisallowInterceptTouchEvent(disallowIntercept); }}
RefreshableListView.java代码:
package refreshableview;import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.animation.ValueAnimator;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.animation.LinearInterpolator;import android.widget.ListAdapter;import android.widget.ListView;import refreshableview.refreshablehelper.RefreshableHelper;public class RefreshableListView extends ListView { private static final String TAG = RefreshableListView.class.getSimpleName(); public RefreshableListView(Context context) { super(context); init(context); } public RefreshableListView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public RefreshableListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } /** * 刷新状态 */ public static final int STATE_REFRESH_NORMAL = 0x21; public static final int STATE_REFRESH_NOT_ARRIVED = 0x22; public static final int STATE_REFRESH_ARRIVED = 0x23; public static final int STATE_REFRESHING = 0x24; private int refreshState; // 刷新状态监听 private RefreshableHelper refreshableHelper; /** * 刷新的view */ private View refreshHeaderView; /** * 刷新的view的真实高度 */ private int originRefreshHeight; /** * 有效下拉刷新需要达到的高度 */ private int refreshArrivedStateHeight; /** * 刷新时显示的高度 */ private int refreshingHeight; /** * 正常未刷新高度 */ private int refreshNormalHeight; public void setRefreshableHelper(RefreshableHelper refreshableHelper) { this.refreshableHelper = refreshableHelper; } private Context context; private void init(Context context) { this.context = context; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); Log.d(TAG, "[onSizeChanged]w: " + w + ", h: " + h); Log.d(TAG, "[onSizeChanged]oldw: " + oldw + ", oldh: " + oldh); Log.d(TAG, "[onSizeChanged]child counts: " + this.getChildCount()); } @Override public void setAdapter(ListAdapter adapter) { if (null == refreshHeaderView) {addHeaderView(); } super.setAdapter(adapter); } private void addHeaderView() { if (null != refreshableHelper) {refreshHeaderView = refreshableHelper.onInitRefreshHeaderView(); } if (null == refreshHeaderView) {Log.e(TAG, "refreshHeaderView is null!");return; } this.addHeaderView(refreshHeaderView); // 计算refreshHeadView尺寸 int width = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); refreshHeaderView.measure(width, expandSpec); originRefreshHeight = refreshHeaderView.getMeasuredHeight(); boolean isUseDefault = true; if (null != refreshableHelper) {isUseDefault = refreshableHelper.onInitRefreshHeight(originRefreshHeight); } // 初始化各个高度 if (isUseDefault) {refreshArrivedStateHeight = originRefreshHeight;refreshingHeight = originRefreshHeight;refreshNormalHeight = 0; } Log.d(TAG, "[onSizeChanged]refreshHeaderView origin height: " + originRefreshHeight); changeViewHeight(refreshHeaderView, refreshNormalHeight); // 初始化为正常状态 setRefreshState(STATE_REFRESH_NORMAL); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { super.dispatchTouchEvent(ev);// if(MotionEvent.ACTION_MOVE == ev.getAction()){//return true;// }// return false; return true; } private float lastDownY = Float.MAX_VALUE; @Override public boolean onTouchEvent(MotionEvent ev) {// super.onTouchEvent(ev); Log.d(TAG, "[onTouchEvent]ev action: " + ev.getAction()); switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:super.onTouchEvent(ev);lastDownY = ev.getY();Log.d(TAG, "Down --> lastDownY: " + lastDownY);break;case MotionEvent.ACTION_MOVE:float curY = ev.getY();float deltaY = curY - lastDownY;Log.d(TAG, "Move --> deltaY(curY - downY): " + deltaY);int curHeight = refreshHeaderView.getMeasuredHeight();int exceptHeight = curHeight + (int) (deltaY / 2);//boolean isTop = this.getScrollY() == 0;boolean isTop = 0 == this.getChildAt(0).getTop();boolean isDropDown = curY - lastDownY > 0;Log.d(TAG, "isTop: " + isTop + ", getTop(): " + this.getChildAt(0).getTop());if (isTop) { if (refreshState == STATE_REFRESH_NORMAL && !isDropDown) { // 正常状态,手指往上(列表往下滚动) super.onTouchEvent(ev); } else { // 如果当前没有处在正在刷新状态,则更新刷新状态 if (STATE_REFRESHING != refreshState) {if (curHeight >= refreshArrivedStateHeight) { // 达到可刷新状态setRefreshState(STATE_REFRESH_ARRIVED);} else if (curHeight == refreshNormalHeight) { // 正常状态setRefreshState(STATE_REFRESH_NORMAL);} else { // 未达到可刷新状态setRefreshState(STATE_REFRESH_NOT_ARRIVED);}changeViewHeight(refreshHeaderView, Math.max(refreshNormalHeight, exceptHeight)); } else {super.onTouchEvent(ev); } }} else { super.onTouchEvent(ev);}lastDownY = curY;break;case MotionEvent.ACTION_UP:super.onTouchEvent(ev);lastDownY = Float.MAX_VALUE;Log.d(TAG, "Up --> lastDownY: " + lastDownY);// 如果是达到刷新状态,则设置正在刷新状态的高度if (STATE_REFRESH_ARRIVED == refreshState) { // 达到了刷新的状态 startHeightAnimation(refreshHeaderView, refreshHeaderView.getMeasuredHeight(), refreshingHeight); setRefreshState(STATE_REFRESHING);} else if (STATE_REFRESHING == refreshState) { // 正在刷新的状态 startHeightAnimation(refreshHeaderView, refreshHeaderView.getMeasuredHeight(), refreshingHeight);} else { // 执行动画后回归正常状态 startHeightAnimation(refreshHeaderView, refreshHeaderView.getMeasuredHeight(), refreshNormalHeight, normalAnimatorListener);}break; } return true; } /** * 刷新完毕后调用此方法 */ public void onCompleteRefresh() { if (STATE_REFRESHING == refreshState) {setRefreshState(STATE_REFRESH_NORMAL);startHeightAnimation(refreshHeaderView, refreshHeaderView.getMeasuredHeight(), refreshNormalHeight); } } /** * 修改当前的刷新状态 * * @param expectRefreshState */ private void setRefreshState(int expectRefreshState) { if (expectRefreshState != refreshState) {refreshState = expectRefreshState;if (null != refreshableHelper) {refreshableHelper.onRefreshStateChanged(refreshHeaderView, refreshState);} } } /** * 改变某控件的高度 * * @param view * @param height */ private void changeViewHeight(View view, int height) { Log.d(TAG, "[changeViewHeight]change Height: " + height); ViewGroup.LayoutParams lp = view.getLayoutParams(); if (null == lp) {lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0); } lp.height = height; view.setLayoutParams(lp); } /** * 改变某控件的高度动画 * * @param view * @param fromHeight * @param toHeight */ private void startHeightAnimation(final View view, int fromHeight, int toHeight) { startHeightAnimation(view, fromHeight, toHeight, null); } private void startHeightAnimation(final View view, int fromHeight, int toHeight, Animator.AnimatorListener animatorListener) { if (toHeight == view.getMeasuredHeight()) {return; } ValueAnimator heightAnimator = ValueAnimator.ofInt(fromHeight, toHeight); heightAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {Integer value = (Integer) valueAnimator.getAnimatedValue();if (null == value) return;changeViewHeight(view, value);} }); if (null != animatorListener) {heightAnimator.addListener(animatorListener); } heightAnimator.setInterpolator(new LinearInterpolator()); heightAnimator.setDuration(300/*ms*/); heightAnimator.start(); } AnimatorListenerAdapter normalAnimatorListener = new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) {super.onAnimationEnd(animation);setRefreshState(STATE_REFRESH_NORMAL); // 回归正常状态 } }; public void setRefreshArrivedStateHeight(int refreshArrivedStateHeight) { this.refreshArrivedStateHeight = refreshArrivedStateHeight; } public void setRefreshingHeight(int refreshingHeight) { this.refreshingHeight = refreshingHeight; } public void setRefreshNormalHeight(int refreshNormalHeight) { this.refreshNormalHeight = refreshNormalHeight; } public int getOriginRefreshHeight() { return originRefreshHeight; }}
RefreshableView.java代码:
package refreshableview;import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.animation.ValueAnimator;import android.content.Context;import android.content.res.TypedArray;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.animation.LinearInterpolator;import android.widget.LinearLayout;import refreshableview.refreshablehelper.RefreshableHelper;import siso.refreshablev.R;public class RefreshableView extends LinearLayout { private static final String TAG = RefreshableView.class.getSimpleName(); public RefreshableView(Context context) { super(context); init(context); } public RefreshableView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.refreshableView); for (int i = 0, len = a.length(); i < len; i++) {int attrIndex = a.getIndex(i);switch (attrIndex) {case R.styleable.refreshableView_interceptAllMoveEvents: interceptAllMoveEvents = a.getBoolean(i, false); break;} } a.recycle(); init(context); } public RefreshableView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } /** * 刷新状态 */ public static final int STATE_REFRESH_NORMAL = 0x21; public static final int STATE_REFRESH_NOT_ARRIVED = 0x22; public static final int STATE_REFRESH_ARRIVED = 0x23; public static final int STATE_REFRESHING = 0x24; private int refreshState; // 刷新状态监听 private RefreshableHelper refreshableHelper; public void setRefreshableHelper(RefreshableHelper refreshableHelper) { this.refreshableHelper = refreshableHelper; } private Context context; /** * 刷新的view */ private View refreshHeaderView; /** * 刷新的view的真实高度 */ private int originRefreshHeight; /** * 有效下拉刷新需要达到的高度 */ private int refreshArrivedStateHeight; /** * 刷新时显示的高度 */ private int refreshingHeight; /** * 正常未刷新高度 */ private int refreshNormalHeight; /** * 默认不允许拦截(即,往子view传递事件),该属性只有在interceptAllMoveEvents为false的时候才有效 */ private boolean disallowIntercept = true; /** * xml中可设置它的值为false,表示不把移动的事件传递给子控件 */ private boolean interceptAllMoveEvents; private void init(Context context) { this.context = context; this.setOrientation(VERTICAL);// Log.d(TAG, "[init]originRefreshHeight: " + refreshHeaderView.getMeasuredHeight()); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (null != refreshableHelper) {refreshHeaderView = refreshableHelper.onInitRefreshHeaderView(); }// refreshHeaderView = LayoutInflater.from(context).inflate(R.layout.refresh_head, null); if (null == refreshHeaderView) {Log.e(TAG, "refreshHeaderView is null!");return; } this.removeView(refreshHeaderView); this.addView(refreshHeaderView, 0); // 计算refreshHeadView尺寸 int width = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); refreshHeaderView.measure(width, expandSpec); Log.d(TAG, "[onSizeChanged]w: " + w + ", h: " + h); Log.d(TAG, "[onSizeChanged]oldw: " + oldw + ", oldh: " + oldh); Log.d(TAG, "[onSizeChanged]child counts: " + this.getChildCount()); originRefreshHeight = refreshHeaderView.getMeasuredHeight(); boolean isUseDefault = true; if (null != refreshableHelper) {isUseDefault = refreshableHelper.onInitRefreshHeight(originRefreshHeight); } // 初始化各个高度 if (isUseDefault) {refreshArrivedStateHeight = originRefreshHeight;refreshingHeight = originRefreshHeight;refreshNormalHeight = 0; } Log.d(TAG, "[onSizeChanged]refreshHeaderView origin height: " + originRefreshHeight); changeViewHeight(refreshHeaderView, refreshNormalHeight); // 初始化为正常状态 setRefreshState(STATE_REFRESH_NORMAL); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.d(TAG, "[dispatchTouchEvent]ev action: " + ev.getAction()); return super.dispatchTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.d(TAG, "[onInterceptTouchEvent]ev action: " + ev.getAction()); if (!interceptAllMoveEvents) {return !disallowIntercept; } // 如果设置了拦截所有move事件,即interceptAllMoveEvents为true if (MotionEvent.ACTION_MOVE == ev.getAction()) {return true; } return false; } @Override public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { if (this.disallowIntercept == disallowIntercept) {return; } this.disallowIntercept = disallowIntercept; super.requestDisallowInterceptTouchEvent(disallowIntercept); } private float downY = Float.MAX_VALUE; @Override public boolean onTouchEvent(MotionEvent event) {// super.onTouchEvent(event); Log.d(TAG, "[onTouchEvent]ev action: " + event.getAction()); switch (event.getAction()) {case MotionEvent.ACTION_DOWN:downY = event.getY();Log.d(TAG, "Down --> downY: " + downY);requestDisallowInterceptTouchEvent(true); // 保证事件可往下传递break;case MotionEvent.ACTION_MOVE:float curY = event.getY();float deltaY = curY - downY;// 是否是有效的往下拖动事件(则需要显示加载header)boolean isDropDownValidate = Float.MAX_VALUE != downY;/** * 修改拦截设置 * 如果是有效往下拖动事件,则事件需要在本ViewGroup中处理,所以需要拦截不往子控件传递,即不允许拦截设为false * 如果不是有效往下拖动事件,则事件传递给子控件处理,所以不需要拦截,并往子控件传递,即不允许拦截设为true */requestDisallowInterceptTouchEvent(!isDropDownValidate);downY = curY;Log.d(TAG, "Move --> deltaY(curY - downY): " + deltaY);int curHeight = refreshHeaderView.getMeasuredHeight();int exceptHeight = curHeight + (int) (deltaY / 2);// 如果当前没有处在正在刷新状态,则更新刷新状态if (STATE_REFRESHING != refreshState) { if (curHeight >= refreshArrivedStateHeight) { // 达到可刷新状态 setRefreshState(STATE_REFRESH_ARRIVED); } else { // 未达到可刷新状态 setRefreshState(STATE_REFRESH_NOT_ARRIVED); }}if (isDropDownValidate) { changeViewHeight(refreshHeaderView, Math.max(refreshNormalHeight, exceptHeight));} else { // 防止从子控件修改拦截后引发的downY为Float.MAX_VALUE的问题 changeViewHeight(refreshHeaderView, Math.max(curHeight, exceptHeight));}break;case MotionEvent.ACTION_UP:downY = Float.MAX_VALUE;Log.d(TAG, "Up --> downY: " + downY);requestDisallowInterceptTouchEvent(true); // 保证事件可往下传递// 如果是达到刷新状态,则设置正在刷新状态的高度if (STATE_REFRESH_ARRIVED == refreshState) { // 达到了刷新的状态 startHeightAnimation(refreshHeaderView, refreshHeaderView.getMeasuredHeight(), refreshingHeight); setRefreshState(STATE_REFRESHING);} else if (STATE_REFRESHING == refreshState) { // 正在刷新的状态 startHeightAnimation(refreshHeaderView, refreshHeaderView.getMeasuredHeight(), refreshingHeight);} else { // 执行动画后回归正常状态 startHeightAnimation(refreshHeaderView, refreshHeaderView.getMeasuredHeight(), refreshNormalHeight, normalAnimatorListener);}break;case MotionEvent.ACTION_CANCEL:Log.d(TAG, "cancel");break; } return true; } /** * 刷新完毕后调用此方法 */ public void onCompleteRefresh() { if (STATE_REFRESHING == refreshState) {setRefreshState(STATE_REFRESH_NORMAL);startHeightAnimation(refreshHeaderView, refreshHeaderView.getMeasuredHeight(), refreshNormalHeight); } } /** * 修改当前的刷新状态 * * @param expectRefreshState */ private void setRefreshState(int expectRefreshState) { if (expectRefreshState != refreshState) {refreshState = expectRefreshState;if (null != refreshableHelper) {refreshableHelper.onRefreshStateChanged(refreshHeaderView, refreshState);} } } /** * 改变某控件的高度 * * @param view * @param height */ private void changeViewHeight(View view, int height) { Log.d(TAG, "[changeViewHeight]change Height: " + height); ViewGroup.LayoutParams lp = view.getLayoutParams(); lp.height = height; view.setLayoutParams(lp); } /** * 改变某控件的高度动画 * * @param view * @param fromHeight * @param toHeight */ private void startHeightAnimation(final View view, int fromHeight, int toHeight) { startHeightAnimation(view, fromHeight, toHeight, null); } private void startHeightAnimation(final View view, int fromHeight, int toHeight, Animator.AnimatorListener animatorListener) { if (toHeight == view.getMeasuredHeight()) {return; } ValueAnimator heightAnimator = ValueAnimator.ofInt(fromHeight, toHeight); heightAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {Integer value = (Integer) valueAnimator.getAnimatedValue();if (null == value) return;changeViewHeight(view, value);} }); if (null != animatorListener) {heightAnimator.addListener(animatorListener); } heightAnimator.setInterpolator(new LinearInterpolator()); heightAnimator.setDuration(300/*ms*/); heightAnimator.start(); } AnimatorListenerAdapter normalAnimatorListener = new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) {super.onAnimationEnd(animation);setRefreshState(STATE_REFRESH_NORMAL); // 回归正常状态 } }; public void setRefreshArrivedStateHeight(int refreshArrivedStateHeight) { this.refreshArrivedStateHeight = refreshArrivedStateHeight; } public void setRefreshingHeight(int refreshingHeight) { this.refreshingHeight = refreshingHeight; } public void setRefreshNormalHeight(int refreshNormalHeight) { this.refreshNormalHeight = refreshNormalHeight; } public int getOriginRefreshHeight() { return originRefreshHeight; }}
RefreshableHelper.java代码:
package refreshableview.refreshablehelper;import android.view.View;public interface RefreshableHelper { /** * 初始化刷新View * * @return */ View onInitRefreshHeaderView(); /** * 初始化各个尺寸高度 * * @param originRefreshHeight * @return */ boolean onInitRefreshHeight(int originRefreshHeight); /** * 刷新状态改变 * * @param refreshView * @param refreshState */ void onRefreshStateChanged(View refreshView, int refreshState);}
main.xml内容:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:rv="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <refreshableview.RefreshableViewandroid:id="@+id/main_refresh_view"android:layout_width="match_parent"android:layout_height="match_parent"rv:interceptAllMoveEvents="false"> <refreshableview.NestScrollView android:layout_width="match_parent" android:layout_height="wrap_content"android:fillViewport="true"><TextView android:id="@+id/main_tv" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:padding="20dp" android:textSize="18sp" android:text="下拉刷新










下拉刷新
下拉刷新










下拉刷新
下拉刷新










下拉刷新
下拉刷新










下拉刷新---下拉刷新










" /> </refreshableview.NestScrollView> </refreshableview.RefreshableView></LinearLayout>
activity_refreshable_list.xml内容:
<?xml version="1.0" encoding="utf-8"?><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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="siso.refreshablev.RefreshableListActivity"></RelativeLayout>
refresh_head.xml内容:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="70dp"android:gravity="center"android:background="#aa000000" > <TextViewandroid:id="@+id/refresh_head_tv"android:layout_width="fill_parent"android:layout_height="70dp"android:gravity="center"android:background="#aabbcc"android:textSize="18sp"android:text="refreshing"/></LinearLayout>
refreshable_list.xml内容:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"> <refreshableview.RefreshableListViewandroid:id="@+id/refreshable_lv"android:layout_width="match_parent"android:layout_height="match_parent"android:cacheColorHint="@android:color/transparent"/></LinearLayout>
运行结果如图:

这里写图片描述

这里写图片描述

这里写图片描述

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。