手把手实现腾讯qq拖拽删去效果(一)

  qq拖拽删除的效果,简单又好用,今天我就叫大家实现吧。

  这个滑动效果,有何难点了,就是响应每行的点击事件了,为了完成这个任务,并且能够实现动画的效果了,我重写了一个slideview这个控件,这个控件是干什么的了,是一个类似于viewflipper带动画的翻页控件了。它又是任何布局,任何控制了。

  首先,我们赏析一下它的布局文件:

<merge xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent" >



    <LinearLayout

        android:id="@+id/view_content"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:orientation="horizontal" >

    </LinearLayout>



    <RelativeLayout

        android:id="@+id/holder"

        android:layout_width="120dp"

        android:layout_height="match_parent"

        android:clickable="true"

        android:background="@drawable/delete_holder_bg">



        <TextView

            android:id="@+id/delete"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:drawableLeft="@drawable/delete_icon_normal"

            android:layout_centerInParent="true"

            android:gravity="center"

            android:textColor="@color/floralwhite"

            android:text="删除" />

    </RelativeLayout>



</merge>

  由布局文件,可得知:

  ①由一对<merge>....</merge>标签包裹了里面的容器,merge标签是什么了,又有什么作用了。可以使用<merge>标签,它将它里面嵌套的view直接include到其父layout中,而没有再加一层view group,因此减小了深度,提高了速度。在这里了,我们就是将一个linearlayout的线性表局文件和relative布局文件嵌套其中了。

  ②relativelayout是显示相应的删除的按钮,而linearlayout主要是显示需要加载数据的值。

  具体的说明,请见下图:

手把手实现腾讯qq拖拽删去效果(一)

  这里我们首先说明了布局文件,接下来就是控制文件了。

  控制文件的代码如何,我们来瞧一瞧:

package com.routemap_infomation.utils;



import android.content.Context;

import android.util.AttributeSet;

import android.util.Log;

import android.util.TypedValue;

import android.view.MotionEvent;

import android.view.View;

import android.widget.LinearLayout;

import android.widget.RelativeLayout;

import android.widget.Scroller;

import android.widget.TextView;



import com.routemap_infomation.myfocus.R;



public class SlideView extends LinearLayout {



    private static final String TAG = "SlideView";



    private Context mContext;

    private LinearLayout mViewContent;

    private RelativeLayout mHolder;

    private Scroller mScroller;

    private OnSlideListener mOnSlideListener;



    private int mHolderWidth = 100;



    private int mLastX = 0;

    private int mLastY = 0;

    private static final int TAN = 2;



    public interface OnSlideListener {

        public static final int SLIDE_STATUS_OFF = 0;

        public static final int SLIDE_STATUS_START_SCROLL = 1;

        public static final int SLIDE_STATUS_ON = 2;



        /**

         * @param view current SlideView

         * @param status SLIDE_STATUS_ON or SLIDE_STATUS_OFF

         */

        public void onSlide(View view, int status);

    }



    public SlideView(Context context) {

        super(context);

        initView();

    }



    public SlideView(Context context, AttributeSet attrs) {

        super(context, attrs);

        initView();

    }



    private void initView() {

        mContext = getContext();

        mScroller = new Scroller(mContext);



        setOrientation(LinearLayout.HORIZONTAL);

        View.inflate(mContext, R.layout.delete_button, this);

        mViewContent = (LinearLayout) findViewById(R.id.view_content);

        mHolderWidth = Math.round(TypedValue.applyDimension(

                TypedValue.COMPLEX_UNIT_DIP, mHolderWidth, getResources()

                        .getDisplayMetrics()));

    }



    public void setButtonText(CharSequence text) {

        ((TextView)findViewById(R.id.delete)).setText(text);

    }



    public void setContentView(View view) {

        mViewContent.addView(view);

    }



    public void setOnSlideListener(OnSlideListener onSlideListener) {

        mOnSlideListener = onSlideListener;

    }



    public void shrink() {

        if (getScrollX() != 0) {

            this.smoothScrollTo(0, 0);

        }

    }



    public boolean onRequireTouchEvent(MotionEvent event) {

        

        int x = (int) event.getX();

        int y = (int) event.getY();

        int scrollX = getScrollX();

        Log.d(TAG, "x=" + x + "  y=" + y);



        switch (event.getAction()) {

        case MotionEvent.ACTION_DOWN: {

            

            if (!mScroller.isFinished()) {

                mScroller.abortAnimation();

            }

            if (mOnSlideListener != null) {

                mOnSlideListener.onSlide(this,

                        OnSlideListener.SLIDE_STATUS_START_SCROLL);

            }

            break;

        }

        case MotionEvent.ACTION_MOVE: {

        

            int deltaX = x - mLastX;

            int deltaY = y - mLastY;

            if (Math.abs(deltaX) < Math.abs(deltaY) * TAN) {

                break;

            }



            int newScrollX = scrollX - deltaX;

            if (deltaX != 0) {

                if (newScrollX < 0) {

                    newScrollX = 0;

                } else if (newScrollX > mHolderWidth) {

                    newScrollX = mHolderWidth;

                }

                this.scrollTo(newScrollX, 0);

            }

            break;

        }

        case MotionEvent.ACTION_UP: {

        

            int newScrollX = 0;

            if (scrollX - mHolderWidth * 0.75 > 0) {

                newScrollX = mHolderWidth;

            }

            this.smoothScrollTo(newScrollX, 0);

            if (mOnSlideListener != null) {

                mOnSlideListener.onSlide(this,

                        newScrollX == 0 ? OnSlideListener.SLIDE_STATUS_OFF

                                : OnSlideListener.SLIDE_STATUS_ON);

                return false;

            }

           // break;

        }

        default:

            break;

        }



        mLastX = x;

        mLastY = y;

        return true;

    }



    private void smoothScrollTo(int destX, int destY) {

        // 缓慢滚动到指定位置

        int scrollX = getScrollX();

        int delta = destX - scrollX;

        mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 3);

        invalidate();

    }



    @Override

    public void computeScroll() {

        if (mScroller.computeScrollOffset()) {

            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());

            postInvalidate();

        }

    }



}

  由代码我们可以下这样的结论了:

  ①这个控件其实本质是一个线性布局(Linearlayout)控件,因此就具有了linearlayout的属性。

  ②我上文说过这个控件是为了实现一个viewflipper翻页动画效果,因此需要一个动画效果,这里,我没有做自身的动画,而是通过了scroller本身滑动带有的动画效果。

  ③因为是拖拽,所以监听屏幕的触摸事件也是理所当然了,因此需要处理好触摸按下(down),触摸移动(move),抬起(up)的事件,对其相应事件下,scroller(滑动条)移动的距离需要进行监听。

  ④由于要移动控件,移动后,相应的控件需要进行了重回。

  这就是我实现了拖拽效果的一利器,今天就介绍到这里了。下节,来说明吧它如何整合到自定义的下拉列表中去。 

  

你可能感兴趣的:(qq)