首页 > 代码库 > 仿qq的条目抽屉动画效果_ViewDragHelper
仿qq的条目抽屉动画效果_ViewDragHelper
GitHub地址:
https://github.com/OOOOOldZhu/DrawerItemView
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;
public class SwipeLayout extends FrameLayout {
private View content;
private View delete;
ViewDragHelper dragHelper;
public SwipeLayout(Context context) {
this(context, null);
}
public SwipeLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SwipeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
//初始化ViewDragHelper
dragHelper = ViewDragHelper.create(this, callback);
}
//只有完成系统对xml文件完成最后标签的解析,才能获得子控件
@Override
protected void onFinishInflate() {
super.onFinishInflate();
content = getChildAt(0);
delete = getChildAt(1);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
content.layout(0, 0, content.getMeasuredWidth(),
content.getMeasuredHeight());
int L = content.getRight();
//content(右下角)的right(距原点的x距离)即为 delete控件的左上角的x坐标
delete.layout(L, 0, L + delete.getMeasuredWidth(),
delete.getMeasuredHeight());
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
//让helper处理拦截事件
boolean result = dragHelper.shouldInterceptTouchEvent(ev);
return result;
}
float downX,downY;
@Override
public boolean onTouchEvent(MotionEvent event) {
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 dx = moveX - downX;
float dy = moveY - downY;
//判断到底偏向于哪个方向
if(Math.abs(dx)>Math.abs(dy)){
//说明是偏向水平方向,那么就认为用户想滑动条目,此时应该让listview不要拦截
requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_UP:
break;
}
dragHelper.processTouchEvent(event);
return true;
}
// 回调方法
ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {
@Override
public boolean tryCaptureView(View child, int pointerId) {
return true;
}
@Override
public int getViewHorizontalDragRange(View child) {
return 1;
}
//修正子控件的位置坐标的方法
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
//限制content
if(child==content){
if(left>0){
left = 0;
}else if(left<-delete.getMeasuredWidth()){
left = -delete.getMeasuredWidth();
}
}else if(child==delete){
//限制delete
if(left>content.getMeasuredWidth()){
left = content.getMeasuredWidth();
}else if(left<(content.getMeasuredWidth()-
delete.getMeasuredWidth()))
{
left = (content.getMeasuredWidth()-
delete.getMeasuredWidth());
}
}
return left;
}
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
super.onViewPositionChanged(changedView, left, top, dx, dy);
//如果移动的是content,那么让delete伴随移动
if(changedView==content){
// int newLeft = delete.getLeft()+dx;
// delete.layout(newLeft,0,newLeft+delete.getMeasuredWidth(),delete.getMeasuredHeight());
ViewCompat.offsetLeftAndRight(delete,dx);
}else if(changedView==delete){
//让content进行伴随移动
ViewCompat.offsetLeftAndRight(content,dx);
}
//回调接口的方法
if(listener!=null){
if(content.getLeft()==0){
listener.onClose(SwipeLayout.this);
}else if(content.getLeft()==-delete.getMeasuredWidth()){
listener.onOpen(SwipeLayout.this);
}
}
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
super.onViewReleased(releasedChild, xvel, yvel);
if(content.getLeft()>-delete.getMeasuredWidth()/2){
//关闭抽屉
closeLayout();
}else {
//打开抽屉
openLayout();
}
}
};
/**
* 打开
*/
public void openLayout() {
dragHelper.smoothSlideViewTo(content,-delete.
getMeasuredWidth(),0);
ViewCompat.postInvalidateOnAnimation(this);
}
/**
* 关闭
*/
public void closeLayout() {
dragHelper.smoothSlideViewTo(content,0,0);
ViewCompat.postInvalidateOnAnimation(this);
}
@Override
public void computeScroll() {
super.computeScroll();
if(dragHelper.continueSettling(true)){
ViewCompat.postInvalidateOnAnimation(this);
}
}
private OnSwipeListener listener;
public void setOnSwipeListener(OnSwipeListener listener){
this.listener = listener;
}
public interface OnSwipeListener{
void onOpen(SwipeLayout currentLayout);
void onClose(SwipeLayout currentLayout);
}
}
MainActivity中:
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; 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 butterknife.Bind; import butterknife.ButterKnife; public class MainActivity extends AppCompatActivity { private ListView listview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listview = (ListView) findViewById(R.id.listview); listview.setAdapter(new MyAdapter()); //监听listview的滚动 listview.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if(openedLayout!=null){ openedLayout.closeLayout(); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); } SwipeLayout openedLayout;//用来记录打开的SwipeLayout class MyAdapter extends BaseAdapter implements SwipeLayout.OnSwipeListener{ @Override public int getCount() { return Constant.NAMES.length; } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { MyHolder myHolder = null; if(convertView==null){ convertView = View.inflate(parent.getContext(), R.layout.adapter_list, null); myHolder = new MyHolder(convertView); convertView.setTag(myHolder); }else { myHolder = (MyHolder) convertView.getTag(); } //绑定数据 myHolder.tvName.setText(Constant.NAMES[position]); //设置监听器 myHolder.swipeLayout.setOnSwipeListener(this); return convertView; } @Override public void onOpen(SwipeLayout currentLayout) { //应该关闭当前已经打开的 if(openedLayout!=null && openedLayout!=currentLayout){ openedLayout.closeLayout(); } openedLayout = currentLayout; } @Override public void onClose(SwipeLayout currentLayout) { if(openedLayout==currentLayout){ openedLayout = null; } } } static class MyHolder { @Bind(R.id.tv_name) TextView tvName; @Bind(R.id.tv_delete) TextView tvDelete; @Bind(R.id.swipeLayout) SwipeLayout swipeLayout; MyHolder(View view) { ButterKnife.bind(this, view); } } }
仿qq的条目抽屉动画效果_ViewDragHelper
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。