<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>