关闭

自定义ListView侧滑删除 畅所欲滑,删你想删

标签: android自定义ListView侧滑删除
518人阅读 评论(0) 收藏 举报
分类:

常规的ListView 删除都是单点,或者长按删除

为了用户体验,出现了很多的交互方式

这里给大家分享一下侧滑删除

  


首先自定义的控件,这里这是简单继承,处理了一部分的事件分发,并没有自定义属性

SlidingDelete.class

/**
 * @author ruyi
 * @version 创建时间:2016年5月30日 上午10:16:58
 * 
 */
public class SlidingDelete extends HorizontalScrollView {
	public static final String HIDEN_SLIDING = "HIDEN_SLIDING";
	private static final int HIDEN_ALL_SLIDING = -1;
	
	private int mScreenWidth;
	private LinearLayout mWapper; //根布局(LinearLayout)
	private ViewGroup mContent; // item布局
	private ViewGroup mMenu;   // 删除布局
	private Context mContext;
	private int mHashcode;  // 当前context 的唯一hashcode
	
	private boolean isSliding;
	private static boolean isAllSliding;
	
	
	/**
	 * 显示所有的非当前的主菜单单
	 */
	private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			int stringExtra = intent.getIntExtra("hashcode", 0);
			if (stringExtra != mHashcode) {
				showMenu();
			}
		}
	};

	public SlidingDelete(Context context) {
		super(context);
	}

	public SlidingDelete(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		WindowManager wm = (WindowManager) context
				.getSystemService(Context.WINDOW_SERVICE);
		DisplayMetrics outMetrics = new DisplayMetrics();
		wm.getDefaultDisplay().getMetrics(outMetrics);
		mScreenWidth = outMetrics.widthPixels;

		IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(HIDEN_SLIDING);
		context.registerReceiver(mBroadcastReceiver, intentFilter);
		mContext = context;
		mHashcode = this.hashCode();
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		mWapper = (LinearLayout) getChildAt(0);
		mContent = (ViewGroup) mWapper.getChildAt(0);
		mMenu = (ViewGroup) mWapper.getChildAt(1);
		mContent.getLayoutParams().width = mScreenWidth;

		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}

	private boolean isCancel = false;

	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			if (isCancel) {
				isCancel = false;
			}
			if (!isSliding && isAllSliding) {
				showMenus(mContext);
				isCancel = true;
				return true;
			}
			break;
		default:
			break;
		}
		
		if (isCancel) {
			return true;
		}
		
		return super.dispatchTouchEvent(ev);
	}

	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			break;
		case MotionEvent.ACTION_MOVE:
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_CANCEL:
			if (getScrollX() < mMenu.getWidth() / 2) {
				showMenu();
			} else {
				hideMenu();
			}
			return true;
		default:
			break;
		}
		return super.onTouchEvent(ev);
	}

	/**
	 * 显示 主菜单
	 */
	public void showMenu() {
		if (isSliding) {
			isSliding = false;
			isAllSliding = false;
		}
		this.smoothScrollTo(0, 0);
	}

	/**
	 * 显示 所有非当前主菜单
	 */
	public static void showMenus(Context context) {
		if (isAllSliding) {
			isAllSliding = false;
			Intent intent = new Intent();
			intent.putExtra("hashcode", HIDEN_ALL_SLIDING);
			intent.setAction(HIDEN_SLIDING);
			context.sendBroadcast(intent);
		}
	}

	/**
	 * 显示 删除菜单(显示当前滑动的删除菜单,还原非当前的主菜单)
	 */
	public void hideMenu() {
		Intent intent = new Intent();
		intent.putExtra("hashcode", mHashcode);
		intent.setAction(HIDEN_SLIDING);
		mContext.sendBroadcast(intent);
		this.smoothScrollTo(mMenu.getWidth(), 0);
		isSliding = true;
		isAllSliding = true;
	}

	/**
	 * 直接隐藏 删除菜单
	 */
	public void fastHideMenu() {
		Intent intent = new Intent();
		intent.putExtra("hashcode", mHashcode);
		intent.setAction(HIDEN_SLIDING);
		mContext.sendBroadcast(intent);
		this.scrollTo(0, 0);
	}

}

这里自定义控件,根标签是LinearLayout, 第一个Child是主Item , 第二个就是删除按钮所在的容器了


main_layout 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView 
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
        
    
</RelativeLayout>

每个Item的布局,这个自定义控件根布局必须是LinearLayout

item.layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.ruiyi.testslidedelete.SlidingDelete
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:overScrollMode="never"
        android:scrollbars="none" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <RelativeLayout 
                android:id="@+id/item"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <ImageView 
                    android:id="@+id/iv"
                    android:layout_width="wrap_content"
                    android:layout_height="80dp"
                    android:src="@drawable/ic_launcher"/>
                <TextView 
                    android:id="@+id/tv"
                    android:layout_alignTop="@id/iv"
                    android:layout_alignBottom="@id/iv"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:gravity="center"/>
            </RelativeLayout>

            <FrameLayout
                android:id="@+id/delete"
                android:layout_width="100dp"
                android:layout_height="match_parent"
                android:background="#ff4c39" >

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:gravity="center"
                    android:text="删除"
                    android:textColor="#FFFFFF"
                    android:textSize="16.5sp" />
            </FrameLayout>
        </LinearLayout>
    </com.ruiyi.testslidedelete.SlidingDelete>
    
</LinearLayout>

这里是我们的适配器,介绍了一下怎么使用,还有点击主页面和删除键的样例处理

MyBaseAdapter.class

/**
 * @author ruyi
 * @version 创建时间:2016年5月30日 上午11:14:25
 * 
 */
public class MyBaseAdapter extends BaseAdapter {
	private Context mContext;
	private ArrayList<String> mList;
	private OnItemContentClickListener listener;
	
	public MyBaseAdapter(Context context){
		this.mContext = context;
	}
	
	public void setDate(ArrayList<String> list){
		mList = list;
	}

	@Override
	public int getCount() {
		return mList == null ? 0 : mList.size();
	}

	@Override
	public Object getItem(int position) {
		return mList.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		final ViewHolder holder;
		if (convertView == null || convertView.getTag() == null) {
			convertView = LayoutInflater.from(mContext).inflate(R.layout.item_delete, null);
			holder = new ViewHolder(convertView);
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}
		
		SlidingDelete.showMenus(parent.getContext());
		MyClickListener clickListener = new MyClickListener(position, mList.get(position));
		holder.tv.setText(mList.get(position));
		holder.item.setOnClickListener(clickListener);
		holder.delete.setOnClickListener(clickListener);
		return convertView;
	}

	public class ViewHolder {
		public TextView tv;
		public RelativeLayout item;
		public FrameLayout delete;

		public ViewHolder(View view) {
			tv = (TextView) view.findViewById(R.id.tv);
			item = (RelativeLayout) view.findViewById(R.id.item);
			delete = (FrameLayout) view.findViewById(R.id.delete);
		}
	}
	
	public interface OnItemContentClickListener {
		public void onItemClick(String string);
		public void onDeleteClick(int position);
	}

	public void setOnItemContentClickListener(OnItemContentClickListener listener) {
		this.listener = listener;
	}
	
	public class MyClickListener implements OnClickListener {
		private int position;
		private String string;
		
		public MyClickListener(int position, String string) {
			this.position = position;
			this.string = string;
		}
		@Override
		public void onClick(View v) {
			SlidingDelete.showMenus(v.getContext());
			if (listener == null) {
				return;
			}
			switch (v.getId()) {
				case R.id.item :
					listener.onItemClick(string);
					break;
				case R.id.delete :
					listener.onDeleteClick(position);
					break;
				default :
					break;
			}
		}
	};
}

这里是Activity.class

public class MainActivity extends Activity implements OnItemContentClickListener{
	
	private ListView mLv;
	private ArrayList<String> mList = new ArrayList<String>();
	private MyBaseAdapter mAdapter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		initData();
		initView();
		
	}

	private void initView() {
		mLv = (ListView) findViewById(R.id.lv);
		mAdapter = new MyBaseAdapter(this);
		mAdapter.setDate(mList);
		mAdapter.setOnItemContentClickListener(this);
		mLv.setAdapter(mAdapter);
	}

	private void initData() {
		for(int i=0 ;i<20;i++){
			mList.add(""+i);
		}
	}

	@Override
	public void onItemClick(String string) {
		Toast.makeText(MainActivity.this, string+"被点击" , Toast.LENGTH_SHORT).show();
	}

	@Override
	public void onDeleteClick(int position) {
		mList.remove(position);
		mAdapter.notifyDataSetChanged();
	}

}

就这样

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:13421次
    • 积分:568
    • 等级:
    • 排名:千里之外
    • 原创:43篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条