是否可以使用setRefreshing()方法显示带动画的滑动刷新指示器

时间:2015-10-01 04:32:05

标签: android parallax swiperefreshlayout

我必须为Parallax实施Swipe to refresh动画和ListView。在将列表视图拖动到down时,listview标题图像应显示视差动画。当视差动画超出限制列表视图时,应显示滑动刷新指示器。我知道可以使用setRefreshing(true)。但是使用此方法不会显示刷新指示器的动画,就像它从顶部滑动一样。

那么有没有办法在运行时显示带有默认动画的刷新指示器?

<RelativeLayout
    android:id="@+id/layoutListing"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipeRefreshLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <com.xxx.views.ParallaxListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fadingEdge="none"
            android:overScrollMode="never" >
        </com.xxx.views.ParallaxListView>
    </android.support.v4.widget.SwipeRefreshLayout>

</RelativeLayout>

public class ParallaxListView extends ListView implements OnScrollListener {

    public final static double ZOOM_X2 = 2;
    private Context context = null;
    private ImageView mImageView;
    private int mDrawableMaxHeight = -1;
    private int mImageViewHeight = -1;
    private int mDefaultImageViewHeight = 0;
    private double mZoomRatio;

    private int firstVisibleItem  =0;

    private int lastTopValueAssigned;

    private Handler uiHandler =  new Handler();

    private boolean isRefreshListView = false;

    private interface OnOverScrollByListener {
        public boolean overScrollBy(int deltaX, int deltaY, int scrollX,
                                    int scrollY, int scrollRangeX, int scrollRangeY,
                                    int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent);
    }

    private interface OnTouchEventListener {
        public void onTouchEvent(MotionEvent ev);
    }

    /**
     * 
     * Constructor for ParallaxListView.
     * @param context
     * @param attrs
     * @param defStyle
     */
    public ParallaxListView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        init(context);

    }

    /**
     * 
     * Constructor for ParallaxListView.
     * @param context
     * @param attrs
     */
    public ParallaxListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public ParallaxListView(Context context) {
        super(context);
        init(context);
    }

    public void init(Context context) {
        this.context = context;
        //setOnScrollListener(this);
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                mDefaultImageViewHeight =  context.getResources().getDrawable(R.drawable.dflt,context.getTheme()).getIntrinsicHeight();
            } else {
                mDefaultImageViewHeight = context.getResources().getDrawable(R.drawable.dflt).getIntrinsicHeight();
            }
        } catch (Exception e) {
        }
    }

  /*
   * (non-Javadoc)
   * @see android.widget.AbsListView#onLayout(boolean, int, int, int, int)
   */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        new Handler().post(new Runnable() {

            @Override
            public void run() {
                initViewsBounds(mZoomRatio);
            }
        });

    }

    /*
     * (non-Javadoc)
     * @see android.widget.AbsListView.OnScrollListener#onScrollStateChanged(android.widget.AbsListView, int)
     */
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

    /*
     * (non-Javadoc)
     * @see android.view.View#overScrollBy(int, int, int, int, int, int, int, int, boolean)
     */
    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,
                                   int scrollY, int scrollRangeX, int scrollRangeY,
                                   int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        boolean isCollapseAnimation = false;
        isCollapseAnimation = scrollByListener.overScrollBy(deltaX, deltaY,
                scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX,
                maxOverScrollY, isTouchEvent)
                || isCollapseAnimation;
        return isCollapseAnimation ? true : super.overScrollBy(deltaX, deltaY,
                scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX,
                maxOverScrollY, isTouchEvent);
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
                         int visibleItemCount, int totalItemCount) {
        this.firstVisibleItem = firstVisibleItem;
        parallaxImage(mImageView);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if(mImageView != null){ 
            View firstView = (View) mImageView.getParent();
            // firstView.getTop < getPaddingTop means mImageView will be covered by top padding,
            // so we can layout it to make it shorter
            if (firstView.getTop() < getPaddingTop() && mImageView.getHeight() > mImageViewHeight) {
                mImageView.getLayoutParams().height = Math.max(mImageView.getHeight() - (getPaddingTop() - firstView.getTop()), mImageViewHeight);
                // to set the firstView.mTop to 0,
                // maybe use View.setTop() is more easy, but it just support from Android 3.0 (API 11)
                firstView.layout(firstView.getLeft(), 0, firstView.getRight(), firstView.getHeight());
                mImageView.requestLayout();
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        touchListener.onTouchEvent(ev);
        return super.onTouchEvent(ev);
    }

    public void setParallaxImageView(ImageView iv) {
        try {
            mImageView = iv;
            mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        } catch (Exception e) {
        }
    }

    private void initViewsBounds(double zoomRatio) {
        if (mImageViewHeight == -1) {
            mImageViewHeight = mImageView.getMeasuredHeight();
            if (mImageViewHeight <= 0) {
                mImageViewHeight = mDefaultImageViewHeight;
            }
            double ratio = ((double) mImageView.getDrawable().getIntrinsicWidth()) / ((double) mImageView.getWidth());

            mDrawableMaxHeight = (int) ((mImageView.getDrawable().getIntrinsicHeight() / ratio) * (zoomRatio > 1 ?
                    zoomRatio : 1));
        }
    }

    public void setZoomRatio(double zoomRatio) {
        mZoomRatio = zoomRatio;
    }


    private OnOverScrollByListener scrollByListener = new OnOverScrollByListener() {
        @Override
        public boolean overScrollBy(int deltaX, int deltaY, int scrollX,
                                    int scrollY, int scrollRangeX, int scrollRangeY,
                                    int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {

            if (mImageView.getHeight() <= mDrawableMaxHeight && isTouchEvent) {
                if (deltaY < 0) {
                    if (mImageView.getHeight() - deltaY / 2 >= mImageViewHeight) {
                        if(mImageView.getHeight() > (mDrawableMaxHeight * 0.70)){
                            //here i want to show refresh indicator 
                        }
                        mImageView.getLayoutParams().height = mImageView.getHeight() - deltaY / 2 < mDrawableMaxHeight ?
                                mImageView.getHeight() - deltaY / 2 : mDrawableMaxHeight;
                        mImageView.requestLayout();
                    }
                } else {
                    if (mImageView.getHeight() > mImageViewHeight) {
                        mImageView.getLayoutParams().height = mImageView.getHeight() - deltaY > mImageViewHeight ?
                                mImageView.getHeight() - deltaY : mImageViewHeight;
                        mImageView.requestLayout();
                        return true;
                    }
                }
            }
            return false;
        }
    };


    private void fireSwipeToRefresh(){
        if(!isRefreshListView){
            uiHandler.post(new Runnable() {

                    @Override
                    public void run() {
                        isRefreshListView = true;
                        Intent intent = new Intent(INTENT_ACTION_SWIPE_TO_REFRESH);
                        intent.putExtra(INTENT_EXTRA_FIRST_VISIBLE_INDEX, firstVisibleItem);
                        LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
                    }
                }) ;
        }
    }

    private OnTouchEventListener touchListener = new OnTouchEventListener() {
        @Override
        public void onTouchEvent(MotionEvent ev) {
            if (ev.getAction() == MotionEvent.ACTION_UP) {
                isRefreshListView = false;
                if (mImageViewHeight - 1 < mImageView.getHeight()) {
                    ResetAnimimation animation = new ResetAnimimation(
                            mImageView, mImageViewHeight);
                    animation.setDuration(400);
                    animation.setInterpolator(new DecelerateInterpolator());
                    mImageView.startAnimation(animation);
                }
            }
        }
    };

    public class ResetAnimimation extends Animation {
        private int targetHeight;
        private int originalHeight;
        private int extraHeight;
        private View mView;

        protected ResetAnimimation(View view, int targetHeight) {
            this.mView = view;
            this.targetHeight = targetHeight;
            originalHeight = view.getHeight();
            extraHeight = this.targetHeight - originalHeight;
        }

        @Override
        protected void applyTransformation(float interpolatedTime,
                Transformation t) {
            int newHeight;
            newHeight = (int) (targetHeight - extraHeight * (1 - interpolatedTime));
            mView.getLayoutParams().height = newHeight;
            mView.requestLayout();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

将你的listView放在你的滑动内,以刷新这样的布局。

if(prefs.getBoolean("isUserLogin", false)){
                startActivity(new Intent(SplashActivity.this, MainActivity.class));
                finish();
            }else{
                startActivity(new Intent(SplashActivity.this, LoginActivity.class));
                finish();
            }

希望这会对你有帮助......