疯了,疯了,刚刚写的一不小心被我删了 ,我就简单的把代码贴下,代码上面都有注释,
首先是布局文件,
<com.qianfeng.sideqq.ui.DragLayer 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:id="@+id/mdragLayer"
android:background="@drawable/bg"
tools:context=".MainActivity" >
<LinearLayout
android:id="@+id/left_content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ff6600ff"
android:orientation="vertical" >
<ImageView
android:id="@+id/iv_head"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/head" />
<ListView
android:id="@+id/lv_left"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
<com.qianfeng.sideqq.ui.MyLinearLayout
android:id="@+id/my_linear"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:paddingLeft="20dp" >
<ImageView
android:id="@+id/iv_main_head"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_centerVertical="true"
android:src="@drawable/head" />
</RelativeLayout>
<ListView
android:id="@+id/lv_main"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</com.qianfeng.sideqq.ui.MyLinearLayout>
</com.qianfeng.sideqq.ui.DragLayer>
自定义的两个控件,
/**
* 自定义view 实现 拖动的效果
*
* @author Administrator
*
*/
public class DragLayer extends FrameLayout {
public DragLayer(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DragLayer(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private int mRange;
private ViewDragHelper mDragHelper;
private ViewGroup mleftLayout;
private ViewGroup mMainLayout;
private int windowWindth;
private int windowHeight;
private Status mStatus;
public Status getStatus() {
return mStatus;
}
public void setStatus(Status mStatus) {
this.mStatus = mStatus;
}
private OnDragStatusChangeListener mlistener;
// 定义的状态的枚举的 三种状态
public static enum Status{
Open, Close,Draging;
}
public interface OnDragStatusChangeListener {
// 状态打开的时候回调的方法
void open();
// 状态关闭的时候回调的方法
void close();
// 滑动的时候回调的方法
void draging(float percent);
}
public void setDragStatusListener(OnDragStatusChangeListener listener){
this.mlistener=listener;
}
private void init() {
// 参数1 是viewGroup 参数2 回调的接口,参数3 敏感度
mDragHelper = ViewDragHelper.create(this, mCallback);
}
ViewDragHelper.Callback mCallback = new ViewDragHelper.Callback() {
// 尝试捕获view的时候回调的方法
@Override
public boolean tryCaptureView(View arg0, int arg1) {
// 返回true 表示的是 都可以进行滑动
return true;
}
// 当capturedChild 被捕获成功的时候回调的方法
public void onViewCaptured(View capturedChild, int activePointerId) {
super.onViewCaptured(capturedChild, activePointerId);
}
public int getViewHorizontalDragRange(View child) {
// 获得View 横向被拖动的范围 ,但是值得注意的是,它不能决定拖拽的范围,仅仅决定了动画执行的速度
return mRange;
};
// clamp 夹紧, 固定住 方法的作用是, 通过返回的int值,来确定view显示的地方
// 参数1 正在滑动view 参数2
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
if (child == mMainLayout) {
left = getMoveDistance(left);
}
return left;
}
// 当changedView 的位置改变的时候回调的方法,处理要做的事情(更新状态,伴随动画,重绘界面)
// 参数1 目前正在改变位置的view 参数2left 到x轴原点left的距离, 参数3top 到y轴的距离, 参数4dx
// 表示的是速度还有方向,向左移动为正, 向右移动为负;
// 参数5 同参数4
public void onViewPositionChanged(View changedView, int left, int top,
int dx, int dy) {
super.onViewPositionChanged(changedView, left, top, dx, dy);
int newleft = left;
if (changedView == mleftLayout) {
// 当滑动的view等于mleftLayout的时候 强制把 mleftLayout 重绘到屏幕的大小
mleftLayout.layout(0, 0, windowWindth, windowHeight);
newleft = mMainLayout.getLeft() + dx;
newleft = getMoveDistance(newleft);
// 把一个控件放到一个位置 , 位置有四个参数决定
mMainLayout.layout(newleft, 0, newleft + windowWindth,
windowHeight);
}
dispatchEvent(newleft);
// 为了 兼容低版本 手动调用绘制
invalidate();
};
// 当view被释放的时候,执行动画,参数1 被释放的子view 参数2,水平方向上的速度 ,参数3 竖直方向上的速度
public void onViewReleased(View releasedChild, float xvel, float yvel) {
super.onViewReleased(releasedChild, xvel, yvel);
if (xvel == 0 && mMainLayout.getLeft() > mRange / 2.0f) {
open();
} else if (xvel > 0) {
open();
} else {
close();
}
}
};
protected void dispatchEvent(int newleft) {
// percent 的取值范围应该是从0-1
float percent=newleft*1.0f/mRange;
// 更新状态, 执行回调
mStatus=UpdataStatus(percent);
switch (mStatus) {
//打开
case Open:
mlistener.open();
break;
// 关闭
case Close:
mlistener.close();
break;
// 滑动
case Draging:
mlistener.draging(percent);
break;
default:
break;
}
// 测界面 的缩放的动画
// mleftLayout.setScaleX(1-0.5f*percent);
// mleftLayout.setScaleY(1-0.5f*percent);
ViewHelper.setScaleX(mleftLayout, (0.5f+0.5f*percent));
ViewHelper.setScaleY(mleftLayout, (0.5f+0.5f*percent));
ViewHelper.setTranslationX(mleftLayout, evaluate(percent, -windowWindth/2.0f, 0));
ViewHelper.setAlpha(mleftLayout, evaluate(percent,0.5f,1.0f));
//主界面的缩放动画
ViewHelper.setScaleX(mMainLayout, evaluate(percent, 1.0f, 0.8f));
ViewHelper.setScaleY(mMainLayout, evaluate(percent, 1.0f, 0.8f));
}
// 更新状态的方法
private Status UpdataStatus(float percent) {
if (percent==0) {
return Status.Close;
}else if (percent==1.0f) {
return Status.Open;
}else {
return Status.Draging;
}
}
/**
* 估值器
* @param fraction
* @param startValue
* @param endValue
* @return
*/
public Float evaluate(float fraction, Number startValue, Number endValue) {
float startFloat = startValue.floatValue();
return startFloat + fraction * (endValue.floatValue() - startFloat);
}
public void close() {
close(true);
}
/**
* 关闭的动画
*/
public void close(boolean isSmooth) {
// 是否平滑的关闭
int finalLeft = 0;
if (isSmooth) {
// 如果返回的true 代表还没有移动到要移动位置,需要刷新下界面
boolean flag = mDragHelper.smoothSlideViewTo(mMainLayout,
finalLeft, 0);
if (flag) {
ViewCompat.postInvalidateOnAnimation(DragLayer.this);
}
} else {
mMainLayout.layout(finalLeft, 0, finalLeft + windowWindth,
windowHeight);
}
}
public void open() {
open(true);
}
/**
* 打开的动画
*/
public void open(boolean isSmooth) {
// 是否平滑的关闭
int finalLeft = mRange;
if (isSmooth) {
// 如果返回的true 代表还没有移动到要移动位置,需要刷新下界面
boolean flag = mDragHelper.smoothSlideViewTo(mMainLayout,
finalLeft, 0);
if (flag) {
ViewCompat.postInvalidateOnAnimation(DragLayer.this);
}
} else {
mMainLayout.layout(finalLeft, 0, finalLeft + windowWindth,
windowHeight);
}
}
public void computeScroll() {
super.computeScroll();
// 是否持续平滑动作
if (mDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
// 重写 父类的方法 ,让VIewDragHelper 去判断是否应该去 拦截事件
public boolean onInterceptTouchEvent(android.view.MotionEvent ev) {
return mDragHelper.shouldInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mDragHelper.processTouchEvent(event);
// 返回true 表示的是持续接受 触摸事件
return true;
}
// 当xml文件 解析完毕之后,回调的方法
@Override
protected void onFinishInflate() {
super.onFinishInflate();
// 拿到两个控件的实例
mleftLayout = (ViewGroup) this.getChildAt(0);
mMainLayout = (ViewGroup) this.getChildAt(1);
}
// 当view的大小 改变的时候回调的方法 注意的是这个方法是执行在onMeasure(测量的方法) 方法 之后的
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// 这里的getMeasuredWidth()和getWidth()方法 得到的值都是一样的
windowWindth = getMeasuredWidth();
windowHeight = getMeasuredHeight();
// 滑动的距离
mRange = (int) (0.6f * windowWindth);
}
private int getMoveDistance(int left) {
if (left < 0) {
return 0;
} else if (left > mRange) {
return mRange;
}
return left;
}
}
自定义的linearLayer的类
public class MyLinearLayout extends LinearLayout{
private DragLayer mDragLayer;
public MyLinearLayout(Context context) {
super(context);
}
public MyLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
// 把 Draglayer 初始化
public void setDragLayer(DragLayer mDragLayer){
this.mDragLayer=mDragLayer;
}
// 重写拦截事件的方法
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// 如果当前是关闭状态
if (mDragLayer.getStatus()==Status.Close) {
return super.onInterceptTouchEvent(ev);
}else {
// 如果 状态是滑动 或者打开的状态 ,直接拦截事件
return true;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mDragLayer.getStatus()==Status.Close) {
return super.onTouchEvent(event);
}else {
// 如果 状态是滑动 或者打开的状态 ,直接拦截事件
if (event.getAction()==MotionEvent.ACTION_UP) {
mDragLayer.close();
}
return true;
}
}
}
Activity类的实现
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final DragLayer mDragLayer= (DragLayer) findViewById(R.id.mdragLayer);
ListView mleftListView = (ListView) findViewById(R.id.lv_left);
ListView mMainListView = (ListView) findViewById(R.id.lv_main);
final MyLinearLayout myLinearLayout= (MyLinearLayout) findViewById(R.id.my_linear);
final ImageView iv_main_head= (ImageView) findViewById(R.id.iv_main_head);
final ImageView iv_left_head=(ImageView) findViewById(R.id.iv_head);
myLinearLayout.setDragLayer(mDragLayer);
iv_left_head.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 当 点击的时候让它 关闭右侧的菜单 ,显示 主界面
mDragLayer.close();
}
});
iv_main_head.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 打开 右侧的菜单
mDragLayer.open();
}
});
mleftListView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_expandable_list_item_1,Cheeses.sCheeseStrings){
@Override
public View getView(int position, View convertView,
ViewGroup parent) {
// 把textview的颜色改成 白色的
View view=super.getView(position, convertView, parent);
TextView mTextView=(TextView)(view);
mTextView.setTextColor(Color.WHITE);
return view;
}
});
mMainListView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_expandable_list_item_1, Cheeses.NAMES));
mDragLayer.setDragStatusListener(new OnDragStatusChangeListener() {
@Override
public void open() {
System.out.println("sss"+"open");
}
@Override
public void close() {
// 当关闭的时候让 头像晃动
System.out.println("sss"+"close");
// TranslateAnimation translateAnimation
// 参数1 动画添加到那个控件上 , 参数2 动画的名字 参数3 动画执行的范围
ObjectAnimator animator=ObjectAnimator.ofFloat(iv_main_head, "translationX", 20);
// 插补器 动态的改变 动画执行过程中的速度 等等
animator.setInterpolator(new CycleInterpolator(4));
animator.setDuration(500);
animator.start();
}
@Override
public void draging(float percent) {
// System.out.println("sss"+"draging");
float alpha=1.0f-percent;
// 设置 透明度 当 正在滑动的时候 让iv_main_head 随着 滑动 而消失 或者显示
ViewHelper.setAlpha(iv_main_head, alpha);
}
});
}
}
还有一个就是ListView数据的具体实现类