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的更多相关文章

  1. 【Android UI设计与开发】第03期:引导界面(三)仿微信引导界面以及动画效果

    基于前两篇比较简单的实例做铺垫之后,这一篇我们来实现一个稍微复杂一点的引导界面的效果,当然也只是稍微复杂了一点,对于会的人来说当然还是so easy!正所谓会者不难,难者不会,大概说的就是这个意思了吧 ...

  2. android开发学习 ------- 仿QQ侧滑效果的实现

    需要做一个仿QQ侧滑删除的一个效果: 一开始是毫无头绪,百度找思路,找到  https://blog.csdn.net/xiaxiazaizai01/article/details/53036994  ...

  3. Android高仿qq及微信底部菜单的几种实现方式

    最近项目没那么忙,想着开发app的话,有很多都是重复,既然是重复的,那就没有必要每次都去写,所以就想着写一个app通用的基本框架,这里说的框架不是什么MVC,MVP,MVVM这种,而是app开发的通用 ...

  4. wing带你玩转自定义view系列(2) 简单模仿qq未读消息去除效果

    上一篇介绍了贝塞尔曲线的简单应用 仿360内存清理效果 这一篇带来一个  两条贝塞尔曲线的应用 : 仿qq未读消息去除效果. 转载请注明出处:http://blog.csdn.net/wingicho ...

  5. Fragment,仿QQ空间

    转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/9023451          在今天的这篇文章当中,我依然会以实战加理论结合 ...

  6. Android仿QQ窗口的抖动的动画效果

    就是仿照QQ窗口的抖动效果,在项目的res下创建anim文件夹,再创建两个xml文件:cycle.xml  . myanim.xml   cycle.xml  :   <?xml version ...

  7. Android -- 自定义ViewGroup+贝塞尔+属性动画实现仿QQ点赞效果

    1,昨天我们写了篇简单的贝塞尔曲线的应用,今天和大家一起写一个QQ名片上常用的给别人点赞的效果,实现效果图如下: 红心的图片比较丑,见谅见谅(哈哈哈哈哈哈).... 2,实现的思路和原理 从上面的效果 ...

  8. android 自定义scrollview 仿QQ空间效果 下拉伸缩顶部图片,上拉回弹 上拉滚动顶部title 颜色渐变

    首先要知道  自定义scrollview 仿QQ效果 下拉伸缩放大顶部图片 的原理是监听ontouch事件,在MotionEvent.ACTION_MOVE事件时候,使用不同倍数的系数,重置布局位置[ ...

  9. 安卓仿QQ红包领取详情界面动画

    为了能清楚的看到这个效果,本人不惜几次花费重金给众群叼发放红包,来查看红包领取详情界面的动画效果,QQ效果如图: 图中我们可以看到,动画处的头像和文字是一起的,即同时并且是整体,注意,是整体进行缩放的 ...

随机推荐

  1. 迟到的 WPF 学习 —— 入门

    之所以说"迟到的",是因为我太晚才开始学习 WPF 了,之前 WPF 刚发布的时候有过粗浅了解,那时的 WPF 还非常简陋,VS 提供的内置控件十分匮乏,让我这样的非常依赖 Win ...

  2. 如何将 Area 中的 Controller 放到独立的程序集?

    目录 背景如何将 Area 中的 Controller 放到独立的程序集?备注 背景返回目录 本文假设您已经熟悉了 ASP.NET MVC 的常规开发方式.执行模型和关键扩展点,这里主要说一下如何使用 ...

  3. SQLSERVER数据库自动备份工具SQLBackupAndFTP(功能全面)

    挺好用的SQLSERVER数据库自动备份工具SQLBackupAndFTP(功能全面) 这个工具主要就是自动备份数据库,一键还原数据库,发送备份数据库日志报告到邮箱,自动压缩备份好的数据库 定期执行数 ...

  4. 用c#实现与飞环语音卡的交互

    现在很多企业都采用freeswitch搭建的软交换来实现通话,主要优势成本低吞吐量大,但是语音卡的通话质量还是瑞胜一筹. 去年有机会在朋友公司里帮忙开发与软交换交互的上层服务及接口,在开发过程中稍微研 ...

  5. 单一职责原则SRP

    定义: There should nerver be more then one reason for a class to change. 优点: 1.类的复杂性降低,实现什么职责都有清晰明确的定义 ...

  6. 一步一步深入spring(6)--使用基于XML配置的spring实现的AOP

    上节我们提到了使用基于注解实现的AOP,这节我们将用基于xml配置的方式来实现的AOP. 1.首先建立一个类,作为切面类,这个类主要用来实现注解中各种通知要实现的方法. package com.yan ...

  7. C#中WindowsForm常见控件的运用

    C#中WindowsForm常见控件的运用 -- 1.button(曹操,贡天子以令不臣): 属性;text:我们经常可以看见将按钮命名为“登入”,在其属性面板里面编辑text即可:如下图:      ...

  8. java自动生成略缩图

    当你要做一个图库的项目时,对图片大小.像素的控制是首先需要解决的难题. 本篇文章,在前辈的经验基础上,分别对单图生成略缩图和批量生成略缩图做个小结. 一.单图生成略缩图 单图经过重新绘制,生成新的图片 ...

  9. OpenRisc-34-ORPSoC跑eCos实验

    引言 ORPSoC目前支持好几种OS,除了前面一直介绍的linux,还支持eCos,eCos是RTOS,如果你的系统对时间的要求比较高,那eCos会是一个不错的选择. 本小节就简单介绍一下,在ORPS ...

  10. iOS 指南针的制作 附带源码

    iOS  指南针的制作  附带源码 代码下载地址: http://vdisk.weibo.com/s/HK4yE   http://pan.baidu.com/share/link?shareid=7 ...