您的位置:首页 > 其它

ViewDragHelper实现仿qq列表滑动删除

2016-07-03 16:04 344 查看

实现过程概述

实现qq列表侧滑删除,核心还是ViewDragHelper的实现。

关于ViewDragHelper的基础用法,我在另外一篇博客ViewDragHelper简介中已经介绍过了。如果不是特别了解ViewDragHelper,可以看看。

需要实现的ViewGroup是LinearLayout,基本的思路是:LinearLayout中的两个布局都是水平排列。列表的内容布局填充整个列表,菜单布局在屏幕之外,是看不到的。向左滑动内容布局,菜单布局也随之滑动。这时就可以看到屏幕外的菜单布局了。

代码

自定义控件SwipeLayout

public 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);

}

}


效果图



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  qq 博客 布局