標籤:
1、觸摸事件 dispatchTouchEvent 判斷是否處理觸摸動作 onTouchEvent 處理觸摸動作
2、Android對於控制和擷取View在螢幕很強大
ListView:
pointToPosition 根據觸摸點擷取item的位置
getChildAt 根據索引擷取item的View,注意從第一個可視化的item算起
View:
getLocationOnScreen擷取View在螢幕的座標
import android.content.Context;import android.util.AttributeSet;import android.view.Gravity;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import android.widget.Button;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.PopupWindow;public class MyListView extends ListView{ private static final String TAG = "MyListView"; // private static final int VELOCITY_SANP = 200; // private VelocityTracker mVelocityTracker; /** * 使用者滑動的最小距離 */ private int touchSlop; /** * 是否響應滑動 */ private boolean isSliding; /** * 手指按下時的x座標 */ private int xDown; /** * 手指按下時的y座標 */ private int yDown; /** * 手指移動時的x座標 */ private int xMove; /** * 手指移動時的y座標 */ private int yMove; private LayoutInflater mInflater; private PopupWindow mPopupWindow; private int mPopupWindowHeight; private int mPopupWindowWidth; private Button mDelBtn; /** * 為刪除按鈕提供一個回調介面 */ private DelButtonClickListener mListener; /** * 當前手指觸摸的View */ private View mCurrentView; /** * 當前手指觸摸的位置 */ private int mCurrentViewPos; /** * 必要的一些初始化 * * @param context * @param attrs */ public MyListView(Context context, AttributeSet attrs) { super(context, attrs); mInflater = LayoutInflater.from(context); // 擷取裝置所支援的最小滑動距離 touchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); View view = mInflater.inflate(R.layout.button_list, null); mDelBtn = (Button) view.findViewById(R.id.id_item_btn1); // mPopupWindow = new PopupWindow(view, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); /** * 先調用下measure,否則拿不到寬和高 */ mPopupWindow.getContentView().measure(0, 0); mPopupWindowHeight = mPopupWindow.getContentView().getMeasuredHeight(); mPopupWindowWidth = mPopupWindow.getContentView().getMeasuredWidth(); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { int action = ev.getAction(); int x = (int) ev.getX(); int y = (int) ev.getY(); switch (action) { case MotionEvent.ACTION_DOWN: xDown = x; yDown = y; /** * 如果當前popupWindow顯示,則直接隱藏,然後屏蔽ListView的touch事件的下傳 */ if (mPopupWindow.isShowing()) { dismissPopWindow(); return false; } // 獲得當前手指按下時的item的位置 mCurrentViewPos = pointToPosition(xDown, yDown); // 獲得當前手指按下時的item View view = getChildAt(mCurrentViewPos - getFirstVisiblePosition()); mCurrentView = view; break; case MotionEvent.ACTION_MOVE: xMove = x; yMove = y; int dx = xMove - xDown; int dy = yMove - yDown; /** * 判斷是否是從右至左的滑動 */ if (xMove < xDown && Math.abs(dx) > touchSlop && Math.abs(dy) < touchSlop) { // Log.e(TAG, "touchslop = " + touchSlop + " , dx = " + dx + // " , dy = " + dy); isSliding = true; } break; } return super.dispatchTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) { int action = ev.getAction(); /** * 如果是從右至左的滑動才相應 */ if (isSliding) { switch (action) { case MotionEvent.ACTION_MOVE: int[] location = new int[2]; // 獲得當前item的位置x與y mCurrentView.getLocationOnScreen(location); // 設定popupWindow的動畫 mPopupWindow.setAnimationStyle(R.style.button_anim_style); mPopupWindow.update(); mPopupWindow.showAtLocation(mCurrentView, Gravity.LEFT | Gravity.TOP, location[0] + mCurrentView.getWidth(), location[1]);// + mCurrentView.getHeight() / 2 - mPopupWindowHeight / 2); // 設定刪除按鈕的回調 mDelBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mListener != null) { mListener.clickHappend(mCurrentViewPos); mPopupWindow.dismiss(); } } }); // Log.e(TAG, "mPopupWindow.getHeight()=" + mPopupWindowHeight); break; case MotionEvent.ACTION_UP: isSliding = false; } // 相應滑動期間螢幕itemClick事件,避免發生衝突 return true; } return super.onTouchEvent(ev); } /** * 隱藏popupWindow */ private void dismissPopWindow() { if (mPopupWindow != null && mPopupWindow.isShowing()) { mPopupWindow.dismiss(); } } public void setDelButtonClickListener(DelButtonClickListener listener) { mListener = listener; } interface DelButtonClickListener { public void clickHappend(int position); }}
Android 自訂ListView控制項,滑動刪除