qq拖拽删除的效果,简单又好用,今天我就叫大家实现吧。
这个滑动效果,有何难点了,就是响应每行的点击事件了,为了完成这个任务,并且能够实现动画的效果了,我重写了一个slideview这个控件,这个控件是干什么的了,是一个类似于viewflipper带动画的翻页控件了。它又是任何布局,任何控制了。
首先,我们赏析一下它的布局文件:
由布局文件,可得知:
①由一对<merge>....</merge>标签包裹了里面的容器,merge标签是什么了,又有什么作用了。可以使用<merge>标签,它将它里面嵌套的view直接include到其父layout中,而没有再加一层view group,因此减小了深度,提高了速度。在这里了,我们就是将一个linearlayout的线性表局文件和relative布局文件嵌套其中了。
②relativelayout是显示相应的删除的按钮,而linearlayout主要是显示需要加载数据的值。
具体的说明,请见下图:
这里我们首先说明了布局文件,接下来就是控制文件了。
控制文件的代码如何,我们来瞧一瞧:
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(滑动条)移动的距离需要进行监听。
④由于要移动控件,移动后,相应的控件需要进行了重回。
这就是我实现了拖拽效果的一利器,今天就介绍到这里了。下节,来说明吧它如何整合到自定义的下拉列表中去。