zoukankan      html  css  js  c++  java
  • 自己定义滑动删除item的ListView。

    首先继承创建继承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);
    				}
    			});
    			//(从当前页面可见的開始)获取一行的布局
    			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;
    	}
    }
    





  • 相关阅读:
    一分钟搞懂列式与行式数据库(转)
    docker daemon 配置文件
    Docker-删除untagged docker images
    全栈JavaScript之路(十三)了解 ElementTraversal 规范
    static, readonly, const
    Timer与AlarmManager的差别
    计算客 (人人都有极客精神)爆力
    nginx 配置web 虚拟文件夹 而且codeIgniter,thinkphp 重定向url 地址
    单例模式之 懒汉模式普通版
    POJ 3468 A Simple Problem with Integers 【树状数组】
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/6752305.html
Copyright © 2011-2022 走看看