├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ └── nineoldandroids-2.4.0.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── listviewdeletedemo │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ ├── com.util │ │ │ ├── ZQListView.java │ │ │ └── ZQView.java │ │ └── com │ │ │ └── listviewdeletedemo │ │ │ ├── ActivityExpandableListViewDelete.java │ │ │ ├── ActivityListViewDelete.java │ │ │ ├── FrontViewToMove.java │ │ │ ├── MainActivity.java │ │ │ ├── MyElvAdapter.java │ │ │ ├── OnClickDeleteListenter.java │ │ │ └── UserInfo.java │ └── res │ │ ├── drawable │ │ └── holder_bg.xml │ │ ├── layout │ │ ├── activity_expandablelistview.xml │ │ ├── activity_listview.xml │ │ ├── activity_main.xml │ │ ├── delete_view.xml │ │ ├── item1.xml │ │ ├── item2.xml │ │ └── list_item.xml │ │ ├── mipmap-hdpi │ │ ├── del_icon_normal.png │ │ ├── ic_launcher.png │ │ └── ssdk_oks_classic_qq.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── listviewdeletedemo │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 1.8 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

本案例主要实现了ListViewExpandableListView的侧滑删除操作功能

2 |

效果图:

3 |

               

4 | 5 |

注:更新修复侧滑删除报错。

6 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.listviewdeletedemo" 9 | minSdkVersion 15 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(include: ['*.jar'], dir: 'libs') 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.3.0' 26 | compile files('libs/nineoldandroids-2.4.0.jar') 27 | } 28 | -------------------------------------------------------------------------------- /app/libs/nineoldandroids-2.4.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DickyQie/android-list-control/91db2eceaea8ee4389919967f447335ca29582e8/app/libs/nineoldandroids-2.4.0.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Android\SDK/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/listviewdeletedemo/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.listviewdeletedemo; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/java/com.util/ZQListView.java: -------------------------------------------------------------------------------- 1 | package com.util; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.MotionEvent; 6 | import android.widget.ListView; 7 | 8 | /**** 9 | * 10 | * 自定义ListView控件 11 | * 12 | * @author zhangqie 13 | * 14 | */ 15 | public class ZQListView extends ListView { 16 | 17 | private static final String TAG = "SilderListView"; 18 | 19 | private ZQView mFocusedItemView; 20 | 21 | float mX = 0; 22 | float mY = 0; 23 | private int mPosition = -1; 24 | boolean isSlider = false; 25 | 26 | public ZQListView(Context context) { 27 | super(context); 28 | } 29 | 30 | public ZQListView(Context context, AttributeSet attrs) { 31 | super(context, attrs); 32 | } 33 | 34 | public ZQListView(Context context, AttributeSet attrs, int defStyle) { 35 | super(context, attrs, defStyle); 36 | } 37 | 38 | @Override 39 | public boolean onTouchEvent(MotionEvent event) { 40 | float x = event.getX(); 41 | float y = event.getY(); 42 | switch (event.getAction()) { 43 | case MotionEvent.ACTION_DOWN: 44 | isSlider = false; 45 | mX = x; 46 | mY = y; 47 | int position = pointToPosition((int) x, (int) y); 48 | if (mPosition != position) { 49 | mPosition = position; 50 | if (mFocusedItemView != null) { 51 | mFocusedItemView.reset(); 52 | } 53 | } 54 | break; 55 | case MotionEvent.ACTION_MOVE: 56 | if (mPosition != -1) { 57 | if (Math.abs(mY - y) < 30 && Math.abs(mX - x) > 20) { 58 | int first = this.getFirstVisiblePosition(); 59 | int index = mPosition - first; 60 | mFocusedItemView = (ZQView) getChildAt(index); 61 | mFocusedItemView.onTouchEvent(event); 62 | isSlider = true; 63 | return true; 64 | } 65 | } 66 | break; 67 | case MotionEvent.ACTION_UP: 68 | if (isSlider) { 69 | isSlider = false; 70 | if (mFocusedItemView != null) { 71 | mFocusedItemView.adjust(mX - x > 0); 72 | return true; 73 | } 74 | } 75 | break; 76 | } 77 | return super.onTouchEvent(event); 78 | } 79 | } -------------------------------------------------------------------------------- /app/src/main/java/com.util/ZQView.java: -------------------------------------------------------------------------------- 1 | package com.util; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | import android.util.AttributeSet; 6 | import android.util.TypedValue; 7 | import android.view.MotionEvent; 8 | import android.view.View; 9 | import android.widget.LinearLayout; 10 | import android.widget.Scroller; 11 | 12 | import com.listviewdeletedemo.R; 13 | 14 | 15 | /**** 16 | * 17 | *侧滑布局设计 18 | * 19 | * @author zhangqie 20 | * 21 | */ 22 | public class ZQView extends LinearLayout { 23 | private static final String TAG = "SlideView"; 24 | private static final int TAN = 2; 25 | private int mHolderWidth = 120; 26 | private float mLastX = 0; 27 | private float mLastY = 0; 28 | private Context mContext; 29 | private LinearLayout mViewContent; 30 | private Scroller mScroller; 31 | 32 | public ZQView(Context context, Resources resources) { 33 | super(context); 34 | initView(); 35 | } 36 | 37 | public ZQView(Context context) { 38 | super(context); 39 | initView(); 40 | } 41 | 42 | public ZQView(Context context, AttributeSet attrs) { 43 | super(context, attrs); 44 | initView(); 45 | } 46 | 47 | private void initView() { 48 | setOrientation(LinearLayout.HORIZONTAL); 49 | mContext = getContext(); 50 | mScroller = new Scroller(mContext); 51 | View.inflate(mContext, R.layout.delete_view, this); 52 | mViewContent = (LinearLayout) findViewById(R.id.view_content); 53 | mHolderWidth = Math.round(TypedValue.applyDimension( 54 | TypedValue.COMPLEX_UNIT_DIP, mHolderWidth, getResources() 55 | .getDisplayMetrics())); 56 | } 57 | 58 | public void setContentView(View view) { 59 | mViewContent.addView(view); 60 | } 61 | 62 | public void shrink() { 63 | int offset = getScrollX(); 64 | if (offset == 0) { 65 | return; 66 | } 67 | scrollTo(0, 0); 68 | } 69 | 70 | public void reset() { 71 | int offset = getScrollX(); 72 | if (offset == 0) { 73 | return; 74 | } 75 | smoothScrollTo(0, 0); 76 | } 77 | 78 | public void adjust(boolean left) { 79 | int offset = getScrollX(); 80 | if (offset == 0) { 81 | return; 82 | } 83 | if (offset < 20) { 84 | this.smoothScrollTo(0, 0); 85 | } else if (offset < mHolderWidth - 20) { 86 | if (left) { 87 | this.smoothScrollTo(mHolderWidth, 0); 88 | } else { 89 | this.smoothScrollTo(0, 0); 90 | } 91 | } else { 92 | this.smoothScrollTo(mHolderWidth, 0); 93 | } 94 | } 95 | 96 | @Override 97 | public boolean onTouchEvent(MotionEvent event) { 98 | switch (event.getAction()) { 99 | case MotionEvent.ACTION_MOVE: 100 | float x = event.getX(); 101 | float y = event.getY(); 102 | float deltaX = x - mLastX; 103 | float delatY = y - mLastY; 104 | mLastX = x; 105 | mLastY = y; 106 | if (Math.abs(deltaX) < Math.abs(delatY) * TAN) { 107 | break; 108 | } 109 | if (deltaX != 0) { 110 | float newScrollX = getScrollX() - deltaX; 111 | if (newScrollX < 0) { 112 | newScrollX = 0; 113 | } else if (newScrollX > mHolderWidth) { 114 | newScrollX = mHolderWidth; 115 | } 116 | this.scrollTo((int) newScrollX, 0); 117 | } 118 | break; 119 | } 120 | return super.onTouchEvent(event); 121 | } 122 | 123 | private void smoothScrollTo(int destX, int destY) { 124 | int scrollX = getScrollX(); 125 | int delta = destX - scrollX; 126 | mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 3); 127 | invalidate(); 128 | } 129 | 130 | @Override 131 | public void computeScroll() { 132 | if (mScroller.computeScrollOffset()) { 133 | scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); 134 | postInvalidate(); 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /app/src/main/java/com/listviewdeletedemo/ActivityExpandableListViewDelete.java: -------------------------------------------------------------------------------- 1 | package com.listviewdeletedemo; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.View; 8 | import android.widget.ExpandableListView; 9 | import android.widget.Toast; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | 15 | /***** 16 | * ExpandableListView侧滑删除 17 | * 18 | * @author zhangqie 19 | */ 20 | 21 | public class ActivityExpandableListViewDelete extends AppCompatActivity{ 22 | 23 | private List list =new ArrayList<>(); 24 | private Context context; 25 | private ExpandableListView myElv; 26 | private MyElvAdapter myAdapter; 27 | 28 | @Override 29 | protected void onCreate(@Nullable Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_expandablelistview); 32 | context = this; 33 | initData(); 34 | initView(); 35 | } 36 | 37 | public void initView() { 38 | myElv = (ExpandableListView) findViewById(R.id.expandablelist); 39 | myAdapter = new MyElvAdapter(context, myElv,list); 40 | myElv.setAdapter(myAdapter); 41 | myElv.setGroupIndicator(null); 42 | int intgroupCount = myElv.getCount(); 43 | //全部展开 44 | for (int i=0; i show1(){ 71 | List list =new ArrayList<>(); 72 | UserInfo.Data data=new UserInfo().new Data(); 73 | data.setName("歆语博客"); 74 | data.setAge("18"); 75 | data.setCheckBox(false); 76 | list.add(data); 77 | return list; 78 | } 79 | 80 | private List show2(){ 81 | List list =new ArrayList<>(); 82 | UserInfo.Data data=new UserInfo().new Data(); 83 | data.setName("切切歆语"); 84 | data.setAge("19"); 85 | data.setCheckBox(false); 86 | list.add(data); 87 | UserInfo.Data data1=new UserInfo().new Data(); 88 | data1.setName("胡歌"); 89 | data1.setAge("36"); 90 | data1.setCheckBox(false); 91 | list.add(data1); 92 | return list; 93 | } 94 | 95 | 96 | 97 | } 98 | -------------------------------------------------------------------------------- /app/src/main/java/com/listviewdeletedemo/ActivityListViewDelete.java: -------------------------------------------------------------------------------- 1 | package com.listviewdeletedemo; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import android.app.Activity; 7 | import android.os.Bundle; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.View.OnClickListener; 11 | import android.view.ViewGroup; 12 | import android.widget.AdapterView; 13 | import android.widget.AdapterView.OnItemClickListener; 14 | import android.widget.BaseAdapter; 15 | import android.widget.ImageView; 16 | import android.widget.TextView; 17 | import android.widget.Toast; 18 | 19 | import com.util.ZQListView; 20 | import com.util.ZQView; 21 | 22 | 23 | /***** 24 | * 25 | * ListView侧滑删除 26 | * 27 | * @author zhangqie 28 | * 29 | */ 30 | public class ActivityListViewDelete extends Activity implements 31 | OnItemClickListener, OnClickListener { 32 | 33 | 34 | private ZQListView mListView; 35 | 36 | private List mMessageItems = new ArrayList(); 37 | 38 | 39 | @Override 40 | protected void onCreate(Bundle savedInstanceState) { 41 | super.onCreate(savedInstanceState); 42 | setContentView(R.layout.activity_listview); 43 | initView(); 44 | } 45 | 46 | 47 | private void initView() { 48 | mListView = (ZQListView) findViewById(R.id.list); 49 | for (int i = 0; i < 12; i++) { 50 | MessageItem item = new MessageItem(); 51 | item.title = "标题" + (i + 1); 52 | item.msg = "消息" + (i + 1); 53 | item.time = "2016-6-1" + i; 54 | mMessageItems.add(item); 55 | } 56 | mListView.setAdapter(new SlideAdapter()); 57 | mListView.setOnItemClickListener(this); 58 | } 59 | 60 | private class SlideAdapter extends BaseAdapter { 61 | 62 | private LayoutInflater mInflater; 63 | 64 | SlideAdapter() { 65 | super(); 66 | mInflater = getLayoutInflater(); 67 | } 68 | 69 | @Override 70 | public int getCount() { 71 | return mMessageItems.size(); 72 | } 73 | 74 | @Override 75 | public Object getItem(int position) { 76 | return mMessageItems.get(position); 77 | } 78 | 79 | @Override 80 | public long getItemId(int position) { 81 | return position; 82 | } 83 | 84 | @Override 85 | public View getView(int position, View convertView, ViewGroup parent) { 86 | ViewHolder holder; 87 | 88 | ZQView slideView = (ZQView) convertView; 89 | if (slideView == null) { 90 | View itemView = mInflater.inflate(R.layout.list_item, null); 91 | 92 | slideView = new ZQView(ActivityListViewDelete.this); 93 | slideView.setContentView(itemView); 94 | holder = new ViewHolder(slideView); 95 | slideView.setTag(holder); 96 | } else { 97 | holder = (ViewHolder) slideView.getTag(); 98 | } 99 | MessageItem item = mMessageItems.get(position); 100 | slideView.shrink(); 101 | holder.title.setText(item.title); 102 | holder.time.setText(item.time); 103 | holder.deleteHolder.setOnClickListener(ActivityListViewDelete.this); 104 | 105 | return slideView; 106 | } 107 | 108 | } 109 | 110 | public class MessageItem { 111 | public String title; 112 | public String msg; 113 | public String time; 114 | } 115 | 116 | private static class ViewHolder { 117 | public ImageView icon; 118 | public TextView title; 119 | public TextView time; 120 | public ViewGroup deleteHolder; 121 | 122 | ViewHolder(View view) { 123 | icon = (ImageView) view.findViewById(R.id.icon); 124 | title = (TextView) view.findViewById(R.id.title); 125 | time = (TextView) view.findViewById(R.id.time); 126 | deleteHolder = (ViewGroup) view.findViewById(R.id.holder); 127 | } 128 | } 129 | 130 | @Override 131 | public void onItemClick(AdapterView parent, View view, int position, 132 | long id) { 133 | Toast.makeText(this, "onItemClick position=" + position, Toast.LENGTH_LONG).show(); 134 | 135 | } 136 | 137 | @Override 138 | public void onClick(View v) { 139 | if (v.getId() == R.id.holder) { 140 | Toast.makeText(this, "删除操作", Toast.LENGTH_LONG).show(); 141 | 142 | } 143 | } 144 | 145 | } 146 | -------------------------------------------------------------------------------- /app/src/main/java/com/listviewdeletedemo/FrontViewToMove.java: -------------------------------------------------------------------------------- 1 | package com.listviewdeletedemo; 2 | 3 | import android.support.v4.view.MotionEventCompat; 4 | import android.view.MotionEvent; 5 | import android.view.View; 6 | import android.view.View.OnTouchListener; 7 | import android.widget.ListView; 8 | 9 | import com.nineoldandroids.animation.Animator; 10 | import com.nineoldandroids.animation.AnimatorListenerAdapter; 11 | 12 | import static com.nineoldandroids.view.ViewHelper.setTranslationX; 13 | import static com.nineoldandroids.view.ViewPropertyAnimator.animate; 14 | 15 | /** 16 | * @author 17 | * 18 | */ 19 | 20 | public class FrontViewToMove { 21 | 22 | private View frontView;// 所要滑动的视图 23 | private int downX;// 手指按下时的x坐标 24 | private boolean hasMoved = false;// 判断视图是否被移动 25 | private int xToMove = 100;// 视图所要被移动的距离,默认200 26 | private ListView listView;// 如果所需移动的视图为ListView或其子类的item项,传入视图容器,限制其上下滚动 27 | 28 | /** 29 | * @param frontView 30 | * 所要滑动的视图 31 | */ 32 | public FrontViewToMove(View frontView) { 33 | this.frontView = frontView; 34 | moveListener(); 35 | } 36 | 37 | /** 38 | * @param frontView 39 | * 所要滑动的视图 40 | * @param xToMove 41 | * 视图所要被移动的距离 42 | */ 43 | public FrontViewToMove(View frontView, int xToMove) { 44 | this.frontView = frontView; 45 | this.xToMove = xToMove; 46 | moveListener(); 47 | } 48 | 49 | /** 50 | * @param frontView 51 | * 所要滑动的视图 52 | * @param listView 53 | * 所要滑动的视图的容器 54 | */ 55 | public FrontViewToMove(View frontView, ListView listView) { 56 | this.frontView = frontView; 57 | this.listView = listView; 58 | moveListener(); 59 | } 60 | 61 | /** 62 | * @param frontView 63 | * 所要滑动的视图 64 | * @param listView 65 | * 所要滑动的视图的容器 66 | * @param xToMove 67 | * 视图所要被移动的距离 68 | */ 69 | public FrontViewToMove(View frontView, ListView listView, int xToMove) { 70 | this.frontView = frontView; 71 | this.listView = listView; 72 | this.xToMove = xToMove; 73 | moveListener(); 74 | } 75 | 76 | /** 77 | * 设置frontView的OnTouch监听,使其产生滑动的动画效果 78 | */ 79 | public void moveListener() { 80 | frontView.setOnTouchListener(new OnTouchListener() { 81 | 82 | @Override 83 | public boolean onTouch(View view, MotionEvent motionEvent) { 84 | 85 | switch (MotionEventCompat.getActionMasked(motionEvent)) { 86 | case MotionEvent.ACTION_DOWN: { 87 | 88 | downX = (int) motionEvent.getRawX(); 89 | if (hasMoved) { 90 | downX = downX + xToMove; 91 | } else { 92 | view.onTouchEvent(motionEvent);// 当视图没有被移动,返回事件,使点击事件可用。 93 | } 94 | return true; 95 | } 96 | 97 | case MotionEvent.ACTION_UP: { 98 | 99 | float deltaX = motionEvent.getRawX() - downX; 100 | boolean swap = false; 101 | 102 | if ((deltaX > -xToMove / 2 && hasMoved) 103 | || (deltaX < -xToMove && !hasMoved)) { 104 | swap = true; 105 | } 106 | 107 | if (swap) { 108 | if (!hasMoved) { 109 | generateRevealAnimate(frontView, -xToMove); 110 | hasMoved = true; 111 | } else { 112 | generateRevealAnimate(frontView, 0); 113 | hasMoved = false; 114 | } 115 | } else { 116 | if (hasMoved) { 117 | generateRevealAnimate(frontView, -xToMove); 118 | } else { 119 | generateRevealAnimate(frontView, 0); 120 | } 121 | } 122 | 123 | break; 124 | } 125 | 126 | case MotionEvent.ACTION_MOVE: { 127 | float deltaX = motionEvent.getRawX() - downX; 128 | 129 | MotionEvent cancelEvent = MotionEvent.obtain(motionEvent); 130 | 131 | cancelEvent.setAction(MotionEvent.ACTION_CANCEL 132 | | (motionEvent.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT)); 133 | 134 | if (deltaX < -10) { 135 | view.onTouchEvent(cancelEvent);// 当滑动时清空该视图的点击事件 136 | if (null != listView) {// 当视图滑动时限制listView的上下滚动 137 | listView.requestDisallowInterceptTouchEvent(false); 138 | listView.onTouchEvent(cancelEvent); 139 | } 140 | } 141 | 142 | if (!(deltaX > 0 && !hasMoved)) { 143 | setTranslationX(frontView, deltaX); 144 | } 145 | return true; 146 | } 147 | } 148 | return false; 149 | } 150 | }); 151 | 152 | } 153 | 154 | /** 155 | * @param view 156 | * 所要移动的视图 157 | * @param deltaX 158 | * 最终移动的距离 159 | */ 160 | public void generateRevealAnimate(final View view, float deltaX) { 161 | int moveTo = 0; 162 | moveTo = (int) deltaX; 163 | animate(view).translationX(moveTo).setDuration(10) 164 | .setListener(new AnimatorListenerAdapter() { 165 | @Override 166 | public void onAnimationEnd(Animator animation) { 167 | 168 | } 169 | }); 170 | } 171 | 172 | } 173 | -------------------------------------------------------------------------------- /app/src/main/java/com/listviewdeletedemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.listviewdeletedemo; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.os.Bundle; 7 | import android.view.View; 8 | 9 | /*** 10 | * 11 | * ListView+ExpandableListView 侧滑删除 12 | * 13 | * @author zhangqie 14 | * 15 | */ 16 | public class MainActivity extends Activity implements View.OnClickListener { 17 | 18 | private Intent intent; 19 | @Override 20 | protected void onCreate(Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | setContentView(R.layout.activity_main); 23 | findViewById(R.id.button1).setOnClickListener(this); 24 | findViewById(R.id.button2).setOnClickListener(this); 25 | } 26 | 27 | @Override 28 | public void onClick(View v) { 29 | // TODO Auto-generated method stub 30 | switch (v.getId()) { 31 | case R.id.button1: 32 | intent=new Intent(MainActivity.this,ActivityListViewDelete.class); 33 | break; 34 | case R.id.button2: 35 | intent=new Intent(MainActivity.this,ActivityExpandableListViewDelete.class); 36 | break; 37 | 38 | default: 39 | break; 40 | } 41 | startActivity(intent); 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/listviewdeletedemo/MyElvAdapter.java: -------------------------------------------------------------------------------- 1 | package com.listviewdeletedemo; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.View.OnClickListener; 8 | import android.view.ViewGroup; 9 | import android.widget.BaseExpandableListAdapter; 10 | import android.widget.Button; 11 | import android.widget.ListView; 12 | import android.widget.TextView; 13 | import android.widget.Toast; 14 | 15 | import java.util.List; 16 | 17 | public class MyElvAdapter extends BaseExpandableListAdapter { 18 | 19 | 20 | private Context context; 21 | private ListView listView; 22 | List list; 23 | 24 | public MyElvAdapter(Context context, ListView listView, List list) { 25 | super(); 26 | this.context = context; 27 | this.listView = listView; 28 | this.list=list; 29 | } 30 | 31 | @Override 32 | public Object getChild(int arg0, int arg1) { 33 | // TODO Auto-generated method stub 34 | return list.get(arg0).getDatas().get(arg1); 35 | } 36 | 37 | @Override 38 | public long getChildId(int arg0, int arg1) { 39 | // TODO Auto-generated method stub 40 | return 0; 41 | } 42 | 43 | @Override 44 | public View getChildView(final int groupPosition, final int position, 45 | boolean arg2, View convertView, ViewGroup parent) { 46 | 47 | final ViewHolder1 viewHolder1; 48 | if (convertView == null){ 49 | convertView = LayoutInflater.from(context).inflate(R.layout.item2, 50 | null); 51 | viewHolder1=new ViewHolder1(convertView); 52 | convertView.setTag(viewHolder1); 53 | 54 | }else { 55 | viewHolder1=(ViewHolder1)convertView.getTag(); 56 | } 57 | new FrontViewToMove(viewHolder1.frontView, listView,200); 58 | viewHolder1.button.setOnClickListener(new OnClickListener() { 59 | @Override 60 | public void onClick(View v) { 61 | //删除事件,回调接口传参数 62 | onClickDeleteListenter.onItemClick(v,groupPosition,position); 63 | new FrontViewToMove(viewHolder1.frontView, listView,200).generateRevealAnimate(viewHolder1.frontView,0); 64 | 65 | } 66 | }); 67 | viewHolder1.textView.setTextSize(20); 68 | viewHolder1.textView.setTextColor(Color.DKGRAY); 69 | viewHolder1.textView.setText(" " + list.get(groupPosition).getDatas().get(position).getName()); 70 | return convertView; 71 | } 72 | 73 | class ViewHolder1 { 74 | private TextView textView; 75 | private View frontView; 76 | private Button button; 77 | public ViewHolder1(View view){ 78 | textView= (TextView) view.findViewById(R.id.text); 79 | button = (Button) view.findViewById(R.id.btn_delete); 80 | frontView = view.findViewById(R.id.id_front); 81 | } 82 | } 83 | 84 | 85 | // 删除接口回调方法 86 | private OnClickDeleteListenter onClickDeleteListenter = null; 87 | public void setOnClickDeleteListenter(OnClickDeleteListenter listener) { 88 | this.onClickDeleteListenter = listener; 89 | } 90 | 91 | @Override 92 | public int getChildrenCount(int arg0) { 93 | // TODO Auto-generated method stub 94 | return (list!=null && list.size()>0)? list.get(arg0).getDatas().size() : 0; 95 | } 96 | 97 | @Override 98 | public Object getGroup(int arg0) { 99 | // TODO Auto-generated method stub 100 | return list.get(arg0); 101 | } 102 | 103 | @Override 104 | public int getGroupCount() { 105 | // TODO Auto-generated method stub 106 | return (list!=null && list.size()>0) ? list.size() : 0; 107 | } 108 | 109 | @Override 110 | public long getGroupId(int arg0) { 111 | // TODO Auto-generated method stub 112 | return 0; 113 | } 114 | 115 | @Override 116 | public View getGroupView(final int groupPosition, boolean isExpanded, 117 | View convertView, ViewGroup parent) { 118 | final ViewHolder viewHolder; 119 | if (convertView ==null){ 120 | convertView = LayoutInflater.from(context).inflate(R.layout.item1,null); 121 | viewHolder =new ViewHolder(convertView); 122 | convertView.setTag(viewHolder); 123 | }else { 124 | viewHolder=(ViewHolder)convertView.getTag(); 125 | } 126 | viewHolder.textView.setText("条目 " + list.get(groupPosition).getId()); 127 | viewHolder.textView.setOnClickListener(new OnClickListener() { 128 | @Override 129 | public void onClick(View v) { 130 | Toast.makeText(context,"第一层点击操作",Toast.LENGTH_LONG).show(); 131 | } 132 | }); 133 | return convertView; 134 | } 135 | 136 | @Override 137 | public boolean hasStableIds() { 138 | // TODO Auto-generated method stub 139 | return false; 140 | } 141 | 142 | @Override 143 | public boolean isChildSelectable(int arg0, int arg1) { 144 | // TODO Auto-generated method stub 145 | return false; 146 | } 147 | 148 | class ViewHolder { 149 | TextView textView; 150 | public ViewHolder(View view){ 151 | textView= (TextView) view.findViewById(R.id.name); 152 | } 153 | } 154 | 155 | } 156 | -------------------------------------------------------------------------------- /app/src/main/java/com/listviewdeletedemo/OnClickDeleteListenter.java: -------------------------------------------------------------------------------- 1 | package com.listviewdeletedemo; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * Created by zhanqgie on 2017/6/23. 7 | */ 8 | 9 | public interface OnClickDeleteListenter { 10 | 11 | void onItemClick(View view, int onePosition, int position); 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/listviewdeletedemo/UserInfo.java: -------------------------------------------------------------------------------- 1 | package com.listviewdeletedemo; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by zhangqie on 2017/8/23. 7 | */ 8 | 9 | public class UserInfo { 10 | 11 | private int id; 12 | private List datas; 13 | private boolean checkBox; 14 | 15 | public int getId() { 16 | return id; 17 | } 18 | 19 | public void setId(int id) { 20 | this.id = id; 21 | } 22 | 23 | public void setDatas(List datas) { 24 | this.datas = datas; 25 | } 26 | public List getDatas() { 27 | return datas; 28 | } 29 | 30 | public void setCheckBox(boolean checkBox) { 31 | this.checkBox = checkBox; 32 | } 33 | public boolean isCheckBox() { 34 | return checkBox; 35 | } 36 | class Data{ 37 | String name; 38 | String age; 39 | boolean checkBox; 40 | 41 | public boolean isCheckBox() { 42 | return checkBox; 43 | } 44 | 45 | public void setCheckBox(boolean checkBox) { 46 | this.checkBox = checkBox; 47 | } 48 | 49 | public String getName() { 50 | return name; 51 | } 52 | 53 | public void setName(String name) { 54 | this.name = name; 55 | } 56 | 57 | public String getAge() { 58 | return age; 59 | } 60 | 61 | public void setAge(String age) { 62 | this.age = age; 63 | } 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/holder_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_expandablelistview.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_listview.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 |