Android-学习-侧栏

来源:互联网 发布:易语言数据比较 编辑:程序博客网 时间:2024/05/29 03:49

Android开发技巧-实现侧栏滑动

布局文件:

slide.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="#c3c4c5"    >    <com.example.administrator.sss.SlideMenu        android:id="@+id/slide_menu"        android:layout_width="fill_parent"        android:layout_height="fill_parent" >        <include layout="@layout/layout_menu" />        <RelativeLayout            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:orientation="vertical" >            <include layout="@layout/layout_title_bar" />        </RelativeLayout>    </com.example.administrator.sss.SlideMenu></LinearLayout>

layout_title_bar.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="45.0dip"    android:background="@drawable/bg_title_bar"    android:gravity="center_vertical" >    <ImageView        android:id="@+id/title_bar_menu_btn"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerVertical="true"        android:layout_marginLeft="3.0dip"        android:layout_marginRight="3.0dip"        android:layout_marginTop="3.0dip"        android:gravity="center"        android:src="@drawable/ic_top_bar_category" />    <ImageView        android:layout_width="wrap_content"        android:layout_height="fill_parent"        android:layout_toRightOf="@id/title_bar_menu_btn"        android:background="@drawable/ic_top_divider" />    <TextView        android:id="@+id/title_bar_name"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:ellipsize="end"        android:gravity="center"        android:paddingLeft="75.0dip"        android:paddingRight="75.0dip"        android:singleLine="true"        android:text="数据分析"        android:textColor="#ffffff"        android:textSize="22sp" /></RelativeLayout>

layout_menu.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="240dip"    android:layout_height="fill_parent"    android:background="@drawable/bitmap_book_read_chapterlist_repeat"    android:orientation="vertical" >    <TextView        android:layout_width="240dip"        android:layout_height="28.0dip"        android:background="#ff313131"        android:gravity="center_vertical"        android:paddingLeft="15.0dip"        android:text="分类"        android:textColor="#ff959595"        android:textSize="14.0sp" />    <TextView        android:layout_width="240dip"        android:layout_height="50.0dip"        android:background="@drawable/selector_category_item"        android:clickable="true"        android:drawableLeft="@drawable/ic_category_mark"        android:drawablePadding="1.0dip"        android:gravity="center_vertical"        android:paddingLeft="15.0dip"        android:paddingRight="10.0dip"        android:text="网页分析"        android:textColor="#ff959595"        android:textSize="16.0sp"        android:id="@+id/web_ans"/>    <View        android:layout_width="240dip"        android:layout_height="2.0dip"        android:background="@drawable/ic_shelf_category_divider" />    <TextView        android:layout_width="240dip"        android:layout_height="50.0dip"        android:background="@drawable/selector_category_item"        android:clickable="true"        android:drawableLeft="@drawable/ic_category_mark"        android:drawablePadding="1.0dip"        android:gravity="center_vertical"        android:paddingLeft="15.0dip"        android:paddingRight="10.0dip"        android:text="数据分析"        android:textColor="#ff959595"        android:textSize="16.0sp"        android:id="@+id/data_ans"/>    <View        android:layout_width="240dip"        android:layout_height="2.0dip"        android:background="@drawable/ic_shelf_category_divider" />    <TextView        android:layout_width="240dip"        android:layout_height="50.0dip"        android:background="@drawable/selector_category_item"        android:clickable="true"        android:drawableLeft="@drawable/ic_category_mark"        android:drawablePadding="1.0dip"        android:gravity="center_vertical"        android:paddingLeft="15.0dip"        android:paddingRight="10.0dip"        android:text="浏览"        android:textColor="#ff959595"        android:textSize="16.0sp"        android:id="@+id/slide_show"/>    <View        android:layout_width="240dip"        android:layout_height="2.0dip"        android:background="@drawable/ic_shelf_category_divider" /></LinearLayout>

/////////////////////////////////////////////////////
slideview.java

package com.example.administrator.sss;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.ImageView;import com.example.administrator.sss.R;import com.example.administrator.sss.SlideMenu;public class slideview extends Activity implements OnClickListener{    private SlideMenu slideMenu;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.slide);        slideMenu = (SlideMenu) findViewById(R.id.slide_menu);        ImageView menuImg = (ImageView) findViewById(R.id.title_bar_menu_btn);        menuImg.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.title_bar_menu_btn:                if (slideMenu.isMainScreenShowing()) {                    slideMenu.openMenu();                } else {                    slideMenu.closeMenu();                }                break;        }    }}

slidemenu.java

package com.example.administrator.sss;import android.content.Context;import android.graphics.Canvas;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.VelocityTracker;import android.view.View;import android.view.ViewConfiguration;import android.view.ViewGroup;import android.widget.Scroller;public class SlideMenu extends ViewGroup {    public static final int SCREEN_MENU = 0;    public static final int SCREEN_MAIN = 1;    private static final int SCREEN_INVALID = -1;    private int mCurrentScreen;    private int mNextScreen = SCREEN_INVALID;    private Scroller mScroller;    private VelocityTracker mVelocityTracker;    private int mTouchSlop;    private float mLastMotionX;    private float mLastMotionY;    private final static int TOUCH_STATE_REST = 0;    private final static int TOUCH_STATE_SCROLLING = 1;    private static final int SNAP_VELOCITY = 1000;    public int mTouchState = TOUCH_STATE_REST;    private boolean mLocked;    private boolean mAllowLongPress;    public SlideMenu(Context context) {        this(context, null, 0);    }    public SlideMenu(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public SlideMenu(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        mScroller = new Scroller(getContext());        mCurrentScreen = SCREEN_MAIN;        mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        measureViews(widthMeasureSpec, heightMeasureSpec);    }    public void measureViews(int widthMeasureSpec, int heightMeasureSpec) {        View menuView = getChildAt(0);        menuView.measure(menuView.getLayoutParams().width + menuView.getLeft()                + menuView.getRight(), heightMeasureSpec);        View contentView = getChildAt(1);        contentView.measure(widthMeasureSpec, heightMeasureSpec);    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        int childCount = getChildCount();        if (childCount != 2) {            throw new IllegalStateException(                    "The childCount of SlidingMenu must be 2");        }        View menuView = getChildAt(0);        final int width = menuView.getMeasuredWidth();        menuView.layout(-width, 0, 0, menuView.getMeasuredHeight());        View contentView = getChildAt(1);        contentView.layout(0, 0, contentView.getMeasuredWidth(),                contentView.getMeasuredHeight());    }    @Override    protected void onFinishInflate() {        super.onFinishInflate();        View child;        for (int i = 0; i < getChildCount(); i++) {            child = getChildAt(i);            child.setFocusable(true);            child.setClickable(true);        }    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        if (mLocked) {            return true;        }        final int action = ev.getAction();        if ((action == MotionEvent.ACTION_MOVE)                && (mTouchState != TOUCH_STATE_REST)) {            return true;        }        final float x = ev.getX();        final float y = ev.getY();        switch (action) {        case MotionEvent.ACTION_MOVE:            final int xDiff = (int) Math.abs(x - mLastMotionX);            final int yDiff = (int) Math.abs(y - mLastMotionY);            final int touchSlop = mTouchSlop;            boolean xMoved = xDiff > touchSlop;            boolean yMoved = yDiff > touchSlop;            if (xMoved || yMoved) {                if (xMoved) {                    // Scroll if the user moved far enough along the X axis                    mTouchState = TOUCH_STATE_SCROLLING;                    enableChildrenCache();                }                // Either way, cancel any pending longpress                if (mAllowLongPress) {                    mAllowLongPress = false;                    // Try canceling the long press. It could also have been                    // scheduled                    // by a distant descendant, so use the mAllowLongPress flag                    // to block                    // everything                    final View currentScreen = getChildAt(mCurrentScreen);                    currentScreen.cancelLongPress();                }            }            break;        case MotionEvent.ACTION_DOWN:            // Remember location of down touch            mLastMotionX = x;            mLastMotionY = y;            mAllowLongPress = true;            mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST                    : TOUCH_STATE_SCROLLING;            break;        case MotionEvent.ACTION_CANCEL:        case MotionEvent.ACTION_UP:            // Release the drag            clearChildrenCache();            mTouchState = TOUCH_STATE_REST;            mAllowLongPress = false;            break;        }        /*         * The only time we want to intercept motion events is if we are in the         * drag mode.         */        return mTouchState != TOUCH_STATE_REST;    }    void enableChildrenCache() {        final int count = getChildCount();        for (int i = 0; i < count; i++) {            final View layout = (View) getChildAt(i);            layout.setDrawingCacheEnabled(true);        }    }    void clearChildrenCache() {        final int count = getChildCount();        for (int i = 0; i < count; i++) {            final View layout = (View) getChildAt(i);            layout.setDrawingCacheEnabled(false);        }    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        if (mLocked) {            return true;        }        if (mVelocityTracker == null) {            mVelocityTracker = VelocityTracker.obtain();        }        mVelocityTracker.addMovement(ev);        final int action = ev.getAction();        final float x = ev.getX();        switch (action) {        case MotionEvent.ACTION_DOWN:            /*             * If being flinged and user touches, stop the fling. isFinished             * will be false if being flinged.             */            if (!mScroller.isFinished()) {                mScroller.abortAnimation();            }            // Remember where the motion event started            mLastMotionX = x;            break;        case MotionEvent.ACTION_MOVE:            if (mTouchState == TOUCH_STATE_SCROLLING) {                // Scroll to follow the motion event                final int deltaX = (int) (mLastMotionX - x);                mLastMotionX = x;                if (deltaX < 0) {                    if (deltaX + getScrollX() >= -getChildAt(0).getWidth()) {                        scrollBy(deltaX, 0);                    }                } else if (deltaX > 0) {                    final int availableToScroll = getChildAt(                            getChildCount() - 1).getRight()                            - getScrollX() - getWidth();                    if (availableToScroll > 0) {                        scrollBy(Math.min(availableToScroll, deltaX), 0);                    }                }            }            break;        case MotionEvent.ACTION_UP:            if (mTouchState == TOUCH_STATE_SCROLLING) {                final VelocityTracker velocityTracker = mVelocityTracker;                velocityTracker.computeCurrentVelocity(1000);                int velocityX = (int) velocityTracker.getXVelocity();                if (velocityX > SNAP_VELOCITY && mCurrentScreen == SCREEN_MAIN) {                    // Fling hard enough to move left                    snapToScreen(SCREEN_MENU);                } else if (velocityX < -SNAP_VELOCITY                        && mCurrentScreen == SCREEN_MENU) {                    // Fling hard enough to move right                    snapToScreen(SCREEN_MAIN);                } else {                    snapToDestination();                }                if (mVelocityTracker != null) {                    mVelocityTracker.recycle();                    mVelocityTracker = null;                }            }            mTouchState = TOUCH_STATE_REST;            break;        case MotionEvent.ACTION_CANCEL:            mTouchState = TOUCH_STATE_REST;        }        return true;    }    @Override    public void computeScroll() {        if (mScroller.computeScrollOffset()) {            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());        } else if (mNextScreen != SCREEN_INVALID) {            mCurrentScreen = Math.max(0,                    Math.min(mNextScreen, getChildCount() - 1));            mNextScreen = SCREEN_INVALID;            clearChildrenCache();        }    }    @Override    public void scrollTo(int x, int y) {        super.scrollTo(x, y);        postInvalidate();    }    @Override    protected void dispatchDraw(Canvas canvas) {        final int scrollX = getScrollX();        super.dispatchDraw(canvas);        canvas.translate(scrollX, 0);    }    @Override    public boolean dispatchUnhandledMove(View focused, int direction) {        if (direction == View.FOCUS_LEFT) {            if (getCurrentScreen() > 0) {                snapToScreen(getCurrentScreen() - 1);                return true;            }        } else if (direction == View.FOCUS_RIGHT) {            if (getCurrentScreen() < getChildCount() - 1) {                snapToScreen(getCurrentScreen() + 1);                return true;            }        }        return super.dispatchUnhandledMove(focused, direction);    }    protected void snapToScreen(int whichScreen) {        enableChildrenCache();        whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));        boolean changingScreens = whichScreen != mCurrentScreen;        mNextScreen = whichScreen;        View focusedChild = getFocusedChild();        if (focusedChild != null && changingScreens                && focusedChild == getChildAt(mCurrentScreen)) {            focusedChild.clearFocus();        }        final int newX = (whichScreen - 1) * getChildAt(0).getWidth();        final int delta = newX - getScrollX();        mScroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta) * 2);        invalidate();    }    protected void snapToDestination() {        if (getScrollX() == 0) {            return;        }        final int screenWidth = getChildAt(0).getWidth();        final int whichScreen = (screenWidth + getScrollX() + (screenWidth / 2))                / screenWidth;        snapToScreen(whichScreen);    }    public int getCurrentScreen() {        return mCurrentScreen;    }    public boolean isMainScreenShowing() {        return mCurrentScreen == SCREEN_MAIN;    }    public void openMenu() {        mCurrentScreen = SCREEN_MENU;        snapToScreen(mCurrentScreen);    }    public void closeMenu() {        mCurrentScreen = SCREEN_MAIN;        snapToScreen(mCurrentScreen);    }    public void unlock() {        mLocked = false;    }    public void lock() {        mLocked = true;    }}

实现效果:
这里写图片描述

这里写图片描述

注意:资源可以自行添加

实例源码

百度云链接:http://pan.baidu.com/s/1eSxDXMM

0 0