自定義viewgroup->sildeMenu.java
package com.xuhao.sliding.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Scroller;
public class SildeMenu extends FrameLayout {
private View menuView, mainView;
private int menuWidth = 0;
private Scroller scroller;
public SildeMenu(Context context) {
super(context);
init();
}
public SildeMenu(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
scroller = new Scroller(getContext());
}
/**
* 當1級的子view全部加載完調用,可以用初始化子view的引用 注意,這裏無法獲取子view的寬高
*/
@Override
protected void onFinishInflate() {
super.onFinishInflate();
menuView = getChildAt(0);
mainView = getChildAt(1);
menuWidth = menuView.getLayoutParams().width;
// Log.e("Main", menuWidth + "");
}
/**
* widthMeasureSpec和heightMeasureSpec是系統測量SlideMenu時傳入的參數
* 這2個參數測kiang出來的寬高能讓slidemenu充滿船體,其實是正好等於屏幕的寬高
*/
// @Override
// protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// int measureSpec = MeasureSpec.makeMeasureSpec(menuWidth,
// MeasureSpec.EXACTLY);
// // Log.e("Main", measureSpec + "measureSpec");
// // 測量所有子view的寬高
// // 通過getLayoutParams方法可以獲取到佈局文件中指定寬高
// menuView.measure(measureSpec, heightMeasureSpec);
// // 直接使用slidemenu的測量參數,以爲他的狂傲就是充滿父窗體
// mainView.measure(widthMeasureSpec, heightMeasureSpec);
// }
// dispatchTouchEvent(MotionEvent ev)
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = (int) ev.getX();
break;
case MotionEvent.ACTION_MOVE:
int deltaX = (int) (ev.getX() - downX);
if(Math.abs(deltaX)>8){
//如果左右滑動大於8就讓slidemenu處理
return true;
}
break;
}
return super.onInterceptTouchEvent(ev);
}
/**
* l:當前子view的左邊在父view的座標系中的x座標 t:當前子view的頂邊在父view座標系中的y座標
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
menuView.layout(-menuWidth, 0, 0, menuView.getMeasuredHeight());
mainView.layout(0, 0, r, b);
}
private int downX;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = (int) event.getX();
break;
case MotionEvent.ACTION_MOVE:
int moveX = (int) event.getX();
int detalX = moveX - downX;
int newScrollX = getScrollX() - detalX;
if (newScrollX < -menuWidth)
newScrollX = -menuWidth;
if (newScrollX > 0)
newScrollX = 0;
scrollTo(newScrollX, 0);
downX = moveX;
break;
case MotionEvent.ACTION_UP:
// ScrollAnimation animation;
// if (getScrollX() > -menuWidth / 2) {
// // 關閉菜單
// animation = new ScrollAnimation(this, 0);
// // scrollTo(0, 0);
// } else {
// // 打開菜單
// animation = new ScrollAnimation(this, -menuWidth);
// // scrollTo(-menuWidth, 0);
// }
// startAnimation(animation);
if (getScrollX() > -menuWidth / 2) {
// 關閉菜單
closeMenu();
} else {
// 打開菜單
openMenu();
}
break;
}
return true;
}
/**
* 打開慘淡
*/
private void openMenu() {
scroller.startScroll(getScrollX(), 0, -menuWidth - getScrollX(), 0, 400);
invalidate();
}
/**
* 關閉菜單
*/
private void closeMenu() {
scroller.startScroll(getScrollX(), 0, 0 - getScrollX(), 0, 400);
invalidate();
}
/**
* Scroller不主動去掉用此方法 invalidate()可以調用這個方法 invalidate->draw->computeScroll
*/
@Override
public void computeScroll() {
super.computeScroll();
if (scroller.computeScrollOffset()) {// 返回true表示動畫沒有結束
scrollTo(scroller.getCurrX(), 0);
invalidate();
}
}
public void switchMenu(){
if(getScrollX()==0){
//需要打開
openMenu();
}else{
//需要關閉
closeMenu();
}
}
}
activity_main.xml
<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" >
<com.xuhao.sliding.view.SildeMenu
android:id="@+id/sildemenu"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- 菜單佈局 -->
<include layout="@layout/layout_menu" />
<!-- 主界面佈局 -->
<include layout="@layout/layout_main" />
</com.xuhao.sliding.view.SildeMenu>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="240dp"
android:layout_height="match_parent"
android:background="@drawable/menu_bg" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="300dp" >
<TextView
style="@style/MenuTabStyle"
android:background="#33ababab"
android:drawableLeft="@drawable/tab_news"
android:text="新聞" />
<TextView
style="@style/MenuTabStyle"
android:drawableLeft="@drawable/tab_read"
android:text="訂閱" />
<TextView
style="@style/MenuTabStyle"
android:drawableLeft="@drawable/tab_ties"
android:text="跟帖" />
<TextView
style="@style/MenuTabStyle"
android:drawableLeft="@drawable/tab_pics"
android:text="圖片" />
<TextView
style="@style/MenuTabStyle"
android:drawableLeft="@drawable/tab_ugc"
android:text="話題" />
<TextView
style="@style/MenuTabStyle"
android:drawableLeft="@drawable/tab_vote"
android:text="投票" />
<TextView
style="@style/MenuTabStyle"
android:drawableLeft="@drawable/tab_focus"
android:text="聚合閱讀" />
</LinearLayout>
</ScrollView>
layout_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ccc"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center_vertical"
android:background="@drawable/top_bar_bg" >
<ImageView
android:id="@+id/iv_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/main_back" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:background="@drawable/top_bar_divider" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:text="序號新聞"
android:textColor="#ffffff"
android:textSize="22sp" />
</LinearLayout>
<TextView android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#000000"
android:textSize="30sp"
android:gravity="center"
android:text="釣魚島是中國的..."/>
</LinearLayout>
自定義的動畫ScrollAnimation.java
package com.xuhao.sliding.view;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
public class ScrollAnimation extends Animation {
private View view;
private int startScrollX;
private int totalValue;
private int targetScrollX;
public ScrollAnimation(View view, int targetScrollX) {
super();
this.view = view;
this.targetScrollX = targetScrollX;
startScrollX = view.getScrollX();
totalValue = targetScrollX - startScrollX;
int time = Math.abs(totalValue);
setDuration(time);
}
/**
* 在指定的時間內一直執行該方法,一直到動畫結束 interpolatedTime:0-1 標識動畫執行的進度或者百分比 time:0 - 0.5 -
* 0.7 - 1 value:10 - 60 - 80 - 110 當前的值=起始值+總的差值*interpolatedTime
*/
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
int currentScrollX = (int) (startScrollX + totalValue
* interpolatedTime);
view.scrollTo(currentScrollX, 0);
}
}
mainactiviy.java
package com.xuhao.sliding;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ImageView;
import com.xuhao.sliding.view.SildeMenu;
import comxuhao.sliding.R;
public class MainActivity extends Activity {
private ImageView iv;
private SildeMenu sildeMenu;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
iv=(ImageView) findViewById(R.id.iv_menu);
sildeMenu=(SildeMenu) findViewById(R.id.sildemenu);
iv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
sildeMenu.switchMenu();
}
});
}
}