package com.android.pc.ioc.view; import java.io.IOException; import java.io.InputStream; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.Typeface; import android.util.AttributeSet; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.animation.LinearInterpolator; import android.view.animation.RotateAnimation; import android.widget.AbsoluteLayout; import android.widget.AdapterView; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.TextView; import com.android.pc.ioc.event.EventBus; import com.android.pc.ioc.inject.InjectView; import com.android.pc.util.Handler_Bitmap; import com.android.pc.util.Handler_System; public class PullToRefreshView extends LinearLayout { // private static final String TAG = "PullToRefreshView"; // refresh states private static final int PULL_TO_REFRESH = 2; private static final int RELEASE_TO_REFRESH = 3; private static final int REFRESHING = 4; // pull state private static final int PULL_NONE_STATE = -1; private static final int PULL_UP_STATE = 0; private static final int PULL_DOWN_STATE = 1; /** * last y */ private int mLastMotionY; /** * lock */ // private boolean mLock; /** * header view */ private RelativeLayout mHeaderView; /** * footer view */ private RelativeLayout mFooterView; /** * list or grid */ private AdapterView<?> mAdapterView; /** * scrollview */ private ScrollView mScrollView; /** * header view height */ private int mHeaderViewHeight; /** * footer view height */ private int mFooterViewHeight; /** * header view image */ private ImageView mHeaderImageView; /** * footer view image */ private ImageView mFooterImageView; /** * header tip text */ private TextView mHeaderTextView; /** * footer tip text */ private TextView mFooterTextView; /** * header refresh time */ private TextView mHeaderUpdateTextView; /** * header progress bar */ private ProgressBar mHeaderProgressBar; /** * footer progress bar */ private ProgressBar mFooterProgressBar; /** * header view current state */ private int mHeaderState; /** * footer view current state */ private int mFooterState; /** * pull state,pull up or pull down;PULL_UP_STATE or PULL_DOWN_STATE */ private int mPullState = PULL_NONE_STATE; /** * 变为向下的箭头,改变箭头方向 */ private RotateAnimation mFlipAnimation; /** * 变为逆向的箭头,旋转 */ private RotateAnimation mReverseFlipAnimation; /** * footer refresh listener */ private OnFooterRefreshListener mOnFooterRefreshListener; /** * footer refresh listener */ private OnHeaderRefreshListener mOnHeaderRefreshListener; private boolean isGet = false; private boolean isHeader = true; private boolean isFooter = true; private Bitmap downBitmap; private Bitmap upBitmap; private PullToRefreshManager manager; private EventBus eventBus = EventBus.getDefault(); /** * last update time */ // private String mLastUpdateTime; public PullToRefreshView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public PullToRefreshView(Context context) { super(context); init(); } /** * init * * @param context */ private void init() { manager = PullToRefreshManager.getInstance(); // 需要设置成vertical setOrientation(LinearLayout.VERTICAL); // Load all of the animations we need in code rather than through XML mFlipAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); mFlipAnimation.setInterpolator(new LinearInterpolator()); mFlipAnimation.setDuration(250); mFlipAnimation.setFillAfter(true); mReverseFlipAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); mReverseFlipAnimation.setInterpolator(new LinearInterpolator()); mReverseFlipAnimation.setDuration(250); mReverseFlipAnimation.setFillAfter(true); // header view 在此添加,保证是第一个添加到linearlayout的最上端 addHeaderView(); } @Override public void addView(View child) { super.addView(child); } private void addHeaderView() { try { InputStream down = getResources().getAssets().open("down.png"); InputStream up = getResources().getAssets().open("up.png"); downBitmap = BitmapFactory.decodeStream(down); upBitmap = BitmapFactory.decodeStream(up); } catch (IOException e) { } float rote = Handler_System.getPadRoate(); downBitmap = Handler_Bitmap.scaleImg(downBitmap, (int) (downBitmap.getWidth() * rote), (int) (downBitmap.getHeight() * rote)); upBitmap = Handler_Bitmap.scaleImg(upBitmap, (int) (upBitmap.getWidth() * rote), (int) (upBitmap.getHeight() * rote)); mHeaderView = new RelativeLayout(getContext()); LayoutParams layoutParams = new LayoutParams(LayoutParams.FILL_PARENT, (int) (100 * rote)); layoutParams.bottomMargin = (int) (15 * rote); layoutParams.topMargin = (int) (15 * rote); layoutParams.gravity = Gravity.CENTER; mHeaderView.setLayoutParams(layoutParams); mHeaderProgressBar = new ProgressBar(getContext()); mHeaderProgressBar.setIndeterminate(false); mHeaderProgressBar.setVisibility(View.GONE); RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams((int) (40 * rote), (int) (40 * rote)); rl.leftMargin = (int) (30 * rote); rl.rightMargin = (int) (20 * rote); rl.addRule(RelativeLayout.CENTER_VERTICAL); mHeaderProgressBar.setLayoutParams(rl); mHeaderView.addView(mHeaderProgressBar); mHeaderImageView = new ImageView(getContext()); rl = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); rl.leftMargin = (int) (30 * rote); rl.rightMargin = (int) (20 * rote); rl.addRule(RelativeLayout.CENTER_VERTICAL); mHeaderImageView.setLayoutParams(rl); mHeaderImageView.setImageBitmap(downBitmap); mHeaderView.addView(mHeaderImageView); LinearLayout layout = new LinearLayout(getContext()); rl = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); rl.addRule(RelativeLayout.CENTER_VERTICAL); layout.setOrientation(VERTICAL); layout.setGravity(Gravity.CENTER); layout.setLayoutParams(rl); mHeaderTextView = new TextView(getContext()); mHeaderTextView.setGravity(Gravity.CENTER); mHeaderTextView.setText(manager.getPull_label()); mHeaderTextView.setTextColor(Color.BLACK); mHeaderTextView.setTypeface(Typeface.DEFAULT_BOLD, Typeface.ITALIC); rl = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); mHeaderTextView.setLayoutParams(rl); layout.addView(mHeaderTextView); mHeaderUpdateTextView = new TextView(getContext()); mHeaderUpdateTextView.setGravity(Gravity.CENTER); mHeaderUpdateTextView.setText(manager.getUpdateTime()); mHeaderUpdateTextView.setTextColor(Color.BLACK); mHeaderUpdateTextView.setVisibility(View.GONE); mHeaderUpdateTextView.setTextSize(10f); rl = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, 40); mHeaderUpdateTextView.setLayoutParams(rl); layout.addView(mHeaderUpdateTextView); mHeaderView.addView(layout); // header layout measureView(mHeaderView); mHeaderViewHeight = mHeaderView.getMeasuredHeight(); LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, mHeaderViewHeight); // 设置topMargin的值为负的header View高度,即将其隐藏在最上方 params.topMargin = -(mHeaderViewHeight); // mHeaderView.setLayoutParams(params1); addView(mHeaderView, params); } private void addFooterView() { mFooterView = new RelativeLayout(getContext()); float rote = Handler_System.getPadRoate(); LayoutParams layoutParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); layoutParams.bottomMargin = (int) (15 * rote); layoutParams.topMargin = (int) (10 * rote); layoutParams.gravity = Gravity.CENTER; mFooterView.setLayoutParams(layoutParams); mFooterProgressBar = new ProgressBar(getContext()); mFooterProgressBar.setIndeterminate(false); mFooterProgressBar.setVisibility(View.GONE); RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); rl.leftMargin = (int) (30 * rote); rl.topMargin = (int) (10 * rote); rl.rightMargin = (int) (20 * rote); mFooterProgressBar.setLayoutParams(rl); mFooterView.addView(mFooterProgressBar); mFooterImageView = new ImageView(getContext()); rl = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); rl.leftMargin = (int) (30 * rote); rl.rightMargin = (int) (20 * rote); mFooterImageView.setLayoutParams(rl); mFooterImageView.setImageBitmap(upBitmap); mFooterView.addView(mFooterImageView); LinearLayout layout = new LinearLayout(getContext()); rl = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); layout.setOrientation(VERTICAL); rl.addRule(RelativeLayout.CENTER_IN_PARENT); layout.setGravity(Gravity.CENTER); layout.setLayoutParams(rl); mFooterTextView = new TextView(getContext()); mFooterTextView.setGravity(Gravity.CENTER); mFooterTextView.setText(manager.getFooter_pull_label()); mFooterTextView.setTextColor(Color.BLACK); mFooterTextView.setTypeface(Typeface.DEFAULT_BOLD, Typeface.ITALIC); rl = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); mFooterTextView.setLayoutParams(rl); layout.addView(mFooterTextView); mFooterView.addView(layout); // footer layout measureView(mFooterView); mFooterViewHeight = mFooterView.getMeasuredHeight(); LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, mFooterViewHeight); // int top = getHeight(); // params.topMargin // =getHeight();//在这里getHeight()==0,但在onInterceptTouchEvent()方法里getHeight()已经有值了,不再是0; // getHeight()什么时候会赋值,稍候再研究一下 // 由于是线性布局可以直接添加,只要AdapterView的高度是MATCH_PARENT,那么footer view就会被添加到最后,并隐藏 addView(mFooterView, params); } public int getmHeaderState() { return mHeaderState; } public void setmHeaderState(int mHeaderState) { this.mHeaderState = mHeaderState; } public int getmFooterState() { return mFooterState; } public void setmFooterState(int mFooterState) { this.mFooterState = mFooterState; } public void onFooter() { // footer view 在此添加保证添加到linearlayout中的最后 addFooterView(); initContentAdapterView(); View view = getChildAt(0); if (view == null) { return; } ViewTreeObserver vto = this.getViewTreeObserver(); vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { if (isGet) { return true; } isGet = true; if (mAdapterView != null) { int heigth = 0; if (LinearLayout.LayoutParams.class.isAssignableFrom(mAdapterView.getLayoutParams().getClass())) { // 重置listview的高度 LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) mAdapterView.getLayoutParams(); layoutParams.height = mAdapterView.getHeight(); if (layoutParams.height <= 2) { layoutParams.height = PullToRefreshView.this.getHeight(); } mAdapterView.setLayoutParams(layoutParams); heigth = layoutParams.height; } if (LinearLayout.LayoutParams.class.isAssignableFrom(PullToRefreshView.this.getLayoutParams().getClass())) { // 重置下拉组件的高度 LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) PullToRefreshView.this.getLayoutParams(); if (heigth!=0) { params.height = heigth; } PullToRefreshView.this.setLayoutParams(params); } if (AbsoluteLayout.LayoutParams.class.isAssignableFrom(mAdapterView.getLayoutParams().getClass())) { // 重置listview的高度 AbsoluteLayout.LayoutParams layoutParams = (AbsoluteLayout.LayoutParams) mAdapterView.getLayoutParams(); layoutParams.height = mAdapterView.getHeight(); if (layoutParams.height <= 2) { layoutParams.height = PullToRefreshView.this.getHeight(); } mAdapterView.setLayoutParams(layoutParams); heigth = layoutParams.height; } if (AbsoluteLayout.LayoutParams.class.isAssignableFrom(PullToRefreshView.this.getLayoutParams().getClass())) { // 重置下拉组件的高度 AbsoluteLayout.LayoutParams params = (AbsoluteLayout.LayoutParams) PullToRefreshView.this.getLayoutParams(); if (heigth!=0) { params.height = heigth; } PullToRefreshView.this.setLayoutParams(params); } if (RelativeLayout.LayoutParams.class.isAssignableFrom(mAdapterView.getLayoutParams().getClass())) { // 重置listview的高度 RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mAdapterView.getLayoutParams(); layoutParams.height = mAdapterView.getHeight(); if (layoutParams.height <= 2) { layoutParams.height = PullToRefreshView.this.getHeight(); } mAdapterView.setLayoutParams(layoutParams); heigth = layoutParams.height; } if (RelativeLayout.LayoutParams.class.isAssignableFrom(PullToRefreshView.this.getLayoutParams().getClass())) { // 重置下拉组件的高度 RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) PullToRefreshView.this.getLayoutParams(); if (heigth!=0) { params.height = heigth; } PullToRefreshView.this.setLayoutParams(params); } if (FrameLayout.LayoutParams.class.isAssignableFrom(mAdapterView.getLayoutParams().getClass())) { // 重置listview的高度 FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mAdapterView.getLayoutParams(); layoutParams.height = mAdapterView.getHeight(); if (layoutParams.height <= 2) { layoutParams.height = PullToRefreshView.this.getHeight(); } mAdapterView.setLayoutParams(layoutParams); heigth = layoutParams.height; } if (FrameLayout.LayoutParams.class.isAssignableFrom(PullToRefreshView.this.getLayoutParams().getClass())) { // 重置下拉组件的高度 FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) PullToRefreshView.this.getLayoutParams(); if (heigth!=0) { params.height = heigth; } PullToRefreshView.this.setLayoutParams(params); } } return true; } }); } /** * init AdapterView like ListView,GridView and so on;or init ScrollView * */ private void initContentAdapterView() { int count = getChildCount(); if (count < 3) { throw new IllegalArgumentException("This layout must contain 3 child views,and AdapterView or ScrollView must in the second position!"); } View view = null; for (int i = 0; i < count - 1; ++i) { view = getChildAt(i); if (view instanceof AdapterView<?>) { mAdapterView = (AdapterView<?>) view; } if (view instanceof ScrollView) { // finish later mScrollView = (ScrollView) view; } } if (mAdapterView == null && mScrollView == null) { throw new IllegalArgumentException("must contain a AdapterView or ScrollView in this layout!"); } } @Override protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) { super.measureChild(child, parentWidthMeasureSpec, parentHeightMeasureSpec); } private void measureView(View child) { ViewGroup.LayoutParams p = child.getLayoutParams(); if (p == null) { p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); } int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width); int lpHeight = p.height; int childHeightSpec; if (lpHeight > 0) { childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); } else { childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } child.measure(childWidthSpec, childHeightSpec); } @Override public boolean onInterceptTouchEvent(MotionEvent e) { int y = (int) e.getRawY(); switch (e.getAction()) { case MotionEvent.ACTION_DOWN: // 首先拦截down事件,记录y坐标 mLastMotionY = y; break; case MotionEvent.ACTION_MOVE: // deltaY > 0 是向下运动,< 0是向上运动 int deltaY = y - mLastMotionY; if (isRefreshViewScroll(deltaY)) { return true; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: break; } return false; } /* * 如果在onInterceptTouchEvent()方法中没有拦截(即onInterceptTouchEvent()方法中 return false)则由PullToRefreshView 的子View来处理;否则由下面的方法来处理(即由PullToRefreshView自己来处理) */ @Override public boolean onTouchEvent(MotionEvent event) { // if (mLock) { // return true; // } int y = (int) event.getRawY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // onInterceptTouchEvent已经记录 // mLastMotionY = y; break; case MotionEvent.ACTION_MOVE: int deltaY = y - mLastMotionY; if (mPullState == PULL_DOWN_STATE) {// 执行下拉 headerPrepareToRefresh(deltaY); // setHeaderPadding(-mHeaderViewHeight); } else if (mPullState == PULL_UP_STATE) {// 执行上拉 footerPrepareToRefresh(deltaY); } mLastMotionY = y; break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: int topMargin = getHeaderTopMargin(); if (mPullState == PULL_DOWN_STATE) { if (topMargin >= 0) { // 开始刷新 headerRefreshing(); } else { // 还没有执行刷新,重新隐藏 setHeaderTopMargin(-mHeaderViewHeight); } } else if (mPullState == PULL_UP_STATE) { if (Math.abs(topMargin) >= mHeaderViewHeight + mFooterViewHeight) { // 开始执行footer 刷新 footerRefreshing(); } else { // 还没有执行刷新,重新隐藏 setHeaderTopMargin(-mHeaderViewHeight); } } break; } return super.onTouchEvent(event); } /** * 是否应该到了父View,即PullToRefreshView滑动 * * @param deltaY * , deltaY > 0 是向下运动,< 0是向上运动 * @return */ private boolean isRefreshViewScroll(int deltaY) { if (mHeaderState == REFRESHING || mFooterState == REFRESHING) { return false; } // 对于ListView和GridView if (mAdapterView != null) { // 子view(ListView or GridView)滑动到最顶端 if (deltaY > 0) { if (!isHeader) { mPullState = PULL_NONE_STATE; return false; } View child = mAdapterView.getChildAt(0); if (child == null) { // 如果mAdapterView中没有数据,不拦截 return false; } if (mAdapterView.getFirstVisiblePosition() == 0 && child.getTop() == 0) { mPullState = PULL_DOWN_STATE; return true; } int top = child.getTop(); int padding = mAdapterView.getPaddingTop(); if (mAdapterView.getFirstVisiblePosition() == 0 && Math.abs(top - padding) <= 8) {// 这里之前用3可以判断,但现在不行,还没找到原因 mPullState = PULL_DOWN_STATE; return true; } } else if (deltaY < 0) { if (!isFooter) { mPullState = PULL_NONE_STATE; return false; } View lastChild = mAdapterView.getChildAt(mAdapterView.getChildCount() - 1); if (lastChild == null) { // 如果mAdapterView中没有数据,不拦截 return false; } // 最后一个子view的Bottom小于父View的高度说明mAdapterView的数据没有填满父view, // 等于父View的高度说明mAdapterView已经滑动到最后 if (lastChild.getBottom() <= getHeight() && mAdapterView.getLastVisiblePosition() == mAdapterView.getCount() - 1) { mPullState = PULL_UP_STATE; return true; } } } // 对于ScrollView if (mScrollView != null) { // 子scroll view滑动到最顶端 View child = mScrollView.getChildAt(0); if (deltaY > 0 && mScrollView.getScrollY() == 0) { if (!isHeader) { mPullState = PULL_NONE_STATE; return false; } mPullState = PULL_DOWN_STATE; return true; } else if (deltaY < 0 && child.getMeasuredHeight() <= getHeight() + mScrollView.getScrollY()) { if (!isFooter) { mPullState = PULL_NONE_STATE; return false; } mPullState = PULL_UP_STATE; return true; } } return false; } /** * header 准备刷新,手指移动过程,还没有释放 * * @param deltaY * ,手指滑动的距离 */ private void headerPrepareToRefresh(int deltaY) { int newTopMargin = changingHeaderViewTopMargin(deltaY); // 当header view的topMargin>=0时,说明已经完全显示出来了,修改header view 的提示状态 if (newTopMargin >= 0 && mHeaderState != RELEASE_TO_REFRESH) { mHeaderTextView.setText(manager.getRelease_label()); mHeaderUpdateTextView.setVisibility(View.VISIBLE); mHeaderImageView.clearAnimation(); mHeaderImageView.startAnimation(mFlipAnimation); mHeaderState = RELEASE_TO_REFRESH; } else if (newTopMargin < 0 && newTopMargin > -mHeaderViewHeight) {// 拖动时没有释放 mHeaderImageView.clearAnimation(); mHeaderImageView.startAnimation(mFlipAnimation); // mHeaderImageView. mHeaderTextView.setText(manager.getRelease_label()); mHeaderState = PULL_TO_REFRESH; } } /** * footer 准备刷新,手指移动过程,还没有释放 移动footer view高度同样和移动header view 高度是一样,都是通过修改header view的topmargin的值来达到 * * @param deltaY * ,手指滑动的距离 */ private void footerPrepareToRefresh(int deltaY) { int newTopMargin = changingHeaderViewTopMargin(deltaY); // 如果header view topMargin 的绝对值大于或等于header + footer 的高度 // 说明footer view 完全显示出来了,修改footer view 的提示状态 if (Math.abs(newTopMargin) >= (mHeaderViewHeight + mFooterViewHeight) && mFooterState != RELEASE_TO_REFRESH) { mFooterTextView.setText(manager.getFooter_refreshing_label()); mFooterImageView.clearAnimation(); mFooterImageView.startAnimation(mFlipAnimation); mFooterState = RELEASE_TO_REFRESH; } else if (Math.abs(newTopMargin) < (mHeaderViewHeight + mFooterViewHeight)) { mFooterImageView.clearAnimation(); mFooterImageView.startAnimation(mFlipAnimation); mFooterTextView.setText(manager.getFooter_pull_label()); mFooterState = PULL_TO_REFRESH; } } /** * 修改Header view top margin的值 * * @param deltaY */ private int changingHeaderViewTopMargin(int deltaY) { LayoutParams params = (LayoutParams) mHeaderView.getLayoutParams(); float newTopMargin = params.topMargin + deltaY * 0.5f; // 这里对上拉做一下限制,因为当前上拉后然后不释放手指直接下拉,会把下拉刷新给触发了,感谢网友yufengzungzhe的指出 // 表示如果是在上拉后一段距离,然后直接下拉 if (deltaY > 0 && mPullState == PULL_UP_STATE && Math.abs(params.topMargin) <= mHeaderViewHeight) { return params.topMargin; } // 同样地,对下拉做一下限制,避免出现跟上拉操作时一样的bug if (deltaY < 0 && mPullState == PULL_DOWN_STATE && Math.abs(params.topMargin) >= mHeaderViewHeight) { return params.topMargin; } params.topMargin = (int) newTopMargin; mHeaderView.setLayoutParams(params); // invalidate(); return params.topMargin; } /** * header refreshing * */ private void headerRefreshing() { mHeaderState = REFRESHING; setHeaderTopMargin(0); mHeaderImageView.setVisibility(View.GONE); mHeaderImageView.clearAnimation(); mHeaderImageView.setImageDrawable(null); mHeaderProgressBar.setVisibility(View.VISIBLE); mHeaderTextView.setText(manager.getRefreshing_label()); if (mOnHeaderRefreshListener != null) { mOnHeaderRefreshListener.onHeaderRefresh(this); } } /** * footer refreshing * */ private void footerRefreshing() { mFooterState = REFRESHING; int top = mHeaderViewHeight + mFooterViewHeight; setHeaderTopMargin(-top); mFooterImageView.setVisibility(View.GONE); mFooterImageView.clearAnimation(); mFooterImageView.setImageDrawable(null); mFooterProgressBar.setVisibility(View.VISIBLE); mFooterTextView.setText(manager.getRefreshing_label()); if (mOnFooterRefreshListener != null) { mOnFooterRefreshListener.onFooterRefresh(this); } } /** * 设置header view 的topMargin的值 * * @param topMargin * ,为0时,说明header view 刚好完全显示出来; 为-mHeaderViewHeight时,说明完全隐藏了 */ private void setHeaderTopMargin(int topMargin) { LayoutParams params = (LayoutParams) mHeaderView.getLayoutParams(); params.topMargin = topMargin; mHeaderView.setLayoutParams(params); // invalidate(); } /** * header view 完成更新后恢复初始状态 * */ public void onHeaderRefreshComplete() { setHeaderTopMargin(-mHeaderViewHeight); mHeaderImageView.setVisibility(View.VISIBLE); mHeaderImageView.setImageBitmap(downBitmap); mHeaderTextView.setText(manager.getRelease_label()); mHeaderProgressBar.setVisibility(View.GONE); // mHeaderUpdateTextView.setText(""); mHeaderState = PULL_TO_REFRESH; } /** * Resets the list to a normal state after a refresh. * * @param lastUpdated * Last updated at. */ public void onHeaderRefreshComplete(CharSequence lastUpdated) { setLastUpdated(lastUpdated); onHeaderRefreshComplete(); } /** * footer view 完成更新后恢复初始状态 */ public void onFooterRefreshComplete() { setHeaderTopMargin(-mHeaderViewHeight); mFooterImageView.setVisibility(View.VISIBLE); mFooterImageView.setImageBitmap(upBitmap); mFooterTextView.setText(manager.getFooter_pull_label()); mFooterProgressBar.setVisibility(View.GONE); // mHeaderUpdateTextView.setText(""); mFooterState = PULL_TO_REFRESH; } /** * Set a text to represent when the list was last updated. * * @param lastUpdated * Last updated at. */ public void setLastUpdated(CharSequence lastUpdated) { if (lastUpdated != null) { mHeaderUpdateTextView.setVisibility(View.VISIBLE); mHeaderUpdateTextView.setText(lastUpdated); } else { mHeaderUpdateTextView.setVisibility(View.GONE); } } /** * 获取当前header view 的topMargin * */ private int getHeaderTopMargin() { LayoutParams params = (LayoutParams) mHeaderView.getLayoutParams(); return params.topMargin; } public void setOnHeaderRefreshListener(OnHeaderRefreshListener headerRefreshListener) { mOnHeaderRefreshListener = headerRefreshListener; } public void setOnFooterRefreshListener(OnFooterRefreshListener footerRefreshListener) { mOnFooterRefreshListener = footerRefreshListener; } /** * Interface definition for a callback to be invoked when list/grid footer view should be refreshed. */ public interface OnFooterRefreshListener { public void onFooterRefresh(PullToRefreshView view); } /** * Interface definition for a callback to be invoked when list/grid header view should be refreshed. */ public interface OnHeaderRefreshListener { public void onHeaderRefresh(PullToRefreshView view); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); eventBus.unregister(this); } @Override protected void onWindowVisibilityChanged(int visibility) { super.onWindowVisibilityChanged(visibility); switch (visibility) { case View.GONE: eventBus.unregister(this); break; case View.INVISIBLE: eventBus.unregister(this); break; case View.VISIBLE: eventBus.register(this); break; } } public AdapterView<?> getAdapterView() { return mAdapterView; } public boolean isHeader() { return isHeader; } public void setHeader(boolean isHeader) { this.isHeader = isHeader; } public boolean isFooter() { return isFooter; } public void setFooter(boolean isFooter) { this.isFooter = isFooter; } public void onEventMainThread(RefershEntity entity) { switch (entity.getType()) { case InjectView.PULL_CLOSE: setFooter(false); break; case InjectView.DOWN_CLOSE: setHeader(false); break; case InjectView.PULL_OPEN: setFooter(true); break; case InjectView.DOWN_OPEN: setHeader(true); break; case InjectView.DOWN: onHeaderRefreshComplete(); break; case InjectView.PULL: onFooterRefreshComplete(); if (manager.getLimit() == 0) { return; } if (mAdapterView != null) { int count = mAdapterView.getAdapter().getCount(); if (count % manager.getLimit() != 0) { setFooter(false); } else { setFooter(true); } } break; } } }