<span style="font-family: Arial, Helvetica, sans-serif;">package com.support;</span>
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorListenerAdapter;
import com.nineoldandroids.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.BounceInterpolator;
import android.widget.FrameLayout;
public class MenuContainer extends FrameLayout {
private Context context;
private int slideMenuWidth;
private int time = 500;
public MenuContainer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
checkChildCount();
// TODO Auto-generated constructor stub
}
public MenuContainer(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
checkChildCount();
// TODO Auto-generated constructor stub
}
public MenuContainer(Context context) {
super(context);
this.context = context;
checkChildCount();
// TODO Auto-generated constructor stub
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void openMenu() {
getChildAt(1).setVisibility(View.VISIBLE);
getChildAt(2).setTranslationX(slideMenuWidth);
}
public void hideMenu() {
ObjectAnimator animator = ObjectAnimator.ofFloat(
getChildAt(2), "translationX", slideMenuWidth, 0);
animator.setInterpolator(new AccelerateInterpolator());
animator.setDuration(time);
animator.start();
getChildAt(1).setVisibility(View.GONE);
}
private void checkChildCount() {
getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@SuppressLint("NewApi")
@Override
public void onGlobalLayout() {
// TODO Auto-generated method stub
try {
getViewTreeObserver().removeOnGlobalLayoutListener(
this);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (getChildCount() != 2)
throw new RuntimeException(
"MenuContainer must have two view");
View hideView = getChildAt(0);
View darkView=new View(context);
darkView.setBackgroundColor(Color.parseColor("#88000000"));
darkView.setVisibility(View.GONE);
//调整顺序,让用户要显示的界面位于FrameLatout底部,中间添加半透明控件,最上面添加左侧隐藏的控件
removeViewAt(0);
addView(darkView);
addView(hideView);
FrameLayout.LayoutParams params = (LayoutParams) hideView
.getLayoutParams();
params.leftMargin = -hideView.getWidth();//把左侧要隐藏的控件移动到左侧
hideView.setLayoutParams(params);
slideMenuWidth = hideView.getWidth();
darkView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
ObjectAnimator animator = ObjectAnimator.ofFloat(
getChildAt(2), "translationX", slideMenuWidth, 0);
animator.setDuration(time);
animator.setInterpolator(new AccelerateInterpolator());
animator.start();
getChildAt(1).setVisibility(View.GONE);
}
});
// System.out.println("child " +getChildAt(0).toString()+" "+getChildAt(1).toString()+" "+getChildAt(2).toString()+" ");
}
});
// TODO Auto-generated method stub
// if(getChildCount()!=2)
// throw new RuntimeException("MenuContainer must have two view");
}
private float downX;
private float downY;
private final int scaledTouchSlop = 8;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
downX = ev.getRawX();
downY = ev.getRawY();
// System.out.println(downX+" "+downY);
return super.onInterceptTouchEvent(ev);
}
if (ev.getAction() == MotionEvent.ACTION_MOVE) {
float x = ev.getRawX();
float y = ev.getRawY();
// ViewConfiguration.get(context).getScaledTouchSlop() 手机可以识别是最小滑动距离
if (x - downX > Math.abs(y - downY)
&& Math.abs(x - downX) >= ViewConfiguration.get(context)
.getScaledTouchSlop()
&& downX < dip2px(scaledTouchSlop)) {
getChildAt(1).setVisibility(View.VISIBLE);
// System.out.println("view "+getChildAt(1).getY());
return true;
}
}
return super.onInterceptTouchEvent(ev);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
if (downX < dip2px(scaledTouchSlop)&&getChildAt(2).getTranslationX()<slideMenuWidth&&event.getRawX()<slideMenuWidth) {
getChildAt(1).setVisibility(View.VISIBLE);
getChildAt(2).setTranslationX(event.getRawX() - downX);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (downX < dip2px(scaledTouchSlop) ) {
float t = getChildAt(2).getTranslationX();
if (t > slideMenuWidth / 4) {//
ObjectAnimator animator = ObjectAnimator.ofFloat(
getChildAt(2), "translationX", t, slideMenuWidth);
animator.setInterpolator(new BounceInterpolator());
animator.setDuration(time);
animator.start();
} else {
ObjectAnimator animator = ObjectAnimator.ofFloat(
getChildAt(2), "translationX", t, 0);
animator.setDuration(time);
animator.start();
}
}
break;
}
return true;
}
public int dip2px(float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
</pre><pre code_snippet_id="660890" snippet_file_name="blog_20150507_8_4103380" name="code" class="html">
</pre><pre code_snippet_id="660890" snippet_file_name="blog_20150507_8_4103380" name="code" class="html">
</pre><p></p><pre code_snippet_id="660890" snippet_file_name="blog_20150507_9_1722276" name="code" class="html">package com.support;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
<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"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<com.support.MenuContainer
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:id="@+id/hideView"
android:layout_width="200dp"
android:background="#ffd8d8d8"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="hide"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="hide"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="hide"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="hide"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="hide"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="hide"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="hide"/>
</LinearLayout>
<LinearLayout
android:background="#fff"
android:id="@+id/mainView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="xxxx"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="xxxx"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="xxxx"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="xxxx"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="xxxx"/>
</LinearLayout>
</com.support.MenuContainer>
</LinearLayout>