自定义控件--滑动删除
来源:互联网 发布:淘宝买iphone8靠谱吗 编辑:程序博客网 时间:2024/06/05 07:38
1.应用场景:替换item长按删除
2.实现逻辑:
a.自定义一个可以滑动的布局;
4.2 SwipeLayout.java
4.3 MainActivity.java
5. 布局文件
5.2 layout_content.xml
5.3 layout_delete.xml
5.4 list_item.xml
6.运行效果图:
2.实现逻辑:
a.自定义一个可以滑动的布局;
b.将该布局放入adapter的布局中,需要处理滑动冲突;
3.目录结构:
4.java代码:
4.1 SwipeLayoutManager.java
package com.weizh.swipedelete.manager;import com.weizh.swipedelete.widget.SwipeLayout;/** * Created by weizh_000 on 2016/8/24. */public class SwipeLayoutManager { private static SwipeLayoutManager swipeLayoutManager = new SwipeLayoutManager(); private SwipeLayout currentLayout; public static SwipeLayoutManager getInstance(){ return swipeLayoutManager; } //记录当前打开的是哪一个swipeLayout public void setCurrentLayout(SwipeLayout swipeLayout){ this.currentLayout = swipeLayout; } //清除记录 public void clearCurrentLayout(){ currentLayout=null; } //关闭记录中的swipelayout public void closeSwipeLayout(){ if (currentLayout!=null){ currentLayout.close(); } } //判断是否可以左右滑动swipelayout public boolean isShouldOpen(SwipeLayout swipeLayout){ if (currentLayout==null){ //说明无记录,可以打开 return true; }else { //说明有记录, //记录的是自己,可以左右滑动 //记录的是别的swipelayout,则不能滑动 return currentLayout==swipeLayout; } } public void resumeSwipeLayout() { if(currentLayout!=null){ currentLayout.resume(); } }}
4.2 SwipeLayout.java
package com.weizh.swipedelete.widget;import android.content.Context;import android.support.v4.view.ViewCompat;import android.support.v4.widget.ViewDragHelper;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.FrameLayout;import com.weizh.swipedelete.manager.SwipeLayoutManager;/** * Created by weizh_000 on 2016/8/23. */public class SwipeLayout extends FrameLayout { private View contentView;//item内容区域的view private View deleteView;//delete区域的view private int contentWidth;//内容区域的宽度 private int deleteWidth;//delete区域的宽度 private int deleteHeight;//delete区域的高度 private ViewDragHelper dragHelper; private float downX; private float downY; private SwipeState currentState;//当前状态是默认是关闭状态 public SwipeLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public SwipeLayout(Context context) { super(context); init(); } public SwipeLayout(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { dragHelper = ViewDragHelper.create(this, callback); currentState = SwipeState.Close; } enum SwipeState { Open, Close; } @Override protected void onFinishInflate() { super.onFinishInflate(); contentView = getChildAt(0); deleteView = getChildAt(1); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); contentWidth = contentView.getMeasuredWidth(); deleteWidth = deleteView.getMeasuredWidth(); deleteHeight = deleteView.getMeasuredHeight(); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { contentView.layout(0, 0, contentWidth, deleteHeight); deleteView.layout(contentView.getRight(), 0, contentView.getRight() + deleteWidth, deleteHeight); } private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() { @Override public boolean tryCaptureView(View child, int pointerId) { return child == contentView || child == deleteView; } @Override public int getViewHorizontalDragRange(View child) { return deleteWidth; } @Override public int clampViewPositionHorizontal(View child, int left, int dx) { if (child == contentView) { if (left < -deleteWidth) left = -deleteWidth; if (left > 0) left = 0; } else if (child == deleteView) { if (left < contentWidth - deleteWidth) left = contentWidth - deleteWidth; if (left > contentWidth) left = contentWidth; } return left; } @Override public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {// super.onViewPositionChanged(changedView, left, top, dx, dy); //做伴随移动 if (changedView == contentView) { deleteView.layout(deleteView.getLeft() + dx, 0, deleteView.getRight() + dx, deleteHeight); } else if (changedView == deleteView) { contentView.layout(contentView.getLeft() + dx, 0, contentView.getRight() + dx, deleteHeight); } //判断开关逻辑 if (contentView.getLeft() == 0) { //说明state应更改为关闭 currentState = SwipeState.Close; //清空已打开swipelayout记录 SwipeLayoutManager.getInstance().clearCurrentLayout(); } else if (contentView.getLeft() == -deleteWidth) { //说明state应更改为打开 currentState = SwipeState.Open; //记录已打开swipelayout SwipeLayoutManager.getInstance().setCurrentLayout(SwipeLayout.this); } } @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { super.onViewReleased(releasedChild, xvel, yvel); if (contentView.getLeft() < -deleteWidth / 2) { //应该打开 open(); } else { //应该关闭 close(); } } }; //打开swipelayout private void open() { dragHelper.smoothSlideViewTo(contentView, -deleteWidth, 0); ViewCompat.postInvalidateOnAnimation(SwipeLayout.this); } //关闭swipelayout public void close() { dragHelper.smoothSlideViewTo(contentView, 0, 0); ViewCompat.postInvalidateOnAnimation(SwipeLayout.this); }//恢复swipelayout至初始位置 public void resume() { contentView.layout(0,0,contentWidth,deleteHeight); deleteView.layout(contentView.getRight(),0,contentView.getRight()+deleteWidth,deleteHeight); } @Override public void computeScroll() { if (dragHelper.continueSettling(true)) { ViewCompat.postInvalidateOnAnimation(SwipeLayout.this); } } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { //让dragHelper决定是否拦截事件 boolean b = dragHelper.shouldInterceptTouchEvent(ev); if (!SwipeLayoutManager.getInstance().isShouldOpen(this)) { b = true;//将事件传递给onTouchEvent //当前swipelayout不能滑动,先关闭swipelayout SwipeLayoutManager.getInstance().closeSwipeLayout(); //请求父类不要拦截事件 requestDisallowInterceptTouchEvent(true); } return b; } @Override public boolean onTouchEvent(MotionEvent event) { //如果有已打开的swipelayout,则先关闭 if (!SwipeLayoutManager.getInstance().isShouldOpen(this)) { //消费掉触摸事件 return true; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = event.getX(); downY = event.getY(); break; case MotionEvent.ACTION_MOVE: float moveX = event.getX(); float moveY = event.getY(); float delatX = moveX - downX; float delatY = moveY - downY; if (Math.abs(delatX) > Math.abs(delatY)) { //禁止listview拦截事件 requestDisallowInterceptTouchEvent(true); } downX = moveX; downY = moveY; break; case MotionEvent.ACTION_UP: break; } //交给dragHelper处理触摸事件 dragHelper.processTouchEvent(event); return true; }}
4.3 MainActivity.java
package com.weizh.swipedelete;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.view.ViewGroup;import android.widget.AbsListView;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.TextView;import com.weizh.swipedelete.manager.SwipeLayoutManager;import java.util.ArrayList;public class MainActivity extends AppCompatActivity { private ListView lvListView; private ArrayList<String> strings; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); } private void initData() { //1.设置数据 strings = new ArrayList<>(); for (int i=0;i<30;i++) { strings.add("name - "+i); } lvListView.setAdapter(new MyAdapter()); lvListView.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView absListView, int scrollState) { if(scrollState==SCROLL_STATE_TOUCH_SCROLL){ //垂直滑动则需要关闭已经打开的swipelayout SwipeLayoutManager.getInstance().closeSwipeLayout(); } } @Override public void onScroll(AbsListView absListView, int i, int i1, int i2) { } }); } private void initView() { lvListView=(ListView) findViewById(R.id.lv_list); } class MyAdapter extends BaseAdapter{ @Override public int getCount() { return strings.size(); } @Override public Object getItem(int i) { return null; } @Override public long getItemId(int i) { return 0; } @Override public View getView(final int position, View convertView, ViewGroup viewGroup) { ViewHolder holder=null; if (convertView==null){ convertView=View.inflate(getApplicationContext(),R.layout.list_item,null); holder=new ViewHolder(); holder.tvName= (TextView) convertView.findViewById(R.id.tv_name); holder.tvDelete= (TextView) convertView.findViewById(R.id.tv_delete); convertView.setTag(holder); }else { holder= (ViewHolder) convertView.getTag(); } holder.tvName.setText(strings.get(position)); //给delete textview设置点击事件 holder.tvDelete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //恢复swipelayout至初始位置 SwipeLayoutManager.getInstance().resumeSwipeLayout(); //清除swipelayout打开记录 SwipeLayoutManager.getInstance().clearCurrentLayout(); strings.remove(position);//从集合中移除对应的条目数据 notifyDataSetChanged();//通知数据更新 } }); return convertView; } } class ViewHolder{ public TextView tvName; public TextView tvDelete; }}
5. 布局文件
5.1 activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.weizh.swipedelete.MainActivity"> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/lv_list" ></ListView></LinearLayout>
5.2 layout_content.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="80dp" android:paddingLeft="15dp" android:background="#33666666" android:gravity="center_vertical" android:orientation="horizontal" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/head_1"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#99000000" android:id="@+id/tv_name" android:layout_marginLeft="10dp" android:textSize="20sp" android:text="名称"/></LinearLayout>
5.3 layout_delete.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="80dp" android:orientation="horizontal" > <TextView android:layout_width="100dp" android:layout_height="match_parent" android:textSize="18sp" android:textColor="#ffffff" android:gravity="center" android:background="#aa000000" android:text="Call"/> <TextView android:layout_width="100dp" android:layout_height="match_parent" android:textSize="18sp" android:textColor="#ffffff" android:id="@+id/tv_delete" android:gravity="center" android:background="#eeff0000" android:text="Delete"/></LinearLayout>
5.4 list_item.xml
<?xml version="1.0" encoding="utf-8"?><com.weizh.swipedelete.widget.SwipeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/sd_delete" android:layout_width="match_parent" android:layout_height="wrap_content"> <include layout="@layout/layout_content" /> <include layout="@layout/layout_delete" /></com.weizh.swipedelete.widget.SwipeLayout>
6.运行效果图:
7.源码地址:https://github.com/Jszgw/SwipeDelete
0 0
- 自定义控件--滑动删除
- 自定义组合控件之滑动item+删除
- Android开发--自定义控件实现listview的滑动删除item
- android自定义控件SlidingButtonView实现类似QQ滑动删除效果
- Android自定义组合控件下拉刷以及滑动删除
- Android滑动删除控件
- 滑动删除--自定义ListView
- 左右滑动自定义控件
- 自定义控件--滑动按钮
- 自定义控件:滑动开关
- 滑动控件自定义使用
- 滑动控件自定义使用
- 自定义控件之滑动
- 自定义控件之滑动
- Android 结合滑动控件ListView滑动删除
- android自定义listview滑动删除
- 自定义view group2。滑动删除
- Android 自定义滑动控件相关
- “J.U.C”:CyclicBarrier (r)
- Android的强软弱虚引用的基本了解1
- USB hub 多usb接口重映射:udev 规则
- 大地测量海洋测量数据表格
- Shader第十三讲 Alpha混合
- 自定义控件--滑动删除
- TCP通信的三次握手和四次撒手的详细流程(顿悟)
- dts中会用到的MODULE_DEVICE_TABLE
- “J.U.C”:CountDownlatch (r)
- android:自定义温度计View
- greenplum安装
- CDISC SDTM MI domain学习笔记
- php 使用ajax文本框模糊查询
- “J.U.C”:Phaser (r)