大家对于sliding_menu一定不会陌生,左右拖拽来节约空间同时效果也不错,先上个图
我们的两个button对应不同的两个activity,但要求是切换的内容都要在右侧可见,而不是开启一个新的页面
我的实现是通过ActivityGroup+sliding_menu来实现的。直接上代码
A:主页面布局
<RelativeLayout 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"
tools:context=".MainActivity" >
<!-- 主布局 -->
<RelativeLayout
android:id="@+id/mainLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/titlebar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:padding="5dip">
<ImageView
android:id="@+id/ivMore"
android:src="@drawable/nav_more_normal"
android:contentDescription="@string/img_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dip"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/title"
android:textSize="20sp"
android:textColor="#000000"/>
<ImageView
android:id="@+id/ivSettings"
android:src="@drawable/nav_setting_normal"
android:contentDescription="@string/img_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_marginRight="10dip"/>
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/MyContent"
android:orientation="vertical"
android:layout_below="@id/titlebar"
android:background="@drawable/picture"
></LinearLayout>
</RelativeLayout>
<!-- 左侧菜单导航 -->
<RelativeLayout
android:id="@+id/leftLayout"
android:layout_width="140dip"
android:layout_height="match_parent"
android:background="#000000">
<RelativeLayout
android:id="@+id/leftTitlebar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/grey21"
android:padding="5dip">
<TextView
android:layout_marginLeft="5dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text="@string/leftNav"
android:textSize="20sp"
android:textColor="#ffffff"/>
</RelativeLayout>
<LinearLayout
android:id="@+id/layoutSlideMenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/leftTitlebar">
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="act1"
/>
<Button
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="act2"
/>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
B:子页面布局【根据需求自己替换
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_item"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="button1"
android:textSize="20sp" />
</RelativeLayout>
C:主Activity代码
package com.chris.lr.slidemenu;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.app.Activity;
import android.app.ActivityGroup;
import android.content.Intent;
public class MainActivity extends ActivityGroup implements OnGestureListener, OnTouchListener,OnClickListener {
private static final String TAG = "ChrisSlideMenu";
private RelativeLayout mainLayout;
private RelativeLayout leftLayout;
private LinearLayout layoutSlideMenu;
LinearLayout bodyLayout;
private ImageView ivMore;
private ImageView ivSettings;
private GestureDetector mGestureDetector;
private static final int SPEED = 30;
private boolean bIsScrolling = false;
private int iLimited = 0;
private int mScroll = 0;
private View mClickedView = null;
Button button1;
Button button2;
private static int TABSWITCHSTATE = 1;
private static final int TABSWITCHBASEINFO = 1;
private static final int TABSWITCHNEWPUSH = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initView();
initTab();
}
private void initView(){
mainLayout = (RelativeLayout) findViewById(R.id.mainLayout);
leftLayout = (RelativeLayout) findViewById(R.id.leftLayout);
button1 = (Button) findViewById( R.id.btn1 );
button2 = (Button) findViewById( R.id.btn2 );
bodyLayout = (LinearLayout) findViewById( R.id.MyContent );
button1.setOnClickListener( this );
button2.setOnClickListener( this );
mainLayout.setOnTouchListener(this);
leftLayout.setOnTouchListener(this);
layoutSlideMenu = (LinearLayout) findViewById(R.id.layoutSlideMenu);
ivMore = (ImageView) findViewById(R.id.ivMore);
ivSettings = (ImageView) findViewById(R.id.ivSettings);
ivMore.setOnTouchListener(this);
ivSettings.setOnTouchListener(this);
mGestureDetector = new GestureDetector(this);
mGestureDetector.setIsLongpressEnabled(false);
resizeLayout();
}
Intent intentBase ;
Intent intentList;
private void initTab(){
intentBase = new Intent(MainActivity.this, A1.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentList = new Intent(MainActivity.this, A2.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
bodyLayout.addView( getLocalActivityManager().startActivity( "a1", intentBase ).getDecorView() );
}
/*
* 使用leftMargin及rightMargin防止layout被挤压变形
* Math.abs(leftMargin - rightMargin) = layout.width
*/
private void resizeLayout(){
DisplayMetrics dm = getResources().getDisplayMetrics();
// 固定 main layout, 防止被左、右挤压变形
RelativeLayout.LayoutParams lp = (LayoutParams) mainLayout.getLayoutParams();
lp.width = dm.widthPixels;
mainLayout.setLayoutParams(lp);
// 将左layout调整至main layout左边
lp = (LayoutParams) leftLayout.getLayoutParams();
lp.leftMargin = -lp.width;
leftLayout.setLayoutParams(lp);
Log.d(TAG, "left l.margin = " + lp.leftMargin);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0){
RelativeLayout.LayoutParams lp = (LayoutParams) mainLayout.getLayoutParams();
if(lp.leftMargin != 0){
if(lp.leftMargin > 0){
new SlideMenu().execute(leftLayout.getLayoutParams().width, -SPEED);
}
return true;
}
}
return super.onKeyDown(keyCode, event);
}
private void rollLayout(int margin){
RelativeLayout.LayoutParams lp = (LayoutParams) mainLayout.getLayoutParams();
lp.leftMargin += margin;
lp.rightMargin -= margin;
mainLayout.setLayoutParams(lp);
lp = (LayoutParams) leftLayout.getLayoutParams();
lp.leftMargin += margin;
leftLayout.setLayoutParams(lp);
}
private void onScroll(float distanceX){
bIsScrolling = true;
mScroll += distanceX; // 向左为正
Log.d(TAG, "mScroll = " + mScroll + ", distanceX = " + distanceX);
RelativeLayout.LayoutParams lp = (LayoutParams) mainLayout.getLayoutParams();
RelativeLayout.LayoutParams lpLeft = (LayoutParams) leftLayout.getLayoutParams();
Log.d(TAG, "lp.leftMargin = " + lp.leftMargin);
int distance = 0;
if(mScroll > 0){ // 向左移动
if(lp.leftMargin <= 0){ // 打开右导航菜单
if(iLimited > 0){
return;
}
}else if(lp.leftMargin > 0){ // 关闭左导航菜单
distance = lp.leftMargin;
}
if(mScroll >= distance){
mScroll = distance;
}
}else if(mScroll < 0){ // 向右移动
if(lp.leftMargin >= 0){ // 打开左导航菜单
if(iLimited < 0){
return;
}
distance = lpLeft.width - Math.abs(lp.leftMargin);
}else if(lp.leftMargin < 0){ // 关闭右导航菜单
distance = Math.abs(lp.leftMargin);
}
if(mScroll <= -distance){
mScroll = -distance;
}
}
Log.d(TAG, "mScroll = " + mScroll);
if(mScroll != 0){
rollLayout(-mScroll);
}
}
private void onRelease(){
RelativeLayout.LayoutParams lp = (LayoutParams) mainLayout.getLayoutParams();
if(lp.leftMargin < 0){}else if(lp.leftMargin > 0){
/*
* 右移大于左导航宽度一半,则自动展开,否则自动缩回去
*/
if(Math.abs(lp.leftMargin) > leftLayout.getLayoutParams().width/2){
new SlideMenu().execute(leftLayout.getLayoutParams().width - Math.abs(lp.leftMargin), SPEED);
}else{
new SlideMenu().execute(Math.abs(lp.leftMargin), -SPEED);
}
}
}
// onTouch ///
@Override
public boolean onTouch(View v, MotionEvent event) {
mClickedView = v;
if(MotionEvent.ACTION_UP == event.getAction() && bIsScrolling){
onRelease();
}
return mGestureDetector.onTouchEvent(event);
}
/// GestureDetector Override Begin ///
@Override
public boolean onDown(MotionEvent e) {
bIsScrolling = false;
mScroll = 0;
iLimited = 0;
RelativeLayout.LayoutParams lp = (LayoutParams) mainLayout.getLayoutParams();
if(lp.leftMargin > 0){
iLimited = 1;
}else if(lp.leftMargin < 0){
iLimited = -1;
}
return true;
}
@Override
public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
onScroll(distanceX);
return false;
}
@Override
public void onShowPress(MotionEvent arg0) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
/*
* 正常情况下,mainLayout的leftMargin为0,
* 当左/右菜单为打开中,此时就不为0,需要判断
*/
if(mClickedView != null){
RelativeLayout.LayoutParams lp = (LayoutParams) mainLayout.getLayoutParams();
if(mClickedView == ivMore){
Log.d(TAG, "[onSingleTapUp] ivMore clicked! leftMargin = " + lp.leftMargin);
if(lp.leftMargin == 0){
new SlideMenu().execute(leftLayout.getLayoutParams().width, SPEED);
}else{
new SlideMenu().execute(leftLayout.getLayoutParams().width, -SPEED);
}
}else if(mClickedView == mainLayout){
Log.d(TAG, "[onSingleTapUp] mainLayout clicked!");
}
}
return true;
}
/// GestureDetector Override End ///
/**
*
* @author cheng.yang
*
* 左、右菜单滑出
*
* params[0]: 滑动距离
* params[1]: 滑动速度,带方向
*/
public class SlideMenu extends AsyncTask<Integer, Integer, Void>{
@Override
protected Void doInBackground(Integer... params) {
if(params.length != 2){
Log.e(TAG, "error, params must have 2!");
}
int times = params[0] / Math.abs(params[1]);
if(params[0] % Math.abs(params[1]) != 0){
times ++;
}
for(int i = 0; i < times; i++){
this.publishProgress(params[0], params[1], i+1);
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
if(values.length != 3){
Log.e(TAG, "error, values must have 3!");
}
int distance = Math.abs(values[1]) * values[2];
int delta = values[0] - distance;
int leftMargin = 0;
if(values[1] < 0){ // 左移
leftMargin = (delta > 0 ? values[1] : -(Math.abs(values[1]) - Math.abs(delta)));
}else{
leftMargin = (delta > 0 ? values[1] : (Math.abs(values[1]) - Math.abs(delta)));
}
rollLayout(leftMargin);
}
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.btn1:
if(TABSWITCHSTATE == TABSWITCHBASEINFO){
return;
}
bodyLayout.removeAllViews();
bodyLayout.addView( getLocalActivityManager().startActivity( "a1", intentBase ).getDecorView() );
TABSWITCHSTATE = TABSWITCHBASEINFO;
break;
case R.id.btn2:
if(TABSWITCHSTATE == TABSWITCHNEWPUSH){
return;
}
bodyLayout.removeAllViews();
bodyLayout.addView( getLocalActivityManager().startActivity( "a2", intentList ).getDecorView() );
TABSWITCHSTATE = TABSWITCHNEWPUSH;
break;
default:
break;
}
}
}
上面的代码无非就是通过判断MainLayout的滑动,来展示或隐藏左侧的sliding_menu,同时通过ActivityGroup来管理mainLayout中的视图展示