本案例主要实现了ListView和ExpandableListView的侧滑删除操作功能
效果图:
代码:
自定义ListView public class ZQListView extends ListView { private static final String TAG ="ZQListView "; private ZQView mFocusedItemView; float mX = 0; float mY = 0; private int mPosition = -1; boolean isSlider = false; public ZQListView(Contextcontext) { super(context); } public ZQListView(Contextcontext, AttributeSet attrs) { super(context,attrs); } public ZQListView(Contextcontext, AttributeSet attrs,int defStyle) { super(context,attrs, defStyle); } @Override public boolean onTouchEvent(MotionEvent event) { float x =event.getX(); float y =event.getY(); switch(event.getAction()) { case MotionEvent.ACTION_DOWN: isSlider = false; mX = x; mY = y; int position= pointToPosition((int) x, (int) y); if (mPosition !=position) { mPosition =position; if (mFocusedItemView !=null) { mFocusedItemView.reset(); } } break; case MotionEvent.ACTION_MOVE: if (mPosition != -1) { if (Math.abs(mY - y) <30 && Math.abs(mX - x) > 20) { int first =this.getFirstVisiblePosition(); int index =mPosition - first; mFocusedItemView =(ZQView) getChildAt(index); mFocusedItemView.onTouchEvent(event); isSlider = true; return true; } } break; case MotionEvent.ACTION_UP: if (isSlider) { isSlider = false; if (mFocusedItemView !=null) { mFocusedItemView.adjust(mX - x >0); return true; } } break; } return super.onTouchEvent(event); } }
侧滑布局类 public class ZQView extends LinearLayout { private static final String TAG ="SlideView"; private static final int TAN = 2; private int mHolderWidth = 120; private float mLastX = 0; private float mLastY = 0; private Context mContext; private LinearLayout mViewContent; private Scroller mScroller; public ZQView(Contextcontext, Resources resources) { super(context); initView(); } public ZQView(Contextcontext) { super(context); initView(); } public ZQView(Contextcontext, AttributeSet attrs) { super(context,attrs); initView(); } private void initView() { setOrientation(LinearLayout.HORIZONTAL); mContext = getContext(); mScroller = new Scroller(mContext); View.inflate(mContext,R.layout.delete_view,this); mViewContent = (LinearLayout)findViewById(R.id.view_content); mHolderWidth = Math.round(TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP,mHolderWidth,getResources() .getDisplayMetrics())); } public void setContentView(View view) { mViewContent.addView(view); } public void shrink(){ int offset =getScrollX(); if (offset== 0) { return; } scrollTo(0, 0); } public void reset() { int offset =getScrollX(); if (offset== 0) { return; } smoothScrollTo(0, 0); } public void adjust(boolean left) { int offset =getScrollX(); if (offset== 0) { return; } if (offset< 20) { this.smoothScrollTo(0,0); } else if (offset< mHolderWidth - 20) { if (left) { this.smoothScrollTo(mHolderWidth, 0); } else { this.smoothScrollTo(0,0); } } else { this.smoothScrollTo(mHolderWidth, 0); } } @Override public boolean onTouchEvent(MotionEvent event) { switch(event.getAction()) { case MotionEvent.ACTION_MOVE: float x =event.getX(); float y =event.getY(); float deltaX =x -mLastX; float delatY =y -mLastY; mLastX = x; mLastY = y; if (Math.abs(deltaX)< Math.abs(delatY) *TAN) { break; } if (deltaX!= 0) { float newScrollX = getScrollX() - deltaX; if(newScrollX < 0) { newScrollX = 0; } else if(newScrollX > mHolderWidth) { newScrollX = mHolderWidth; } this.scrollTo((int)newScrollX, 0); } break; } return super.onTouchEvent(event); } 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(); } }
布局文件
delete.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"> <LinearLayout android:id="@+id/view_content" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> </LinearLayout> <RelativeLayout android:id="@+id/holder" android:layout_width="120dp" android:layout_height="match_parent" android:background="@drawable/holder_bg" android:clickable="true"> <TextView android:id="@+id/delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:drawableLeft="@drawable/del_icon_normal" android:gravity="center" android:text="删除" android:textColor="@color/floralwhite"/> </RelativeLayout> </merge> listview.xml <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.util.ZQListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#fff4f7f9" android:cacheColorHint="#00000000" android:divider="#6c6c6c" android:dividerHeight="1dp" android:drawSelectorOnTop="false" android:listSelector="#00000000" android:scrollbars="none" android:scrollingCache="false"/> </LinearLayout>
Activity和适配器类 public class ActivityListViewDelete extends Activity implements OnItemClickListener, OnClickListener { private ZQListView mListView; private List<MessageItem> mMessageItems = new ArrayList<ActivityListViewDelete.MessageItem>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } public static int[] Img = {R.drawable.ssdk_oks_classic_qq, R.drawable.ssdk_oks_classic_qzone, R.drawable.ssdk_oks_classic_shortmessage, R.drawable.ssdk_oks_classic_sinaweibo, R.drawable.ssdk_oks_classic_tencentweibo, R.drawable.ssdk_oks_classic_vkontakte, R.drawable.ssdk_oks_classic_wechat, R.drawable.ssdk_oks_classic_wechatfavorite, R.drawable.ssdk_oks_classic_wechatmoments, R.drawable.ssdk_oks_classic_yixinmoments }; private void initView() { mListView = (ZQListView)findViewById(R.id.list); int length = Img.length; for (int i = 0; i< length; i++) { MessageItem item = new MessageItem(); item.iconRes = Img[i]; item.title = "标题" + (i + 1); item.msg = "消息" + (i + 1); item.time = "2016-6-1" + i; mMessageItems.add(item); } mListView.setAdapter(newSlideAdapter()); mListView.setOnItemClickListener(this); } private class SlideAdapter extends BaseAdapter { private LayoutInflater mInflater; SlideAdapter() { super(); mInflater =getLayoutInflater(); } @Override public int getCount() { return mMessageItems.size(); } @Override public Object getItem(int position) { return mMessageItems.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroupparent) { ViewHolder holder; ZQView slideView = (ZQView)convertView; if(slideView == null) { View itemView = mInflater.inflate(R.layout.list_item,null); slideView = newZQView(ActivityListViewDelete.this); slideView.setContentView(itemView); holder = newViewHolder(slideView); slideView.setTag(holder); } else { holder = (ViewHolder) slideView.getTag(); } MessageItem item = mMessageItems.get(position); slideView.shrink(); holder.icon.setImageResource(item.iconRes); holder.title.setText(item.title); holder.time.setText(item.time); holder.deleteHolder.setOnClickListener(ActivityListViewDelete.this); return slideView; } } public class MessageItem { public int iconRes; public String title; public String msg; public String time; } private static class ViewHolder { public ImageViewicon; public TextView title; public TextView time; public ViewGroup deleteHolder; ViewHolder(View view) { icon =(ImageView) view.findViewById(R.id.icon); title =(TextView) view.findViewById(R.id.title); time =(TextView) view.findViewById(R.id.time); deleteHolder =(ViewGroup) view.findViewById(R.id.holder); } } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(this,"onItemClickposition=" + position, 1).show(); } @Override public void onClick(View v) { if(v.getId() == R.id.holder) { Toast.makeText(this,"删除操作",1).show(); } } }
此代码是ListView的侧滑删除操作,ExpandableListView未贴出来,下载代码即可,两个都有。
源码下载:
(注:ExpandableListView的侧滑删除有点错误)
Eclipse下载:http://download.csdn.net/detail/dickyqie/9627652
AndroidStudio下载:https://github.com/DickyQie/ListViewExpandableListViewDelete
相关推荐
Android ListView和ExpandableListView的侧滑删除操作 实现了ListView和ExpandableListView的左滑出现删除的功能。能在实体机和虚拟机上运行,无广告,实现效果和截图一样,但点击expand按钮,在地点进行侧滑时会...
在Android开发中,ListView和ExpandableListView是两个常用的视图组件,用于展示大量数据列表。在用户交互体验日益重要的今天,下拉刷新功能已经成为移动应用的标准特性,它允许用户通过在顶部滑动来获取更新的数据...
本示例“ListView+ExpandableListView实现侧滑删除”着重讲解如何在这两种列表中添加滑动手势来触发删除操作,提升用户体验。侧滑删除是一种常见的移动应用交互设计,用户只需向左滑动列表项,就能看到并执行删除...
总之,"expandableListview侧滑删除demo"是一个很好的实践案例,它展示了如何将流行的侧滑删除功能集成到ExpandableListView中,为用户提供更直观、便捷的操作方式。通过学习和研究这个示例,开发者能够进一步提升...
然后把侧滑删除也揉了进去。 最后请各位注意ListView的上拉,下拉和侧滑都是经过测试可用的。但是ExpandableListView我只用到了上拉加载更多,并未用过下拉和侧滑,下拉应该没问题,但是侧滑恐怕不敢保证,使用的...
对于这个“二级listview”项目,描述中提到“相信只要你会用listview肯定也会用expandablelistView”,这暗示了实现的基本思路可能与`ListView`类似,只是需要处理额外的展开和折叠逻辑。`ListView`通常只需要处理...
综上所述,结合`ExpandableListView`的层级展示能力和侧滑删除的交互设计,可以创建出功能强大的、用户友好的应用界面。在实际开发中,灵活运用这些知识和技术,可以帮助你构建更加高效、易用的Android应用程序。
10. 滑动删除:借鉴Material Design的交互方式,可以实现侧滑删除列表项,提高操作便捷性。 通过学习这些例子,开发者不仅可以掌握ListView的基本用法,还能理解如何根据实际需求进行定制和优化,从而在Android应用...
同时,还可以实现自定义的滑动事件监听,比如侧滑删除。 4. **下拉刷新和上拉加载更多**:在列表顶部添加一个刷新控件,让用户可以手动触发数据更新,这通常用到SwipeRefreshLayout。而当用户滚动到底部时自动加载...
此时,我们就需要用到`ExpandableListView`,它是一个增强版的ListView,支持展开和折叠子项,能够很好地处理二级或更深层次的菜单。 `ExpandableListView`的特性: 1. **层级结构**:与ListView不同,...
在SDK 4.2.2环境下,我们可以利用ExpandableListView或自定义ListView来实现这一功能。 首先,我们需要理解ExpandableListView。这个组件允许我们创建层级结构的数据展示,每个父项可以展开显示其子项。在这个案例...
7. **ListView的其他功能**:除了基本的显示数据外,ListView还支持分组(ExpandableListView)、下拉刷新(SwipeRefreshLayout)、侧滑删除(SwipeToDismiss)等功能,可以根据需求进行扩展。 8. **数据刷新**:当...
当然,ListView的功能远不止这些,还可以结合其他组件和动画效果,如LoadMore加载更多、ExpandableListView可展开子项等,以满足更复杂的界面需求。对于初学者来说,理解ListView的工作原理和使用方法是Android开发...
SwipeRefreshLayout可以实现下拉刷新,而SwipeMenuListView则支持侧滑菜单,用户可以通过左右滑动ListView的项来触发不同的操作,比如删除或更多选项。这需要自定义ListView的Item视图,并添加手势检测逻辑。 4. **...
这个功能通常通过监听ListView的滑动手势来实现,当用户在ListView的某一项上进行滑动时,我们会检测滑动的方向和距离,当达到一定阈值时触发删除操作。这一过程涉及到的主要技术点包括: 1. **手势检测**:Android...
- **ExpandableListView** 是ListView的扩展,支持分组和展开/折叠功能。每个分组可以包含多个子项,用户可以通过点击分组头来展开或收起子项。 2. **Adapter机制**: - Android中的Adapter是连接数据源和UI控件...
5. 添加侧滑栏:你可以使用ExpandableListView或者SwipeRefreshLayout等组件来实现A-Z侧滑栏。当用户点击某个首字母时,更新ListView显示对应首字母的数据。 6. 更新ListView:在用户点击侧滑栏的字母后,调用...
可以使用`ExpandableListView`和自定义`GroupIndicator`来实现分组动画。 9. **加载更多动画** 在滚动到底部时,加载更多数据可以伴随加载指示器动画,如转动的菊花加载图标。这可以通过`ProgressBar`和`Animator`...
首先,SlideExpandableListView基于Android的ExpandableListView进行改造,增加了侧滑手势来触发子项的展开和折叠,这一特性使得用户可以通过简单的滑动操作来查看或隐藏子列表,提高了操作的便捷性。在源码中,我们...
实现类似QQ滑动出现可操作项的功能,...这里使用的ListView演示,还可以是GridView,ExpandableListView。 最关键的代码部分,ListView适配器布局: <?xml version=1.0 encoding=utf-8?> <com.daimajia.s