• 高仿微信实现左滑显示删除button功能


    在实际项目中删除列表中的某一项是很常见的功能。传统的做法能够使用长按监听器等,而如今流行的做法是左滑弹出删除button,微信,QQ等都是这么做的,以下做一个演示样例,代码例如以下:

    主页面MainActivity:代码比較简单常规

    package com.home.testslideview;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.widget.ListView;
    
    import com.home.textslideview.R;
    
    public class MainActivity extends Activity {
    
    	private ListView listView;
    
    	private List<NewInfoBean> list = new ArrayList<NewInfoBean>();
    
    	// 适配器
    	private SlideAdapter adapter;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
    		initView();
    		initData();
    		setAdapter();
    	}
    
    	/**
    	 * 初始化页面控件
    	 */
    	private void initView() {
    		listView = (ListView) findViewById(R.id.main_lv);
    	}
    
    	/**
    	 * 初始化数据
    	 */
    	private void initData() {
    		list.add(new NewInfoBean("这是測试内容1"));
    		list.add(new NewInfoBean("这是測试内容2"));
    		list.add(new NewInfoBean("这是測试内容3"));
    		list.add(new NewInfoBean("这是測试内容4"));
    		list.add(new NewInfoBean("这是測试内容5"));
    		list.add(new NewInfoBean("这是測试内容6"));
    		list.add(new NewInfoBean("这是測试内容7"));
    		list.add(new NewInfoBean("这是測试内容8"));
    		list.add(new NewInfoBean("这是測试内容9"));
    		list.add(new NewInfoBean("这是測试内容10"));
    	}
    
    	/**
    	 * 设置适配器
    	 */
    	private void setAdapter() {
    		if (adapter == null) {
    			adapter = new SlideAdapter(this, list);
    			listView.setAdapter(adapter);
    		} else {
    			adapter.setList(list);
    			adapter.notifyDataSetChanged();
    		}
    	}
    
    }
    

    实体类NewInfoBean:详细项目中由自定义:

    package com.home.testslideview;
    
    public class NewInfoBean {
    	public SlideView slideView;
    
    	private String content;
    
    	public SlideView getSlideView() {
    		return slideView;
    	}
    
    	public void setSlideView(SlideView slideView) {
    		this.slideView = slideView;
    	}
    
    	public String getContent() {
    		return content;
    	}
    
    	public void setContent(String content) {
    		this.content = content;
    	}
    
    	public NewInfoBean() {
    		super();
    	}
    
    	public NewInfoBean(String content) {
    		super();
    		this.content = content;
    	}
    
    }
    
    适配器SlideAdapter:也比較简单

    package com.home.testslideview;
    
    import java.util.List;
    
    import android.content.Context;
    import android.util.SparseArray;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.TextView;
    
    import com.home.testslideview.SlideView.OnSlideListener;
    import com.home.textslideview.R;
    
    public class SlideAdapter extends BaseAdapter implements OnSlideListener,
    		OnClickListener {
    
    	private LayoutInflater inflater;
    
    	private List<NewInfoBean> list;
    
    	private Context context;
    
    	public SlideAdapter(Context context, List<NewInfoBean> list) {
    		if (inflater == null) {
    			inflater = LayoutInflater.from(context);
    		}
    		this.list = list;
    		this.context = context;
    	}
    
    	@Override
    	public int getCount() {
    		return list.size();
    	}
    
    	@Override
    	public Object getItem(int position) {
    		return list.get(position);
    	}
    
    	@Override
    	public long getItemId(int position) {
    		return position;
    	}
    
    	@Override
    	public View getView(int position, View convertView, ViewGroup arg2) {
    
    		SlideView slideView = (SlideView) convertView;
    		NewInfoBean bean = list.get(position);
    		if (slideView == null) {
    			slideView = new SlideView(context);
    			slideView.setOnSlideListener(this);
    		}
    
    		// 设置内容
    		TextView contentText = getAdapterView(slideView,
    				R.id.slideview_tv_content, position);
    		contentText.setText(bean.getContent());
    
    		// 删除button
    		TextView delText = getAdapterView(slideView, R.id.slideview_tv_del,
    				position);
    		delText.setOnClickListener(this);
    
    		bean.slideView = slideView;
    		bean.slideView.shrink();
    
    		return slideView;
    	}
    
    	@SuppressWarnings("unchecked")
    	public <T extends View> T getAdapterView(View convertView, int id,
    			Object tag) {
    		SparseArray<View> viewHolder = null;
    		try {
    			if (convertView.getTag(R.id.view_holder) instanceof SparseArray<?>) {
    				viewHolder = (SparseArray<View>) convertView
    						.getTag(R.id.view_holder);
    			}
    		} catch (ClassCastException e) {
    		}
    		if (viewHolder == null) {
    			viewHolder = new SparseArray<View>();
    			convertView.setTag(R.id.view_holder, viewHolder);
    			convertView.setTag(R.id.order_id, tag);
    		}
    		View childView = viewHolder.get(id);
    		if (childView == null) {
    			childView = convertView.findViewById(id);
    			childView.setTag(tag);
    			viewHolder.put(id, childView);
    		}
    		return (T) childView;
    	}
    
    	public List<NewInfoBean> getList() {
    		return list;
    	}
    
    	public void setList(List<NewInfoBean> list) {
    		this.list = list;
    	}
    
    	@Override
    	public void onSlide(View view, int status) {
    	}
    
    	@Override
    	public void onClick(View v) {
    		switch (v.getId()) {
    		case R.id.slideview_tv_del:
    			int position = (Integer) v.getTag();
    			list.remove(position);
    			notifyDataSetChanged();
    			break;
    
    		default:
    			break;
    		}
    	}
    
    }
    
    比較关键的两个类:

    自己定义的ListView:SlideListView

    package com.home.testslideview;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.ListView;
    
    public class SlideListView extends ListView {
    
    	private SlideView itemView;
    
    	public SlideListView(Context context) {
    		super(context);
    	}
    
    	public SlideListView(Context context, AttributeSet attrs) {
    		super(context, attrs);
    	}
    
    	public void shrinkListItem(int position) {
    		View item = getChildAt(position);
    		if (item != null) {
    			try {
    				((SlideView) item).shrink();
    			} catch (ClassCastException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    
    	@Override
    	public boolean onTouchEvent(MotionEvent event) {
    		switch (event.getAction()) {
    		case MotionEvent.ACTION_DOWN: {
    			int x = (int) event.getX();
    			int y = (int) event.getY();
    			int position = pointToPosition(x, y);
    			if (position != INVALID_POSITION) {
    				NewInfoBean data = (NewInfoBean) getItemAtPosition(position);
    				itemView = data.slideView;
    			}
    		}
    		default:
    			break;
    		}
    
    		if (itemView != null) {
    			itemView.onRequireTouchEvent(event);
    		}
    
    		return super.onTouchEvent(event);
    	}
    
    }
    


    自己定义的ListView中的每一行控件:SlideView(借鉴网上的一个演示样例):

    package com.home.testslideview;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.util.TypedValue;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.LinearLayout;
    import android.widget.Scroller;
    
    import com.home.textslideview.R;
    
    public class SlideView extends LinearLayout {
    
    	private static final String TAG = SlideView.class.getSimpleName();
    
    	private Context mContext;
    	private Scroller mScroller;
    	private OnSlideListener mOnSlideListener;
    
    	private int mHolderWidth = 80;
    
    	private int mLastX = 0;
    	private int mLastY = 0;
    	private static final int TAN = 2;
    
    	private LayoutInflater inflater;
    
    	public interface OnSlideListener {
    		public static final int SLIDE_STATUS_OFF = 0;
    		public static final int SLIDE_STATUS_START_SCROLL = 1;
    		public static final int SLIDE_STATUS_ON = 2;
    
    		/**
    		 * @param view
    		 *            current SlideView
    		 * @param status
    		 *            SLIDE_STATUS_ON or SLIDE_STATUS_OFF
    		 */
    		public void onSlide(View view, int status);
    	}
    
    	public SlideView(Context context) {
    		super(context);
    		initView();
    	}
    
    	public SlideView(Context context, AttributeSet attrs) {
    		super(context, attrs);
    		initView();
    	}
    
    	private void initView() {
    		mContext = getContext();
    		if (inflater == null) {
    			inflater = LayoutInflater.from(mContext);
    		}
    		mScroller = new Scroller(mContext);
    
    		setOrientation(LinearLayout.HORIZONTAL);
    		View.inflate(mContext, R.layout.slide_view_merge, this);
    		mHolderWidth = Math.round(TypedValue.applyDimension(
    				TypedValue.COMPLEX_UNIT_DIP, mHolderWidth, getResources()
    						.getDisplayMetrics()));
    	}
    
    	public void setOnSlideListener(OnSlideListener onSlideListener) {
    		mOnSlideListener = onSlideListener;
    	}
    
    	public void shrink() {
    		if (getScrollX() != 0) {
    			this.smoothScrollTo(0, 0);
    		}
    	}
    
    	public void onRequireTouchEvent(MotionEvent event) {
    		int x = (int) event.getX();
    		int y = (int) event.getY();
    		int scrollX = getScrollX();
    		Log.d(TAG, "x=" + x + "  y=" + y);
    
    		switch (event.getAction()) {
    		case MotionEvent.ACTION_DOWN: {
    			if (!mScroller.isFinished()) {
    				mScroller.abortAnimation();
    			}
    			if (mOnSlideListener != null) {
    				mOnSlideListener.onSlide(this,
    						OnSlideListener.SLIDE_STATUS_START_SCROLL);
    			}
    			break;
    		}
    		case MotionEvent.ACTION_MOVE: {
    			int deltaX = x - mLastX;
    			int deltaY = y - mLastY;
    			if (Math.abs(deltaX) < Math.abs(deltaY) * TAN) {
    				break;
    			}
    
    			int newScrollX = scrollX - deltaX;
    			if (deltaX != 0) {
    				if (newScrollX < 0) {
    					newScrollX = 0;
    				} else if (newScrollX > mHolderWidth) {
    					newScrollX = mHolderWidth;
    				}
    				this.scrollTo(newScrollX, 0);
    			}
    			break;
    		}
    		case MotionEvent.ACTION_UP: {
    			int newScrollX = 0;
    			if (scrollX - mHolderWidth * 0.75 > 0) {
    				newScrollX = mHolderWidth;
    			}
    			this.smoothScrollTo(newScrollX, 0);
    			if (mOnSlideListener != null) {
    				mOnSlideListener.onSlide(this,
    						newScrollX == 0 ?

    OnSlideListener.SLIDE_STATUS_OFF : OnSlideListener.SLIDE_STATUS_ON); } break; } default: break; } mLastX = x; mLastY = y; } private void smoothScrollTo(int destX, int destY) { // 缓慢滚动到指定位置 int scrollX = getScrollX(); int delta = destX - scrollX; mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 3); invalidate(); } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } } }


    main.xml:

    <?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.home.testslideview.SlideListView
            android:id="@+id/main_lv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:cacheColorHint="#00000000"
            android:fadingEdge="none"
            android:listSelector="#00000000"
            android:scrollbars="none" />
    
    </LinearLayout>
    

    slide_view_merge.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <merge xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >
    
        <LinearLayout
            android:id="@+id/slideview_layout_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center_vertical"
            android:gravity="center_vertical"
            android:orientation="horizontal" >
            
            <TextView 
                android:id="@+id/slideview_tv_content"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="内容部分"/>
    
        </LinearLayout>
    
        <LinearLayout
            android:id="@+id/view_layout_del"
            android:layout_width="80dp"
            android:layout_height="match_parent"
            android:layout_gravity="center_vertical"
            android:layout_toRightOf="@id/slideview_layout_content"
            android:clickable="true"
            android:gravity="center_vertical"
            android:orientation="horizontal" >
    
            <TextView
                android:id="@+id/slideview_tv_del"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:layout_marginBottom="2dp"
                android:gravity="center"
                android:padding="15dp"
                android:text="删除"/>
    
        </LinearLayout>
    
    </merge>

    源代码下载:http://download.csdn.net/detail/u010142437/8855289

  • 相关阅读:
    《C#并发编程经典实例》学习笔记—2.4 等待一组任务完成
    Captcha服务(后续2)— 改造Captcha服务之Asp.Net Core项目中如何集成TypeScript
    VS Code调试.Net Core版Hello World
    Visual Studio Code 语言设置
    Captcha服务(后续1)
    css——格式
    作业 5/13
    css选择器
    作业 5/12
    前端——表格标签,表单标签,css
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7209983.html
Copyright © 2020-2023  润新知