1. xml
    activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout    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"    android:orientation="vertical"    >    <com.guyulei.myqq50.DragLayout        android:background="@mipmap/bk"        android:id="@+id/dl_dragLayout"        android:layout_width="match_parent"        android:layout_height="match_parent">        <LinearLayout            android:orientation="vertical"            android:background="#f00"            android:layout_width="200dp"            android:layout_height="match_parent">            <RelativeLayout                android:background="#0ff"                android:layout_width="match_parent"                android:layout_height="150dp">                <ImageView                    android:layout_marginLeft="15dp"                    android:layout_centerVertical="true"                    android:src="@mipmap/qq4"                    android:layout_width="135dp"                    android:layout_height="135dp"/>            RelativeLayout>            <ListView                android:id="@+id/left_listView"                android:layout_width="match_parent"                android:layout_height="match_parent">            ListView>        LinearLayout>        <LinearLayout            android:orientation="vertical"            android:background="#0f0"            android:layout_width="match_parent"            android:layout_height="match_parent">            <RelativeLayout                android:background="#f0f"                android:layout_width="match_parent"                android:layout_height="88dp">                <ImageView                    android:id="@+id/iv_head"                    android:layout_marginLeft="15dp"                    android:layout_centerVertical="true"                    android:src="@mipmap/qq4"                    android:layout_width="77dp"                    android:layout_height="77dp"/>            RelativeLayout>            <ListView                android:id="@+id/main_listView"                android:layout_width="match_parent"                android:layout_height="match_parent">            ListView>        LinearLayout>    com.guyulei.myqq50.DragLayout>LinearLayout>

2.自定义view
public class DragLayout extends FrameLayout

package com.guyulei.myqq50;import android.content.Context;import android.graphics.Color;import android.graphics.PorterDuff;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;import android.widget.LinearLayout;/** * Created by Administrator on 2016/6/30 0030. * 1、为什么不继承 ViewGroup,因为继承 ViewGroup 需要重写 onMeasure()和实现 onLayout()方法,自己 * 实现子 view 的测量和摆放,在这里我们不需要自己去做测量和摆放,而 FrameLayout 已经对这两个方法进 * 行了具体实现,所以继承 FrameLayout 更加简单省事 * 2、为什么不继承 RelativeLayout,因为这里我们只需要层级关系,不需要相对关系,继承 RelativeLayout * 界面效果是一样的,但 RelativeLayout 对 FrameLayout 多了相对关系的计算,效率会低一些,所以选择继 * 承 FrameLayout */public class DragLayout extends FrameLayout {    private ViewDragHelper mViewDragHelper;    private LinearLayout   mLeftContent;    private LinearLayout   mMainContent;    private int            mWidth;    private int            mHeight;    private int            mRange;    private int mLeftWidth;    //状态值    public enum Status {        Open,        Close,        Draging;    }    //默认状态值    private Status status = Status.Close;    //监听对象声明    private OnUpdataDragStateListener mOnUpdataDragStateListener;    //对外接口    public interface OnUpdataDragStateListener {        void onOpen();        void onClose();        void onDragging(float percent);    }    //对外接口回调方法    public void setOnUpdataDragStateListener(OnUpdataDragStateListener onUpdataDragStateListener) {        this.mOnUpdataDragStateListener = onUpdataDragStateListener;    }    //串联构造方法    /**     * 我们可以通过串连三个构造方法的方式实现只调用一次 init()方法     * 这样无论是代码创建还是布局在 xml 中都能调用到我们的初始化代码     *     * @param context     */    //代码创建时调用    public DragLayout(Context context) {        this(context, null);    }    //布局在 xml 中,实例化时调用    public DragLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public DragLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        //初始化        //1.辅助类ViewDragHelper  forparent 2个拖拽控件的父控件 ,sensitivity子控件拖拽的敏感度        //callback:事件回调        mViewDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {            @Override            // tryCaptureView俘获; 夺取; 夺得(尝试夺取子控件)            //返回值代表 子控件 是否可以被夺取            public boolean tryCaptureView(View child, int pointerId) {                return true;            }            //可通过计算测量水平或者垂直方向拖拽的范围  返回>0即可            @Override            public int getViewHorizontalDragRange(View child) {                return mRange;            }            @Override            //clamp紧紧抓住; 紧夹住(紧抓着俘获的view(child)水平或者垂直移动位置)            //dx 变化量(移动的差值 newleft-oldleft)            public int clampViewPositionHorizontal(View child, int left, int dx) {                //dx累加  是  left                if (child == mMainContent) {                    //拖拽为主面板时                    left = fixleft(left);                }                return left;            }            @Override            //松手时  回调(Released释放)            public void onViewReleased(View releasedChild, float xvel, float yvel) {                // xvel水平方向上的速度 左为-    右为+                if (xvel == 0 && mMainContent.getLeft() > mRange / 2) {                    open();                } else if (xvel > 0) {                    //有向右的速度                    open();                } else {                    close();                }            }            //位置发生移动  调用            @Override            public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {                if (changedView == mLeftContent) {                    //控制底下的子控件不能移动(左面板)                    mLeftWidth = mLeftContent.getMeasuredWidth();                    mLeftContent.layout(0, 0, mLeftWidth, mHeight);                    //左面板移动的距离 累加给主面板(移动左面板)                    int oldLeft = mMainContent.getLeft();                    int newLeft = oldLeft + dx;                    //修正左边的位置                    newLeft = fixleft(newLeft);                    mMainContent.layout(newLeft, 0, newLeft + mWidth, mHeight);                }                // dispatch派遣,调度; (迅速地)发出; 迅速处理                dispatchEvent();                invalidate();            }        });    }    //2  mViewDragHelper抢过触摸事件自己决定应该怎么处理    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        return mViewDragHelper.shouldInterceptTouchEvent(ev);    }    //3.mViewDragHelper抢过触摸事件后,进行处理,返回值true    @Override    public boolean onTouchEvent(MotionEvent event) {        mViewDragHelper.processTouchEvent(event);        return true;    }    //4.onFinishInflate()在控件 inflate 完成时会被调用查找子控件    //可以通过 findViewById()的方式查找子控件  getChildAt(0)    @Override    protected void onFinishInflate() {        super.onFinishInflate();        mLeftContent = (LinearLayout) getChildAt(0);        mMainContent = (LinearLayout) getChildAt(1);    }    // 5.onSizeChanged()调用的次数比 onMeasure()少,在这里我们在 onSizeChanged()方法中去获取宽高    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        //获取整个控件的宽度和高度        mWidth = getMeasuredWidth();        mHeight = getMeasuredHeight();        //主界面拖拽的范围(自定义)(0-mRange)(0 < left         mRange = (int) (mWidth * 0.6f);    }    //6.修正左边的距离    private int fixleft(int left) {        if (left < 0) {            left = 0;        } else if (left > mRange) {            left = mRange;        }        return left;    }    //7.打开 smooth变平和,变缓和;Slide Mountain 斯来得山(凯次克来最高峰)    //View child, int finalLeft, int finalTop    private void open() {        open(true);    }    private void open(boolean isSmooth) {        int finalLeft = mRange;        if (isSmooth) {            //开启平滑            if (mViewDragHelper.smoothSlideViewTo(mMainContent, finalLeft, 0)) {                //重绘界面 Compat兼容性;  postInvalidateOnAnimation 动画结束之后再重绘 防止丢帧                ViewCompat.postInvalidateOnAnimation(this);            } else {                mMainContent.layout(finalLeft, 0, finalLeft + mWidth, mHeight);            }        }    }    //8. 关闭    private void close() {        close(true);    }    private void close(boolean isSmooth) {        int finalLeft = 0;        if (isSmooth) {            //开启平滑            if (mViewDragHelper.smoothSlideViewTo(mMainContent, finalLeft, 0)) {                //重绘界面                //invalidate();                ViewCompat.postInvalidateOnAnimation(this);            } else {                mMainContent.layout(finalLeft, 0, finalLeft + mWidth, mHeight);            }        }    }    @Override    public void computeScroll() {        super.computeScroll();        //维持动画        if (mViewDragHelper.continueSettling(true)) {            //重绘            ViewCompat.postInvalidateOnAnimation(this);        }    }    //9.加动画  回调    private void dispatchEvent() {        //获取 百分百 0.0f - 1.0f        float percent = mMainContent.getLeft() * 1.0f / mRange;        Status lastStatus = status;        //状态更新        if (percent == 0) {            status = Status.Close;        } else if (percent == 1) {            status = Status.Open;        } else {            status = Status.Draging;        }        //接口回调        if (mOnUpdataDragStateListener != null) {            mOnUpdataDragStateListener.onDragging(percent);        }        //        if (lastStatus != status && mOnUpdataDragStateListener != null) {            if (status == Status.Open) {                mOnUpdataDragStateListener.onOpen();            } else if (status == Status.Close) {                mOnUpdataDragStateListener.onClose();            }        }        //左面板 缩放  位移  透明的        //0.0f-1.0f   ---0.5f-1.0f        //0.5f + percent * (0.5f);        mLeftContent.setScaleX(0.5f + percent * (0.5f));        mLeftContent.setScaleY(0.5f + percent * (0.5f));        //位移 evaluate(percent,-mw,0)        mLeftContent.setTranslationX(evaluate(percent, -mWidth * 0.5f, 0f));        //透明的evaluate(percent,0.2f,1.0f)        mLeftContent.setAlpha(evaluate(percent, 0.2f, 1.0f));        //主面板 缩放evaluate(percent,0.2f,1.0f)        mMainContent.setScaleY(evaluate(percent, 1.0f, 0.8f));        //背景亮度   滤波器Filter  估价,估值evaluate  门童; 搬运工人Porter欺骗; 把…改头换面;Duff        getBackground().setColorFilter((Integer) evaluateColor(percent, Color.BLACK, Color.TRANSPARENT), PorterDuff.Mode.SRC_OVER);    }    public Object evaluateColor(float fraction, Object startValue, Object endValue) {        int startInt = (Integer) startValue;        int startA = (startInt >> 24) & 0xff;        int startR = (startInt >> 16) & 0xff;        int startG = (startInt >> 8) & 0xff;        int startB = startInt & 0xff;        int endInt = (Integer) endValue;        int endA = (endInt >> 24) & 0xff;        int endR = (endInt >> 16) & 0xff;        int endG = (endInt >> 8) & 0xff;        int endB = endInt & 0xff;        return (int) ((startA + (int) (fraction * (endA - startA))) << 24) |                (int) ((startR + (int) (fraction * (endR - startR))) << 16) |                (int) ((startG + (int) (fraction * (endG - startG))) << 8) |                (int) ((startB + (int) (fraction * (endB - startB))));    }    public Float evaluate(float fraction, Number startValue, Number endValue) {        float startFloat = startValue.floatValue();        return startFloat + fraction * (endValue.floatValue() - startFloat);    }}

3.MainActivity
public class MainActivity extends Activity

package com.guyulei.myqq50;import android.animation.ValueAnimator;import android.app.Activity;import android.graphics.Color;import android.os.Bundle;import android.view.View;import android.view.ViewGroup;import android.view.animation.CycleInterpolator;import android.widget.ArrayAdapter;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;import java.util.Random;import utils.MyToast;public class MainActivity extends Activity {    private DragLayout mDragLayout;    private ListView   mMainlistView;    private ListView   mLeftlistView;    private ImageView  mIvhead;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //主页面imag对象        mIvhead = (ImageView) findViewById(R.id.iv_head);        mDragLayout = (DragLayout) findViewById(R.id.dl_dragLayout);        mDragLayout.setOnUpdataDragStateListener(new DragLayout.OnUpdataDragStateListener() {            @Override            public void onOpen() {                MyToast.showToast(getApplicationContext(), "onOpen");                ////面板打开时,左面板上的 listview 随机滑动到 0 到 50 间的某个位置                mLeftlistView.smoothScrollToPosition(new Random().nextInt(20));            }            @Override            public void onClose() {                MyToast.showToast(getApplicationContext(), "onClose");                ValueAnimator valueAnimator = ValueAnimator.ofFloat(0.0f, 10f);                valueAnimator.setDuration(1000);                valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                    @Override                    public void onAnimationUpdate(ValueAnimator animation) {                        float value = (float) animation.getAnimatedValue();                        mIvhead.setTranslationX(value);                    }                });                //动画插值器                valueAnimator.setInterpolator(new CycleInterpolator(3));                valueAnimator.start();            }            @Override            public void onDragging(float percent) {                MyToast.showToast(getApplicationContext(), "onDragging" + percent);                //percent 0.0f -> 1.0f  => 1.0f -> 0.0f   ==> 1-percent                mIvhead.setAlpha(1-percent);            }        });        //        mMainlistView = (ListView) findViewById(R.id.main_listView);        //main数据        String[] str_main = new String[]{"guyulei", "guyulei1", "guyulei2", "guyulei3", "guyulei4"                , "guyulei5", "guyulei6", "guyulei7", "guyulei8", "guyulei9", "guyulei10",                "guyulei", "guyulei1", "guyulei2", "guyulei3", "guyulei4"                , "guyulei5", "guyulei6", "guyulei7", "guyulei8", "guyulei9", "guyulei10",                "guyulei", "guyulei1", "guyulei2", "guyulei3", "guyulei4"                , "guyulei5", "guyulei6", "guyulei7", "guyulei8", "guyulei9", "guyulei10"};        //设置适配器:ArrayAdapter        mMainlistView.setAdapter(new ArrayAdapter(getApplicationContext(), android.R.layout.simple_list_item_1, str_main) {            @Override            //重新getView  改变字体颜色            public View getView(int position, View convertView, ViewGroup parent) {                TextView view = (TextView) super.getView(position, convertView, parent);                view.setTextColor(Color.BLUE);                return view;            }        });        //        mLeftlistView = (ListView) findViewById(R.id.left_listView);        String[] str_left = new String[]{"顾雨磊", "顾雨磊1", "顾雨磊2", "顾雨磊3", "顾雨磊4"                , "顾雨磊5", "顾雨磊6", "顾雨磊7", "顾雨磊8", "顾雨磊9", "顾雨磊10", "顾雨磊11"                , "顾雨磊12", "顾雨磊13", "顾雨磊14", "顾雨磊15", "顾雨磊16", "顾雨磊17", "顾雨磊18"                , "顾雨磊19"};        mLeftlistView.setAdapter(new ArrayAdapter(getApplicationContext(), android.R.layout.simple_list_item_1, str_left) {            @Override            public View getView(int position, View convertView, ViewGroup parent) {                TextView view = (TextView) super.getView(position, convertView, parent);                view.setTextColor(Color.BLACK);                return view;            }        });    }}

更多相关文章

  1. Android保持背光常亮的设置方法
  2. android EditText控件设置只读
  3. Android中定时器的3种实现方法
  4. Android与服务器通信的方法之一-->TCP
  5. Android ListView 控件学习
  6. ScrollView里面放入多个子控件
  7. android RadioButton文字居中的方法
  8. 编译NotificationManagerService.java文件的方法

随机推荐

  1. SQL建立数据库及删除数据库命令
  2. SQLServer 全文检索(full-text)语法
  3. sqlserver isnull在数据库查询中的应用
  4. SQL 比较一个集合是否在另一个集合里存在
  5. 动态给表添加删除字段并同时修改它的插入
  6. SQL对时间处理的语句小结
  7. sqlserver 数据库学习笔记
  8. SQL中exists的使用方法
  9. SQLServer中的切割字符串SplitString函数
  10. 用SQL语句添加删除修改字段、一些表与字