ViewDragHelper实现仿qq列表滑动删除
2016-07-03 16:04
344 查看
实现过程概述
实现qq列表侧滑删除,核心还是ViewDragHelper的实现。关于ViewDragHelper的基础用法,我在另外一篇博客ViewDragHelper简介中已经介绍过了。如果不是特别了解ViewDragHelper,可以看看。
需要实现的ViewGroup是LinearLayout,基本的思路是:LinearLayout中的两个布局都是水平排列。列表的内容布局填充整个列表,菜单布局在屏幕之外,是看不到的。向左滑动内容布局,菜单布局也随之滑动。这时就可以看到屏幕外的菜单布局了。
代码
自定义控件SwipeLayoutpublic class SwipeLayout extends LinearLayout { private ViewDragHelper viewDragHelper; private View contentView; private View menuview; private int dragDistance; private int screenWidth; private Context context; public SwipeLayout(Context context) { this(context, null); } public SwipeLayout(Context context, AttributeSet attrs) { this(context, attrs, -1); } public SwipeLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context=context; init(); } @Override protected void onFinishInflate() { contentView = getChildAt(0); menuview = getChildAt(1); } void init(){ viewDragHelper = ViewDragHelper.create(this, new DragHelperCallback()); /** * 获取屏幕宽度 */ WindowManager wm=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); screenWidth=outMetrics.widthPixels; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); /** * 必须获得menuview的宽度。因为滑动结束后,menuview必须距离右边为dragDistance个像素长度才能显示完全, * 这里的距离计算,是以menuview左上角的为起点开始计算的。 * * */ dragDistance = menuview.getMeasuredWidth(); } private class DragHelperCallback extends ViewDragHelper.Callback { @Override public void onViewDragStateChanged(int state) { super.onViewDragStateChanged(state); Log.d("liang", "onViewDragStateChanged: "+state); } @Override public boolean tryCaptureView(View view, int i) { return view == contentView||view==menuview ; } @Override public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { /** * dx,dy描述的是偏移量 * 向左边滑动后,contentView随着滑动事件向左边移动。但是menuview是显示不出来的(初始状态menuview是在 * 屏幕之外的)。 * 所以要在滑动的同时,给menuview设置偏移量使其跟随contentView滑动并且刷新界面。 * */ super.onViewPositionChanged( changedView, left, top, dx, dy); if (changedView == contentView) { menuview.offsetLeftAndRight(dx); } else { contentView.offsetLeftAndRight(dx); } invalidate(); } @Override public int clampViewPositionHorizontal(View child, int left, int dx) { final int leftBound = getPaddingLeft(); final int minLeftBound = -leftBound - dragDistance; final int newLeft = Math.min(Math.max(minLeftBound, left), 0);//使其不能向右滑动 Log.d("liang", "clampViewPositionHorizontal: "+newLeft); return newLeft; } @Override public int getViewVerticalDragRange(View child) { return 0; } @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { /** * xvel,yvel表示速度 */ super.onViewReleased(releasedChild, xvel, yvel); if(contentView.getRight()<(screenWidth-30)){ viewDragHelper.smoothSlideViewTo(contentView, -dragDistance, 0); ViewCompat.postInvalidateOnAnimation(SwipeLayout.this); }else{ viewDragHelper.smoothSlideViewTo(contentView, 0, 0); ViewCompat.postInvalidateOnAnimation(SwipeLayout.this); } } } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if(viewDragHelper.shouldInterceptTouchEvent(ev)) { return true; } return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { viewDragHelper.processTouchEvent(event); return true; } @Override public void computeScroll() { super.computeScroll(); if(viewDragHelper.continueSettling(true)) { ViewCompat.postInvalidateOnAnimation(this); } } }
注释写得很全,就不一一解释了。需要说明的是:我在这里获取了当前屏幕的宽度,是为了在提高滑动过程中menuView响应事件的灵敏性。
2.listview的item布局文件:
<widget.SwipeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/line" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFFDFDFE" android:orientation="horizontal"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/fkq" /> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/image" android:layout_alignBottom="@+id/image" android:layout_toRightOf="@+id/image" android:layout_marginLeft="15dp" tools:ignore="RtlHardcoded"> <TextView android:id="@+id/type" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" android:textSize="23sp" android:textColor="@color/bright_foreground_material_light" /> <TextView android:id="@+id/content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="How are you?" android:textSize="24sp" android:textColor="#FF4535FF" android:layout_alignParentBottom="true" /> <TextView android:id="@+id/time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="yesterday" android:textSize="19sp" android:textColor="#FF7F7F80" android:layout_alignParentRight="true" android:padding="10dp" /> </RelativeLayout> </RelativeLayout> <LinearLayout android:layout_width="200dp" android:layout_height="match_parent" android:orientation="horizontal"> <TextView android:id="@+id/zhiding" android:layout_width="66.5dp" android:layout_height="match_parent" android:text="置顶" android:textColor="#FFF" android:textSize="17sp" android:gravity="center" android:background="#FFC6C6CC"/> <TextView android:id="@+id/biaojiweiyidu" android:layout_width="66.5dp" android:layout_height="match_parent" android:textColor="#FFF" android:textSize="17sp" android:text="已读" android:gravity="center" android:background="#FFFD9C01"/> <TextView android:id="@+id/delete" android:layout_width="66.5dp" android:layout_height="match_parent" android:textColor="#FFF" android:textSize="17sp" android:text="删除" android:gravity="center" android:background="#FFFD3A30" android:autoText="false" /> </LinearLayout> </widget.SwipeLayout>
这里面包含两个子布局,一个是内容布局,一个是菜单布局。内容布局填充整个item,而菜单布局是在屏幕之外的,不显示。
3.Activity的主布局:
<RelativeLayout xmlns: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" tools:context=".MainActivity"> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="none"> </ListView> </RelativeLayout>
4.listview的适配器及对应的javabean:
public class MyAdapter extends BaseAdapter { private Context context; private List<Chatter> datas; private LayoutInflater inflater; public MyAdapter(Context context, List<Chatter> datas) { this.context = context; this.datas = datas; inflater=LayoutInflater.from(context); } @Override public int getCount() { return datas.size(); } @Override public Object getItem(int i) { return datas.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int position, View covertView, ViewGroup viewGroup) { ViewHolder holder=null; if(covertView==null){ holder=new ViewHolder(); covertView=inflater.inflate(R.layout.item_list,null); holder.imageView=(ImageView)covertView.findViewById(R.id.image); holder.type=(TextView)covertView.findViewById(R.id.type); holder.content=(TextView)covertView.findViewById(R.id.content); holder.time=(TextView)covertView.findViewById(R.id.time); holder.zhhiding=(TextView)covertView.findViewById(R.id.zhiding); holder.biaojiweiyidu=(TextView)covertView.findViewById(R.id.biaojiweiyidu); holder.delete=(TextView)covertView.findViewById(R.id.delete); covertView.setTag(holder); } else { holder=(ViewHolder)covertView.getTag(); } holder.imageView.setImageBitmap(datas.get(position).getPicture()); holder.type.setText(datas.get(position).getType()); holder.content.setText(datas.get(position).getContent()); holder.time.setText(datas.get(position).getTime()); holder.biaojiweiyidu.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Toast.makeText(context, "标记为已读", Toast.LENGTH_SHORT).show(); } }); holder.delete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Toast.makeText(context,"已经删除",Toast.LENGTH_SHORT).show(); } }); holder.zhhiding.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Toast.makeText(context, "已经置顶", Toast.LENGTH_SHORT).show(); } }); return covertView; } class ViewHolder{ public ImageView imageView; public TextView type,content,time,zhhiding,biaojiweiyidu,delete; } }
public class Chatter { private Bitmap picture; private String type,content,time; public Chatter(Bitmap picture, String type, String content, String time) { this.picture = picture; this.type = type; this.content = content; this.time = time; } public Bitmap getPicture() { return picture; } public void setPicture(Bitmap picture) { this.picture = picture; } public String getTime() { return time; } public void setTime(String time) { this.time = time; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getType() { return type; } public void setType(String type) { this.type = type; } }
5.MainActivity
public class MainActivity extends Activity { private LinearLayout linearLayout; private TextView textView; private ListView listView; private List<Chatter> datas; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } void initView(){ listView=(ListView)findViewById(R.id.listView); datas=new ArrayList<>(); Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.fkq); Chatter chatter=new Chatter(bitmap,"好友","你好","昨天"); Chatter chatter1=new Chatter(bitmap,"好友","你在干什么","今天下午"); Chatter chatter2=new Chatter(bitmap,"朋友","hello","昨天"); Chatter chatter3=new Chatter(bitmap,"亲人","病好了吗","前天"); Chatter chatter4=new Chatter(bitmap,"老师","作业做完了吗","昨天"); Chatter chatter5=new Chatter(bitmap,"老师","今天不上课","今天"); Chatter chatter6=new Chatter(bitmap,"同学","去打球","子阿武"); Chatter chatter7=new Chatter(bitmap,"同学","去打球","子阿武"); Chatter chatter8=new Chatter(bitmap,"同学","去打球","子阿武"); datas.add(chatter); datas.add(chatter1); datas.add(chatter2); datas.add(chatter3); datas.add(chatter4); datas.add(chatter5); datas.add(chatter6); datas.add(chatter7); datas.add(chatter8); MyAdapter adapter=new MyAdapter(this,datas); listView.setAdapter(adapter); } }
效果图
相关文章推荐
- Android布局的小窍门?
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- Web布局连载——两栏固定布局(五)
- QQ商业化,如何实现从0到1的破局?
- 十年生死两茫茫,Linux QQ 突然复活!
- 新注册
- VB实现的《QQ美女找茬游戏》作弊器实例
- 路由器端QQ封堵方案
- 样式表CSS布局经验
- 四大漏洞入侵博客
- 在winform下实现左右布局多窗口界面的方法之续篇
- QQ输入法自动删除其它输入法的解决方法
- 让普通QQ号也能克隆QQ好友
- 基于ASP实现QQ在线查询功能
- VBS取QQ或TM自动登录代码并防止关闭的脚本
- css网页布局中注意的几个问题小结
- DL.DT.DD实现左右的布局简单例子第1/2页
- 使用CSS框架布局的缺点和优点小结
- div+CSS网页布局的意义与副作用原因小结第1/2页