안 드 로 이 드 상하 슬라이딩 댐퍼 효과 / 드 롭 다운 이미지 신축

최근 에 QQ 공간 을 모방 하 는 효과 (그림 을 아래로 끌 어 당 겨 신축 하 는 효과) 를 만 들 고 싶 습 니 다. 댐퍼 효과 라 고 할 수 있 습 니 다. 자 료 를 살 펴 보 았 습 니 다. 우 리 는 먼저 참고 하 겠 습 니 다 (아래 그림 의 신축, 상하 당 김 신축 포함).
http://blog.csdn.net/jj120522/article/details/8938308
http://www.2cto.com/kf/201610/553393.html  
http://www.haolizi.net/example/view_799.html 
http://blog.csdn.net/dong_junshuai/article/details/54575818
http://www.jb51.net/article/108543.htm
http://blog.csdn.net/kokjuis/article/details/62046834
내 가 여기 서 실현 한 것 은 상하 당 김 저항 효과 이다. 효과 도 를 보 자.
사용자 정의 ScrollView 를 통 해 상하 당 김 저항 효 과 를 실현 합 니 다.
PersonalScrollView2.java
/**
 *  2017/7/26.
 *  ScrollView       
 */
public class PersonalScrollView2 extends ScrollView {
    private static final String TAG = "BounceScrollView";
    //----      --------
    //         
    private float mFirstPosition = 0;
    //           
    private Boolean mScaling = false;
    private View dropZoomView;//      view
    private int dropZoomViewWidth;
    private int dropZoomViewHeight;
    //----      end--------
    //------      --------
    private View inner;//  View
    private float y;//    y  
    private Rect normal = new Rect();//   (       ,            .)
    private boolean isCount = false;//       
    //     
    private float lastX = 0;
    private float lastY = 0;
    //    
    private float currentX = 0;
    private float currentY = 0;
    //      
    private float distanceX = 0;
    private float distanceY = 0;
    private boolean upDownSlide = false; //       flag
    //------      end--------
    public PersonalScrollView2(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    //   
    private void init() {
        setOverScrollMode(OVER_SCROLL_NEVER);
        if (getChildAt(0) != null) {
            inner = getChildAt(0);//        view
            //     
            ViewGroup vg = (ViewGroup) getChildAt(0);
            if (vg.getChildAt(0) != null) {
                dropZoomView = vg.getChildAt(0);
            }
        }
    }
    /***
     *         .             ,           .         onFinishInflate
     *   ,          ,        .
     */
    @Override
    protected void onFinishInflate() {
        //   
        init();
        super.onFinishInflate();
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        //          
        currentX = ev.getX();
        currentY = ev.getY();
        switch (ev.getAction()) {
            case MotionEvent.ACTION_MOVE:
                distanceX = currentX - lastX;
                distanceY = currentY - lastY;
                if (Math.abs(distanceX) < Math.abs(distanceY) && Math.abs(distanceY) > 12) {
                    upDownSlide = true;
                }
                break;
        }
        lastX = currentX;
        lastY = currentY;
        if (upDownSlide && inner != null) commOnTouchEvent(ev);
        return super.dispatchTouchEvent(ev);
    }
    /***
     *     
     *
     * @param ev
     */
    public void commOnTouchEvent(MotionEvent ev) {
        //      
        if (dropZoomViewWidth <= 0 || dropZoomViewHeight <= 0) {
            dropZoomViewWidth = dropZoomView.getMeasuredWidth();
            dropZoomViewHeight = dropZoomView.getMeasuredHeight();
        }
        switch (ev.getAction()) {
            case MotionEvent.ACTION_UP:
                //           
                mScaling = false;
                replyImage();
                //         
                if (isNeedAnimation()) {
                    animation();
                    isCount = false;
                }
                clear0();
                break;
            //        ,    
            case MotionEvent.ACTION_MOVE:
                //    
                final float preY = y;//     y  
                float nowY = ev.getY();//   y  
                int deltaY = (int) (preY - nowY);//     
                if (!isCount) {
                    deltaY = 0; //      0.
                }
                y = nowY;
                //                  ,      
                if (isNeedMove()) {
                    //        
                    if (normal.isEmpty()) {
                        //          
                        normal.set(inner.getLeft(), inner.getTop(),
                                inner.getRight(), inner.getBottom());
                    }
                    //     
                    inner.layout(inner.getLeft(), inner.getTop() - deltaY / 2,
                            inner.getRight(), inner.getBottom() - deltaY / 2);
                }
                isCount = true;
                //    end
                //    
                if (!mScaling) {
                    if (getScrollY() == 0) {
                        mFirstPosition = ev.getY();//           ,      
                    } else {
                        break;
                    }
                }
                int distance = (int) ((ev.getY() - mFirstPosition) * 0.6); //           
                if (distance < 0) { //            ,    
                    break;
                }
                //     
                mScaling = true;
                setZoom(1 + distance);
                //    end
                break;
        }
    }
    /***
     *     ,       
     */
    public void animation() {
        //       
        TranslateAnimation ta = new TranslateAnimation(0, 0, inner.getTop(),
                normal.top);
        ta.setDuration(200);
        inner.startAnimation(ta);
        //            
        inner.layout(normal.left, normal.top, normal.right, normal.bottom);
        normal.setEmpty();
    }
    //         
    public boolean isNeedAnimation() {
        return !normal.isEmpty();
    }
    //     ,header      (       )
    public void replyImage() {
        final float distance = dropZoomView.getMeasuredWidth() - dropZoomViewWidth;
        //     
        ValueAnimator anim = ObjectAnimator.ofFloat(0.0F, 1.0F).setDuration((long) (distance * 0.7));
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float cVal = (Float) animation.getAnimatedValue();
                setZoom(distance - ((distance) * cVal));
            }
        });
        anim.start();
    }
    //    
    public void setZoom(float s) {
        if (dropZoomViewHeight <= 0 || dropZoomViewWidth <= 0) {
            return;
        }
        ViewGroup.LayoutParams lp = dropZoomView.getLayoutParams();
        lp.width = (int) (dropZoomViewWidth + s);
        lp.height = (int) (dropZoomViewHeight * ((dropZoomViewWidth + s) / dropZoomViewWidth));
        dropZoomView.setLayoutParams(lp);
    }
    /***
     *          inner.getMeasuredHeight():          
     *
     * getHeight():         
     *
     * @return
     */
    public boolean isNeedMove() {
        int offset = inner.getMeasuredHeight() - getHeight();
        int scrollY = getScrollY();
        // 0   ,       
        if (scrollY == 0 || scrollY == offset) {
            return true;
        }
        return false;
    }
    //       
    private void clear0() {
        lastX = 0;
        lastY = 0;
        distanceX = 0;
        distanceY = 0;
        upDownSlide = false;
    }
}
fragment_my2.xml



    

        

            

            

            


            
        

        

            

                

                    

                    

                

                

                

                    

                    

                

                

                

                    

                    

                

            

            

            

            

            

                

                

            

            

            

            

            

                

                    

                    

                


                

                    

                    

                


                

                    

                    

                


                

                    

                    

                

            
            

            

            

            

                

                    

                    

                


                

                    

                    

                


                

                    

                    

                

            

        

    
  .view.PersonalScrollView2>

좋은 웹페이지 즐겨찾기