SwipeRefreshLayout 首次进入界面自动下拉刷新

来源:互联网 发布:debian java 编辑:程序博客网 时间:2024/05/22 04:27

废话不说,直入主题.
为了实现这个功能,本渣百度了一圈,找到了俩种可执行的方案.

第一种

//开启  SwipeRefreshLayout.post(new Runable(){    @Override    public void run() {        SwipeRefreshLayout.setRefreshing(true);    }});//关闭SwipeRefreshLayout.post(new Runable(){    @Override    public void run() {        SwipeRefreshLayout.setRefreshing(false);    }});/* 缺点:不会刷新数据需要手动调用 */

第二种

public class AutoSwipeRefreshView extends SwipeRefreshLayout {    public AutoSwipeRefreshView (Context context) {        super(context);    }    public AutoSwipeRefreshView (Context context, AttributeSet attrs) {        super(context, attrs);    }   /**     * 自动刷新     */    public void autoRefresh() {        try {            Field mCircleView = SwipeRefreshLayout.class.getDeclaredField("mCircleView");            mCircleView.setAccessible(true);            View progress = (View) mCircleView.get(this);            progress.setVisibility(VISIBLE);            Method setRefreshing = SwipeRefreshLayout.class.getDeclaredMethod("setRefreshing", boolean.class, boolean.class);            setRefreshing.setAccessible(true);            setRefreshing.invoke(this, true, true);        } catch (Exception e) {            e.printStackTrace();        }    }}/* 优点:封装后代码优雅,不需要手动请求数据 */
//总结:想要在界面一加载的时候出现更新效果,直接调用setRfreshing(true)是出不来效果的,下为什么setRefreshing(true)没有作用?接下来通过源码看看.    /**     * Notify the widget that refresh state has changed. Do not call this when     * refresh is triggered by a swipe gesture.     *     * @param refreshing Whether or not the view should show refresh progress.     */    public void setRefreshing(boolean refreshing) {        if (refreshing && mRefreshing != refreshing) {            // scale and show            mRefreshing = refreshing;            int endTarget = 0;            if (!mUsingCustomStart) {                endTarget = (int) (mSpinnerFinalOffset + mOriginalOffsetTop);            } else {                endTarget = (int) mSpinnerFinalOffset;            }            setTargetOffsetTopAndBottom(endTarget - mCurrentTargetOffsetTop,                    true /* requires update */);            mNotify = false;            startScaleUpAnimation(mRefreshListener);        } else {            setRefreshing(refreshing, false /* notify */);        }    }//在onCreate里或onCreateView里调用setRefreshing(),这个时候关键变量mOriginalOffsetTop并没有获取正确的值,下拉效果动画过程中没有显示到正确的坐标,我们在搜索下这个变量看怎么得到的.  @Override    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        if (mTarget == null) {            ensureTarget();        }        if (mTarget == null) {            return;        }        mTarget.measure(MeasureSpec.makeMeasureSpec(                getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),                MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(                getMeasuredHeight() - getPaddingTop() - getPaddingBottom(), MeasureSpec.EXACTLY));        mCircleView.measure(MeasureSpec.makeMeasureSpec(mCircleWidth, MeasureSpec.EXACTLY),                MeasureSpec.makeMeasureSpec(mCircleHeight, MeasureSpec.EXACTLY));        if (!mUsingCustomStart && !mOriginalOffsetCalculated) {            mOriginalOffsetCalculated = true;            mCurrentTargetOffsetTop = mOriginalOffsetTop = -mCircleView.getMeasuredHeight();        }        mCircleViewIndex = -1;        // Get the index of the circleview.        for (int index = 0; index < getChildCount(); index++) {            if (getChildAt(index) == mCircleView) {                mCircleViewIndex = index;                break;            }        }    }//如代码所见,是在onMeasure里获取的,根据CircleView的高度来赋值的。所以要解决的方法是让mOriginalOffsetTop能在setRefreshing前正确赋值。//在onCreate里面调用SwipeRefreshLayout.setRefreshing(ture,true)即可,但是,这个Api是私有的。所以只能用反射或者手动调//最后一件事,如果使用了第二种方式,注意代码混淆 keep 掉AutoSwipeRefreshView.//最后一件事,如果使用了第二种方式,注意代码混淆 keep 掉AutoSwipeRefreshView.//最后一件事,如果使用了第二种方式,注意代码混淆 keep 掉AutoSwipeRefreshView.//重要的事情要说三遍,因为不keep正式版本是不会自动刷新,debug版本会,很多人会以为是机型问题,别问我是怎么知道的 - -.
1 0
原创粉丝点击