程序员人生 网站导航

自定义滑动删除item的ListView。

栏目:互联网时间:2014-11-12 08:20:57

首先继承创建继承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; } }





------分隔线----------------------------
------分隔线----------------------------

最新技术推荐