基本上关键点在, 1事件, android:longClickable="true" android:descendantFocusability="blocksDescendants" 这个是在item子控件返回true 而使onInterceptTouchEvent 不停有事件来, 2 layout ,的设计,onLayout方法,relativeonLayout好像比较难达到这种拖后还有显示删除按钮 3,一些回调接口,方便toggle



import android.annotation.SuppressLint;

import android.content.Context;

import android.util.AttributeSet;

import android.util.Log;

import android.view.GestureDetector;

import android.view.GestureDetector.SimpleOnGestureListener;

import android.view.MotionEvent;

import android.view.VelocityTracker;

import android.view.View;

import android.view.ViewConfiguration;

import android.widget.LinearLayout;

import android.widget.Scroller;



@SuppressLint("NewApi")

public class SlidingLeftLayout extends LinearLayout {



public SlidingLeftLayout(Context context) {

super(context);

init(context);

}



// public SlidingLeftLayout(Context context, AttributeSet attrs, int

// defStyle) {

// super(context, attrs, defStyle);

// init(context);

// }



public SlidingLeftLayout(Context context, AttributeSet attrs) {

super(context, attrs);

init(context);

}



public SlidingLeftLayout(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

init(context);

}



public void init(Context context) {

mContext = context;

mScroller = new Scroller(mContext);

ViewConfiguration config = ViewConfiguration.get(context);

mTouchSlop = config.getScaledTouchSlop();

mMinFlingVelocity = config.getScaledMinimumFlingVelocity();

setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);



return;

}



private Context mContext;

private static String TAG = "SlidingLeftRelativeLayout";

private static final boolean DEBUG = true;



private static final int TOUCH_MODE_IDLE = 0;

private static final int TOUCH_MODE_DOWN = 1;

private static final int TOUCH_MODE_DRAGGING = 2;



private int mTouchMode;

private int mTouchSlop;

private VelocityTracker mVelocityTracker;

private int mMinFlingVelocity;

private float mTouchX;

private float mStartX;



private static final int SCREEN_ID_NORMAL = 0;

private static final int SCREEN_ID_LEFT = 1;

private int mCurScreen = SCREEN_ID_NORMAL;



private Scroller mScroller = null;

private int mScrollWidth = 120;



// @Override

// protected void onLayout(boolean changed, int l, int t, int r, int b) {

// super.onLayout(changed, l+mScrollWidth, t+mScrollWidth, r, b);

//

// }



@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

super.setOrientation(LinearLayout.HORIZONTAL);

// super.onLayout(changed, l, t, r, b);



int height = getHeight();

int width = getWidth();



int childCount = getChildCount();



for (int i = 0; i < childCount; i++) {

View child = getChildAt(i);

if (child != null && child.getVisibility() != View.GONE) {

if (i == 0) {

child.layout(0, 0, width, height);

} else if (i == 1) {

child.layout(width, 0, width + mScrollWidth, height);

}

}

}



}



// @Override

public boolean onInterceptTouchEvent2(MotionEvent ev) {



final int action = ev.getActionMasked();

if (DEBUG) {

Log.d(TAG, "onInterceptTouchEvent action " + action);

}



if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {

if (DEBUG)

Log.d(TAG, "onInterceptTouchEvent ACTION_UP");

if (mTouchMode == TOUCH_MODE_DRAGGING) {

// stopDrag(ev);

}



if (mVelocityTracker != null) {

mVelocityTracker.recycle();

mVelocityTracker = null;

}

if (DEBUG)

Log.d(TAG, "onInterceptTouchEvent return " + false);

return false;

}



// Nothing more to do here if we have decided whether or not we

// are dragging.

if (action != MotionEvent.ACTION_DOWN) {

if (mTouchMode == TOUCH_MODE_DRAGGING) {

if (DEBUG)

Log.v(TAG, "Intercept returning true!");

if (DEBUG)

Log.d(TAG, "onInterceptTouchEvent return " + true);

return true;

}

}



switch (action) {

case MotionEvent.ACTION_MOVE: {

switch (mTouchMode) {

case TOUCH_MODE_IDLE:

break;



case TOUCH_MODE_DOWN: {

final float x = ev.getX();

if (Math.abs(x - mTouchX) > mTouchSlop) {

mTouchMode = TOUCH_MODE_DRAGGING;

getParent().requestDisallowInterceptTouchEvent(true);

mTouchX = x;

if (DEBUG)

Log.d(TAG, "onInterceptTouchEvent return " + true);

return true;

}

break;

}



case TOUCH_MODE_DRAGGING: {

final float x = ev.getX();

final float dx = mTouchX - x;

mStartX = Math.abs(getScrollX());

float newPos = Math.max(0, Math.min(mStartX + dx, mScrollWidth));

if (newPos != mStartX) {

scrollTo((int) newPos, 0);

mTouchX = x;

invalidate();

}

}

}

break;

}



case MotionEvent.ACTION_DOWN: {

// if (mOnSlideListener != null) {

// mOnSlideListener.onSlidingStart(this);

// }

final float x = ev.getX();

mTouchMode = TOUCH_MODE_DOWN;

mTouchX = x;

}

}



if (mVelocityTracker == null) {

mVelocityTracker = VelocityTracker.obtain();

}

mVelocityTracker.addMovement(ev);



if (DEBUG)

Log.d(TAG, "onInterceptTouchEvent return " + (mTouchMode == TOUCH_MODE_DRAGGING));

return mTouchMode == TOUCH_MODE_DRAGGING;



}



public void shrink() {

if (getScrollX() != 0) {

this.smoothScrollTo(0, 0);

// this.scrollTo(0, 0);



}

}



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();

}

}



@Override

public boolean onInterceptTouchEvent(MotionEvent ev) {

final int action = ev.getActionMasked();

if (DEBUG) {

Log.d(TAG, "onInterceptTouchEvent action " + action);

}



if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {

if (DEBUG)

Log.d(TAG, "onInterceptTouchEvent ACTION_UP");

if (mTouchMode == TOUCH_MODE_DRAGGING) {

// stopDrag(ev);

}



if (mVelocityTracker != null) {

mVelocityTracker.recycle();

mVelocityTracker = null;

}

if (DEBUG)

Log.d(TAG, "onInterceptTouchEvent return " + false);

return false;

}



// Nothing more to do here if we have decided whether or not we

// are dragging.

if (action != MotionEvent.ACTION_DOWN) {

if (mTouchMode == TOUCH_MODE_DRAGGING) {

if (DEBUG)

Log.v(TAG, "Intercept returning true!");

if (DEBUG)

Log.d(TAG, "onInterceptTouchEvent return " + true);

return true;

}

}



switch (action) {

case MotionEvent.ACTION_MOVE: {

switch (mTouchMode) {

case TOUCH_MODE_IDLE:

break;



case TOUCH_MODE_DOWN: {

final float x = ev.getX();

if (Math.abs(x - mTouchX) > mTouchSlop) {

mTouchMode = TOUCH_MODE_DRAGGING;

getParent().requestDisallowInterceptTouchEvent(true);

mTouchX = x;

if (DEBUG)

Log.d(TAG, "onInterceptTouchEvent return " + true);

return true;

}

break;

}



case TOUCH_MODE_DRAGGING: {

final float x = ev.getX();

final float dx = mTouchX - x;

mStartX = Math.abs(getScrollX());

float newPos = Math.max(0, Math.min(mStartX + dx, mScrollWidth));

if (newPos != mStartX) {

scrollTo((int) newPos, 0);

mTouchX = x;

invalidate();

}

}

}

break;

}



case MotionEvent.ACTION_DOWN: {

if (mOnSlideListener != null) {

// mOnSlideListener.onSlideBack();

mOnSlideListener.onSlidingStart(this);

}

final float x = ev.getX();

mTouchMode = TOUCH_MODE_DOWN;

mTouchX = x;

}

}



if (mVelocityTracker == null) {

mVelocityTracker = VelocityTracker.obtain();

}

mVelocityTracker.addMovement(ev);



if (DEBUG)

Log.d(TAG, "onInterceptTouchEvent return " + (mTouchMode == TOUCH_MODE_DRAGGING));

return mTouchMode == TOUCH_MODE_DRAGGING;

}



public boolean onTouchEvent(MotionEvent event) {

if (mVelocityTracker == null) {

mVelocityTracker = VelocityTracker.obtain();

}

mVelocityTracker.addMovement(event);

final int action = event.getActionMasked();

if (DEBUG)

Log.d(TAG, "onTouchEvent action " + action);



switch (action) {

case MotionEvent.ACTION_DOWN: {

final float x = event.getX();

mTouchMode = TOUCH_MODE_DOWN;

mTouchX = x;

}



case MotionEvent.ACTION_MOVE: {

switch (mTouchMode) {

case TOUCH_MODE_IDLE:

break;



case TOUCH_MODE_DOWN: {

final float x = event.getX();

if (Math.abs(x - mTouchX) > mTouchSlop) {

mTouchMode = TOUCH_MODE_DRAGGING;

getParent().requestDisallowInterceptTouchEvent(true);

mTouchX = x;

return true;

}

break;

}



case TOUCH_MODE_DRAGGING: {

final float x = event.getX();

final float dx = mTouchX - x;

mStartX = Math.abs(getScrollX());

float newPos = Math.max(0, Math.min(mStartX + dx, mScrollWidth));

Log.d(TAG, "mStartX " + mStartX + " newPos " + newPos);

if (newPos != mStartX) {

scrollTo((int) newPos, 0);

mTouchX = x;

invalidate();

}

return true;

}

}

break;

}



case MotionEvent.ACTION_UP:

case MotionEvent.ACTION_CANCEL: {

if (mTouchMode == TOUCH_MODE_DRAGGING) {

// stopDrag(event);

}

if (mOnSlideListener != null) {

mOnSlideListener.onSlideBack();

// mOnSlideListener.onSlidingStart(this);

}

if (mVelocityTracker != null) {

mVelocityTracker.recycle();

mVelocityTracker = null;

}

break;

}

}

return true;

}



private OnSlideListener mOnSlideListener;



public interface OnSlideListener {



public void onSlideBack();



public void onSlidingStart(SlidingLeftLayout item);

}



public void setSlidingListener(OnSlideListener l) {

mOnSlideListener = l;

}

}













import java.io.File;

import java.util.LinkedList;



import org.json.JSONObject;



import android.app.AlertDialog;

import android.content.Context;

import android.content.DialogInterface;

import android.graphics.Bitmap;

import android.view.LayoutInflater;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.Button;

import android.widget.ImageView;

import android.widget.RelativeLayout;

import android.widget.TextView;



import com.leo.langtao.bean.FileBean;

import com.leo.langtao.fyrs.R;

import com.leo.langtao.util.BitmapUtil;

import com.leo.langtao.util.JsonUtil;

import com.leo.langtao.util.ViewUtil;

import com.leo.langtao.zxing.view.SlidingLeftLayout;

import com.leo.langtao.zxing.view.SlidingLeftLayout.OnSlideListener;



public class FileAdapter2 extends BaseAdapter implements OnSlideListener{

private Context mContext;

private LinkedList<String> mData;

private String mComer;

private SlidingAdapterInterface mListener;

private SlidingLeftLayout lastSlidingLeftLayout;

private SlidingLeftLayout nowSlidingLeftLayout;



public FileAdapter2(Context ctx, LinkedList<String> data,SlidingAdapterInterface listener) {

mContext = ctx;

mData = data;

mListener = listener;

}



public FileAdapter2(Context ctx, LinkedList<String> data) {

mContext = ctx;

mData = data;

}



public FileAdapter2(Context ctx, LinkedList<String> data, String comer) {

mContext = ctx;

mData = data;

mComer = comer;

}



@Override

public int getCount() {

return mData.size();

}



@Override

public Object getItem(int pos) {

return mData.get(pos);

}



@Override

public long getItemId(int pos) {

return pos;

}



@Override

public View getView(final int pos, View convertView, ViewGroup parent) {

ViewHolder vh = null;

if (convertView == null) {

convertView = LayoutInflater.from(mContext).inflate(

R.layout.item_activity_file_manager_list2, null);

vh = new ViewHolder();

vh.rlo = convertView.findViewById(R.id.rlo);

vh.tvName = ViewUtil.getTextViewById(convertView, R.id.tv_name);

vh.ivIcon = ViewUtil.getImageViewById(convertView, R.id.iv_icon);

vh.btnDel = ViewUtil.getButtonById(convertView, R.id.btn_del_file);

convertView.setTag(vh);

} else {

vh = (ViewHolder) convertView.getTag();

}



final String item = mData.get(pos);

final JSONObject json = JsonUtil.castStringToJson(item);

final FileBean bean = new FileBean(json);

vh.tvName.setText(bean.getName());



if (!bean.isFolder()) {

Bitmap bm = BitmapUtil.getBitmap(bean.getPath(), 50);

vh.ivIcon.setImageBitmap(bm);

}

vh.rlo.setOnClickListener(new View.OnClickListener() {



@Override

public void onClick(View v) {

mListener.onListItemClick(pos);

}

});



vh.btnDel.setOnClickListener(new OnClickListener() {



@Override

public void onClick(View v) {



new AlertDialog.Builder(mContext)

.setTitle(R.string.sure_delete)

.setPositiveButton(R.string.IDS_Btn_OK,

new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog,

int which) {

File file = new File(bean.getPath());

if (file != null) {

try {

if (file.isFile()) {

file.delete();

} else if (file.isDirectory()) {



for (File f : file

.listFiles()) {

f.delete();

}

file.delete();

}



} catch (Exception e) {

e.printStackTrace();

}

mData.remove(pos);

notifyDataSetChanged();

}

}

})

.setNegativeButton(R.string.IDS_Btn_Quit,

null).show();



}

});

((SlidingLeftLayout)convertView.findViewById(R.id.slidingLeftLayout)).setSlidingListener(this);

((SlidingLeftLayout)convertView.findViewById(R.id.slidingLeftLayout)).shrink();

return convertView;

}



private class ViewHolder {

TextView tvName;

ImageView ivIcon;

Button btnDel;

View rlo;

}



public interface SlidingAdapterInterface{

void onListItemClick(int pos);

}



@Override

public void onSlideBack() {

if(lastSlidingLeftLayout!=null&&lastSlidingLeftLayout!=nowSlidingLeftLayout)

lastSlidingLeftLayout.shrink();

}



@Override

public void onSlidingStart(SlidingLeftLayout item) {



if(lastSlidingLeftLayout==null){

if(nowSlidingLeftLayout!=null){

lastSlidingLeftLayout = nowSlidingLeftLayout;

}

}else{

lastSlidingLeftLayout = nowSlidingLeftLayout;

}

nowSlidingLeftLayout = item;

}

}





<?xml version="1.0" encoding="utf-8"?>

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

android:layout_width="match_parent"

android:layout_height="wrap_content" >



<com.leo.langtao.zxing.view.SlidingLeftLayout

android:id="@+id/slidingLeftLayout"

android:layout_width="match_parent"

android:layout_height="50dip" >



<RelativeLayout

android:id="@+id/rlo"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:longClickable="true"

android:descendantFocusability="blocksDescendants" >



<ImageView

android:id="@+id/iv_icon"

android:layout_width="32dip"

android:layout_height="32dip"

android:layout_alignParentLeft="true"

android:layout_centerHorizontal="true"

android:layout_centerVertical="true"

android:layout_marginLeft="@dimen/padding_5dip"

android:layout_marginRight="@dimen/padding_5dip"

android:background="@drawable/icon_file_item"

android:focusable="false" />



<TextView

android:id="@+id/tv_name"

android:textSize="15sp"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerHorizontal="true"

android:layout_centerVertical="true"

android:layout_marginLeft="@dimen/margin_8dip"

android:layout_toRightOf="@+id/iv_icon"

android:focusable="false"

android:text="家居1" />

</RelativeLayout>



<Button

android:id="@+id/btn_del_file"

android:layout_width="32dip"

android:layout_height="32dip"

android:layout_alignParentRight="true"

android:layout_centerHorizontal="true"

android:layout_centerVertical="true"

android:layout_marginLeft="@dimen/padding_8dip"

android:layout_marginRight="@dimen/padding_8dip"

android:background="@drawable/btn_delete_up"

android:focusable="false" />

</com.leo.langtao.zxing.view.SlidingLeftLayout>



</RelativeLayout>

更多相关文章

  1. android监听事件添加动作的三种方式
  2. 【Android】事件分发机制
  3. Android 点击事件分发

随机推荐

  1. php多维数组创建及遍历
  2. 从运维角度测试全局死锁以及带来的问题
  3. 你向 MySQL 数据库插入 100w 条数据用了
  4. 人人都想偷的数据库误操作后悔药!
  5. 一文带你看懂MySQL执行计划
  6. update 主键造成行锁等待测试
  7. 数据持久化框架为什么放弃 Hibernate、JP
  8. 多态与魔术方法
  9. PHP 常用魔术方法
  10. 避坑攻略:细数买云服务器的那些坑,如何避免