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() { @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; } /** * 是否允许父控件拦截事件 * @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() { @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/*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() { @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/*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.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>

运行结果如图:

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

时间: 2024-10-27 21:20:51

Android学习教程之下拉刷新实现代码(11)的相关文章

Android学习教程之下拉刷新实现代码(11)_Android

本文实例为大家分享了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; im

Android笔记之:App列表之下拉刷新的使用_Android

Android的ListView是应用最广的一个组件,功能强大,扩展性灵活(不局限于ListView本身一个类),前面的文章有介绍分组,拖拽,3D立体,游标,圆角,而今天我们要介绍的是另外一个扩展ListView:下拉刷新的ListView.    下拉刷新界面最初流行于iphone应用界面,如图: 列表之下拉刷新的使用_Android-">    然后在Android中也逐渐被应用,比如微博,资讯类.    所以,今天要实现的结果应该也是类似的,先贴出最终完成效果,如下图,接下来我们一步

Android自定义控件下拉刷新实例代码_Android

实现效果: 图片素材: --> 首先, 写先下拉刷新时的刷新布局 pull_to_refresh.xml: <resources> <string name="app_name">PullToRefreshTest</string> <string name="pull_to_refresh">下拉可以刷新</string> <string name="release_to_refre

android编程之下拉刷新实现方法分析_Android

本文实例讲述了android编程之下拉刷新实现方法.分享给大家供大家参考,具体如下: 现在android应用里面下拉刷新比较多 ,今天自己研究一下相关的资料 public class MyListView extends ListView implements OnScrollListener { private static final String TAG = "listview"; private final static int RELEASE_To_REFRESH = 0;

Android中ListView下拉刷新的实现代码

Android中ListView下拉刷新 实现效果图: ListView中的下拉刷新是非常常见的,也是经常使用的,看到有很多同学想要,那我就整理一下,供大家参考.那我就不解释,直接上代码了. 这里需要自己重写一下ListView,重写代码如下: package net.loonggg.listview; import java.util.Date; import android.content.Context; import android.util.AttributeSet; import a

android编程之下拉刷新实现方法分析

本文实例讲述了android编程之下拉刷新实现方法.分享给大家供大家参考,具体如下: 现在android应用里面下拉刷新比较多 ,今天自己研究一下相关的资料 public class MyListView extends ListView implements OnScrollListener { private static final String TAG = "listview"; private final static int RELEASE_To_REFRESH = 0;

Android开发ListView中下拉刷新上拉加载及带列的横向滚动实现方法_Android

ListView 控件可使用四种不同视图显示项目.通过此控件,可将项目组成带有或不带有列标头的列,并显示伴随的图标和文本. 可使用 ListView 控件将称作 ListItem 对象的列表条目组织成下列四种不同的视图之一:1.大(标准)图标2.小图标3.列表4.报表 View 属性决定在列表中控件使用何种视图显示项目. 还可用 LabelWrap 属性控制列表中与项目关联的标签是否可换行显示.另外,还可管理列表中项目的排序方法和选定项目的外观. 相信有很人做的项目估计都用的到这个.就是List

Android实现RecyclerView下拉刷新效果

本文为大家分享了Android实现RecyclerView下拉刷新效果的具体代码,供大家参考,具体内容如下 思路 RealPullRefreshView继承了一个LinearLayout 里面放置了一个刷新头布局,将其margin_top设置为负的刷新头的高度的 再添加一个RecyclerView 触摸事件分发机制,当在特定条件下让RealPullRefreshView拦截触摸事件,否则的话,不拦截,让RecyclerView自己去处理触摸事件 在手指下拉时,定义好不同的状态STATE,在不同状

Swift开发之下拉刷新数据的功能实现(使用UIRefreshControl)

想要下拉刷新表格数据,上拉加载新数据,网上有许多第三方的实现类. 而如果仅仅需要实现下拉刷新数据的话,那么使用 UIRefreshControl 就足够了,简单有好用.   1,UIRefreshControl 的使用步骤: (1)创建 UIRefreshControl,并设置文字,颜色等信息. (2)将 UIRefreshControl 添加到tableview视图中. (3)给 UIRefreshControl 添加方法,当值改变的时候调用,用于数据请求刷新. (4)请求数据确认完成之后,调