delete_button.xml
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/friendlist_delete_item_delete"
android:layout_width="wrap_content"
android:layout_height="@dimen/my_button_height"
android:background="@color/my_button"
android:text="@string/delete"
android:textSize="@dimen/my_button_textsize" >
</Button>
package com.example.groupuse;
public interface OnDeleteListener {
/**
* 根据要删除的id进行删除监听
* @param deleteId
*/
public void onDelete(int deleteId);
}
friendlist_item.xml
<?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="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin" >
<TextView
android:id="@+id/friendlist_item_tv"
android:layout_width="match_parent"
android:layout_height="@dimen/my_textext_height"
android:gravity="center_vertical"/>
</RelativeLayout>
package com.example.groupuse;
import com.example.groupuse.R;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnTouchListener;
import android.widget.ListView;
import android.widget.RelativeLayout;
/**
* 1、想好有几个需要监听的:手势监听OnGestureListener,触屏监听OnTouchListener,自定义删除监听OnDeleteListener
* 2、定义属性:用户手势检测对象GestureDetector、判断是否出现删除按钮的标识符isDeleteShowing
* 3、构造函数初始化要有手势检测对象及手势监听、触屏监听。
* 4、当触摸到屏幕时,textview最先响应onTouch方法,由此考虑需要一个判断是否出现按钮的标识符
* 如果出现,将itemLayout中的删除按钮移除,最终都返回onTouchEvent
* 5、当触摸到屏幕时,textview接着响应onDown方法,判断是否出现按钮的标识符
* 如果不出现,获取当前item的position
* @author Lenovo
*
*
*注意:friendlist内的textview布局中的width要为满屏,理由是选择可能是整行
* 有变化的组件要单独写个xml文件,该文件里的布局为该组件名,如:delete_button里的布局为Button
*/
public class MyListView extends ListView implements OnTouchListener,OnGestureListener{
//构造函数需要实例化的对象,可是调用该对象的监听方法
private GestureDetector gestureDetector;
//判断是否出现删除按钮的标识符
private boolean isDeleteShowing;
//每个item的行布局
private ViewGroup itemLayout;
//删除按钮布局
private View deleteButton;
//选中item的position
private int itemPosition;
//删除接口
private OnDeleteListener deleteListener;
//构造函数,传参
public MyListView(Context context,AttributeSet attrs) {
super(context,attrs);
//实例化手势对象
gestureDetector=new GestureDetector(getContext(), this);
//注册触屏监听
setOnTouchListener(this);
}
/**
* 当手放到屏幕上的时候,首先会是textview响应touch事件,执行onTouch方法。
* 返回值为true,表示这个touch事件被onTouch方法处理完毕,不会把touch事件再传递给Activity,即onTouchEvent方法不会被调用
* 返回值为false,就表示对该点击事件没消费,传递给onTouchEvent
*
* 如果触摸到item,删除按钮出现,将itemLayout中的删除按钮移除,最终都返回onTouchEvent
*/
@Override
public boolean onTouch(View v, MotionEvent event) {
if (isDeleteShowing) {
itemLayout.removeView(deleteButton);
deleteButton=null;
isDeleteShowing=false;
return false;
}else {
return gestureDetector.onTouchEvent(event);
}
}
/**
* 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发
* 返回值为false,系统就会认为你想要忽略之后的其他手势,然后手势监听 的其他方法就不会被调用。
*
* 如果触摸到item,没有出现删除按钮的话,获取被选中的item的position
*/
@Override
public boolean onDown(MotionEvent e) {
if (!isDeleteShowing) {
itemPosition=pointToPosition((int) e.getX(), (int) e.getY());
}
return false;
}
/**
* 用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEvent ACTION_DOWN触发
*/
@Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
/**
* 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发
*/
@Override
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
/**
* 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE触发
*/
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
// TODO Auto-generated method stub
return false;
}
/**
* 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发
*/
@Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
}
/**
* 用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN,多个ACTION_MOVE, 1个ACTION_UP触发
* e1:第1个ACTION_DOWN MotionEvent
* e2:最后一个ACTION_MOVE MotionEvent
* velocityX:X轴上的移动速度,像素/秒
* velocityY:Y轴上的移动速度,像素/秒
*
* 如果没有出现删除按钮并且x的速度>y的速度时,删除按钮获得布局,
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (!isDeleteShowing&&(Math.abs(velocityX)>Math.abs(velocityY))) {
deleteButton=LayoutInflater.from(getContext()).inflate(R.layout.delete_button, null);
deleteButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
itemLayout.removeView(deleteButton);
deleteButton=null;
isDeleteShowing=false;
//接口回调
deleteListener.onDelete(itemPosition);
}
});
//定位到当前显示页面的item个数,getFirstVisiblePosition()是当前页面第一条在listview的行数
itemLayout=(ViewGroup) getChildAt(itemPosition-getFirstVisiblePosition());
//设置布局
RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
params.addRule(RelativeLayout.CENTER_VERTICAL);
//将删除布局添加到listview布局
itemLayout.addView(deleteButton,params);
isDeleteShowing=true;
}
return false;
}
/**
* 接口设置监听的方法
* @param listener
*/
public void setOnDeleteListener(OnDeleteListener listener){
this.deleteListener=listener;
}
}
<pre class="java" name="code">package com.example.groupuse;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.example.groupuse.R;
public class MyAdapter extends ArrayAdapter<String>{
public MyAdapter(Context context, int textViewResourceId, List<String> objects) {
super(context, textViewResourceId, objects);
// TODO Auto-generated constructor stub
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if (convertView==null) {
view=LayoutInflater.from(getContext()).inflate(R.layout.friendlist_item, null);
}else {
view=convertView;
}
TextView textView=(TextView) view.findViewById(R.id.friendlist_item_tv);
textView.setText(getItem(position));
return view;
}
}
package com.example.groupuse;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.Window;
public class MainActivity extends Activity {
private MyListView myListView;
private MyAdapter myAdapter;
private List<String> contentList=new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initList();
myListView=(MyListView) findViewById(R.id.friendlist_tv);
myListView.setOnDeleteListener(new OnDeleteListener() {
@Override
public void onDelete(int deleteId) {
contentList.remove(deleteId);
myAdapter.notifyDataSetChanged();
}
});
myAdapter=new MyAdapter(MainActivity.this, 0, contentList);
myListView.setAdapter(myAdapter);
}
private void initList() {
for(int i=1;i<21;i++){
contentList.add("Content Item "+i);
}
}
}
效果图: