首先继承创建继承ListView和实现OnTouchListener,OnGestureListener的类。
会使用到AbsList中的pointToPosition(int x, int y)方法,这个方法主要是根据点击的位置获得点击行的在列表中的索引。
还有ViewGroup中的getChildAt(int index)方法,主要用于根据当前的索引获得子控件。这个(这个索引以可见屏幕顶端开始)。
之所以实现OnTouchListener,OnGestureListener。是由于OnGestureListener要获得到OnTouchListener传递的事件。
package com.example.mylistview;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
public class MyListView extends ListView implements OnTouchListener,OnGestureListener
{
private GestureDetector gestureDetector;
private View deleteButton;
private ViewGroup itemLayout;
private onDeleteListener listener;
private int selectedItem;
private boolean isDeleteShown;
private Context lcontext;
public void setonDeleteListener(onDeleteListener l)
{
listener = l;
}
//回调接口
public interface onDeleteListener
{
void onDelete(int index);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
gestureDetector = new GestureDetector(getContext(), this);
lcontext = context;
setOnTouchListener(this);
}
//事件的传入口,分发事件给gestureDetector。
@Override
public boolean onTouch(View v, MotionEvent event) {
if(isDeleteShown)
{
itemLayout.removeView(deleteButton);
deleteButton = null;
isDeleteShown = false;
return false;
}
return gestureDetector.onTouchEvent(event);
}
@Override
public boolean onDown(MotionEvent e) {
if(!isDeleteShown)
{
//所按下位置的行数
selectedItem = pointToPosition((int)e.getX(),(int) e.getY());
}
return true;
}
//处理滑动事件
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
//如果按钮没有显示并且在x轴上的速度大于在y轴上的速度
if(!isDeleteShown && 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;
isDeleteShown = false;
listener.onDelete(selectedItem);
}
});
//(从当前页面可见的开始)获得1行的布局
itemLayout = (ViewGroup) getChildAt(selectedItem - getFirstVisiblePosition());
if(itemLayout == null)
{
Toast.makeText(lcontext, "请选择可用的行!", Toast.LENGTH_SHORT).show();
return false;
}
//设置button的添加参数
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
params.addRule(RelativeLayout.CENTER_VERTICAL);
itemLayout.addView(deleteButton, params);
isDeleteShown = true;
}
return true;
}
@Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
}
}
以后定义删除按钮布局,和主界面的布局,item布局。
自定义adapter:
package com.example.mylistview;
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;
public class MyAdapter extends ArrayAdapter<String>
{
public MyAdapter(Context context, int resource, List<String> objects) {
super(context, resource, 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.list_view_item, null);
}
else
{
view = convertView;
}
TextView tv = (TextView)view.findViewById(R.id.text_view);
tv.setText(getItem(position));
return view;
}
}
主界面代码:
</pre><pre name="code" class="java">package com.example.mylistview;
import java.util.ArrayList;
import java.util.List;
import com.example.mylistview.MyListView.onDeleteListener;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.app.Activity;
public class MainActivity extends Activity
{
MyListView myList;
MyAdapter adapter;
private List<String> list = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initList();
myList = (MyListView)findViewById(R.id.myList);
//传入接口,并实现相应的方法
myList.setonDeleteListener(new onDeleteListener() {
@Override
//根据回调传回来的item索引删除相应的行
public void onDelete(int index) {
list.remove(index);
adapter.notifyDataSetChanged();
}
});
adapter = new MyAdapter(this, 0, list);
myList.setAdapter(adapter);
}
private void initList() {
list.clear();
list.add("item 1");
list.add("item 2");
list.add("item 3");
list.add("item 4");
list.add("item 5");
list.add("item 6");
list.add("item 7");
list.add("item 8");
list.add("item 9");
list.add("item 10");
list.add("item 11");
list.add("item 12");
list.add("item 13");
list.add("item 14");
list.add("item 15");
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
if(item.getItemId() == R.id.reLoad)
{
initList();
adapter.notifyDataSetChanged();
}
return true;
}
}