本文实例为大家分享了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;
@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() {
@Override
public View onInitRefreshHeaderView() {
return LayoutInflater.from(MainActivity.this).inflate(R.layout.refresh_head, null);
}
@Override
public boolean onInitRefreshHeight(int originRefreshHeight) {
refreshableView.setRefreshNormalHeight(refreshableView.getOriginRefreshHeight() / 3);
refreshableView.setRefreshingHeight(refreshableView.getOriginRefreshHeight());
refreshableView.setRefreshArrivedStateHeight(refreshableView.getOriginRefreshHeight());
return false;
}
@Override
public 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() {
@Override
public 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() {
@Override
public View onInitRefreshHeaderView() {
return LayoutInflater.from(RefreshableListActivity.this).inflate(R.layout.refresh_head, null);
}
@Override
public boolean onInitRefreshHeight(int originRefreshHeight) {
lv.setRefreshNormalHeight(lv.getOriginRefreshHeight() / 3);
lv.setRefreshingHeight(lv.getOriginRefreshHeight());
lv.setRefreshArrivedStateHeight(lv.getOriginRefreshHeight());
return false;
}
@Override
public 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() {
@Override
public 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;
}
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;
private View refreshHeaderView;
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);
}
}
private void setRefreshState(int expectRefreshState) {
if (expectRefreshState != refreshState) {
refreshState = expectRefreshState;
if (null != refreshableHelper) {
refreshableHelper.onRefreshStateChanged(refreshHeaderView, refreshState);
}
}
}
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);
}
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() {
@Override
public 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);
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;
private View refreshHeaderView;
private int originRefreshHeight;
private int refreshArrivedStateHeight;
private int refreshingHeight;
private int refreshNormalHeight;
private boolean disallowIntercept = true;
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;
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);
}
}
private void setRefreshState(int expectRefreshState) {
if (expectRefreshState != refreshState) {
refreshState = expectRefreshState;
if (null != refreshableHelper) {
refreshableHelper.onRefreshStateChanged(refreshHeaderView, refreshState);
}
}
}
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);
}
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() {
@Override
public 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);
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 onInitRefreshHeaderView();
boolean onInitRefreshHeight(int originRefreshHeight);
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.RefreshableView
android: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="下拉刷新\n\n\n\n\n\n\n\n\n\n\n下拉刷新\n下拉刷新\n\n\n\n\n\n\n\n\n\n\n下拉刷新\n下拉刷新\n\n\n\n\n\n\n\n\n\n\n下拉刷新\n下拉刷新\n\n\n\n\n\n\n\n\n\n\n下拉刷新---下拉刷新\n\n\n\n\n\n\n\n\n\n\n"
/>
</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"
>
<TextView
android: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.RefreshableListView
android:id="@+id/refreshable_lv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="@android:color/transparent"
/>
</LinearLayout>
运行结果如图:
您可能感兴趣的文章:Android中使用RecyclerView实现下拉刷新和上拉加载Android下拉刷新上拉加载控件(适用于所有View)Android实现上拉加载更多以及下拉刷新功能(ListView)Android RecyclerView实现下拉刷新和上拉加载Android下拉刷新上拉加载更多左滑动删除Android ListView实现上拉加载更多和下拉刷新功能Android RecyclerView 上拉加载更多及下拉刷新功能的实现方法Android程序开发之使用PullToRefresh实现下拉刷新和上拉加载Android自定义下拉刷新上拉加载Android使用PullToRefresh实现上拉加载和下拉刷新效果的代码