SlidingMenu-布局实现

类:


package com.example.xlistview_slidingmenytestOne;


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.view.ViewParent;

import android.widget.Scroller;


/**

 * EffectSpace

 * @author lance

 *

 */

public class SlidingMenuView extends ViewGroup{

private static String LOG_TAG = "SlidingMenuView";

    private static final int INVALID_SCREEN = -1;


    private static final int SNAP_VELOCITY = 1000;


    private int mDefaultScreen = 1; 


    private int mCurrentScreen;

    private int mNextScreen = INVALID_SCREEN;

    private Scroller mScroller;

    private VelocityTracker mVelocityTracker;



    private float mLastMotionX;

    private float mLastMotionY;


    private final static int TOUCH_STATE_REST = 0;

    private final static int TOUCH_STATE_SCROLLING = 1;


    public int mTouchState = TOUCH_STATE_REST; 



    private boolean mAllowLongPress;

    private boolean mLocked;


    private int mTouchSlop;


    int totalWidth = 0;

    

    public SlidingMenuView(Context context, AttributeSet attrs) {

        this(context, attrs, 0);

    }

    public SlidingMenuView(Context context, AttributeSet attrs, int defStyle) {

        super(context, attrs, defStyle);

        initWorkspace();

        postDelayed(new Runnable(){

@Override

public void run() {

scrollTo(findViewById(R.id.left_sliding_tab).getWidth(), 0);

}

        }, 50);

    }

    private void initWorkspace() {

        mScroller = new Scroller(getContext());

        mCurrentScreen = mDefaultScreen;

   

        mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();

    }

    boolean isDefaultScreenShowing() {

        return mCurrentScreen == mDefaultScreen;

    }

    int getCurrentScreen() {

        return mCurrentScreen;

    }

    

    public void setCurrentScreen(int currentScreen) {

        mCurrentScreen = Math.max(0, Math.min(currentScreen, getChildCount() - 1));

        

        invalidate();

    }


    void showDefaultScreen() {

        setCurrentScreen(mDefaultScreen);

    }


    @Override

    public void computeScroll() {

     if (mScroller.computeScrollOffset()) {

         scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); 

        } else if (mNextScreen != INVALID_SCREEN) {

            mCurrentScreen = Math.max(0, Math.min(mNextScreen, getChildCount() - 1));

            mNextScreen = INVALID_SCREEN;

            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

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        measureViews(widthMeasureSpec, heightMeasureSpec);

        

    }

public void measureViews(int widthMeasureSpec, int heightMeasureSpec){

View v1 = findViewById(R.id.left_sliding_tab);

v1.measure(v1.getLayoutParams().width+v1.getLeft()+v1.getRight(), heightMeasureSpec);

View v2 = findViewById(R.id.sliding_body);

    v2.measure(widthMeasureSpec, heightMeasureSpec);

    

//     View v3 = findViewById(R.id.right_sliding_tab);

//     v3.measure(v3.getLayoutParams().width+v3.getLeft()+v3.getRight(), heightMeasureSpec);

}

    @Override

    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

        int childLeft = 0;


        final int count = getChildCount();

        for (int i = 0; i < count; i++) {

            final View child = getChildAt(i);

            if (child.getVisibility() != View.GONE) {

                final int childWidth = child.getMeasuredWidth();

                child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());

                childLeft += childWidth;

            }

        }

        totalWidth = childLeft;

    }


@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);

    }


    @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 (getScrollX() > 0) {

                    

                        scrollBy(Math.max(-getScrollX(), 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 > 0) {

                    // Fling hard enough to move left

                    snapToScreen(mCurrentScreen - 1);

                } else if (velocityX < -SNAP_VELOCITY && mCurrentScreen < getChildCount() - 1) {

                    // Fling hard enough to move right

                    snapToScreen(mCurrentScreen + 1);

                } else {

                    snapToDestination();

                }


                if (mVelocityTracker != null) {

                    mVelocityTracker.recycle();

                    mVelocityTracker = null;

                }

            }

            mTouchState = TOUCH_STATE_REST;

            break;

        case MotionEvent.ACTION_CANCEL:

            mTouchState = TOUCH_STATE_REST;

        }


        return true;

    }


    protected void snapToDestination() {


     int whichScreen = 0;

     int count = getChildCount();

     int start = 0;

     int end = 0;

     int viewWidth = 0;

     int tend = 0;

     int tstart = 0;

     final int scrollX = getScrollX();

     for(int i =0;i<count;i++){

     viewWidth = getChildAt(i).getWidth();

     tend = end + viewWidth/2;

     if(i != 0 ){

     viewWidth = getChildAt(i-1).getWidth();

     }

     tstart-=viewWidth;

     if(scrollX > tstart && scrollX < tend){

     break;

     }

     start+=viewWidth;

     end+=viewWidth;

     whichScreen++;

     }

        snapToScreen(whichScreen);

    }


    public 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();

        }

        

        int newX = 0;

        

        for(int i=0;i<whichScreen;i++){

         newX+=getChildAt(i).getWidth();

        }

        newX =Math.min(totalWidth - getWidth(), newX);

        final int delta = newX - getScrollX();

        mScroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta) * 2);

        invalidate();

    }

    

    public int getScreenForView(View v) {

        int result = -1;

        if (v != null) {

            ViewParent vp = v.getParent();

            int count = getChildCount();

            for (int i = 0; i < count; i++) {

                if (vp == getChildAt(i)) {

                    return i;

                }

            }

        }

        return result;

    }


    public void unlock() {

        mLocked = false;

    }


    public void lock() {

        mLocked = true;

    }

    

    void moveToDefaultScreen() {

        snapToScreen(mDefaultScreen);

        getChildAt(mDefaultScreen).requestFocus();

    }



@Override

protected void onFinishInflate() {

// TODO Auto-generated method stub

super.onFinishInflate();

View child;

for(int i=0;i<getChildCount();i++){

child = getChildAt(i);

child.setFocusable(true);

child.setClickable(true);

}

}

}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

    tools:context=".MainActivity" >


    <com.example.slidingmenutestOne.SlidingMenuView

        android:id="@+id/sliding_menu_view"

        android:layout_width="match_parent"

        android:layout_height="match_parent" >


        <LinearLayout

            android:id="@+id/left_sliding_tab"

            android:layout_width="wrap_content"

            android:layout_height="match_parent"

            android:background="#ffffcc"

            android:orientation="vertical" >


            <ListView

                android:id="@+id/lv_main_listview"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content" >

            </ListView>

        </LinearLayout>


        <FrameLayout

            android:id="@+id/sliding_body"

            android:layout_width="fill_parent"

            android:layout_height="fill_parent" >

        </FrameLayout>


        <LinearLayout

            android:id="@+id/right_sliding_tab"

            android:layout_width="wrap_content"

            android:background="#ccffff"

            android:orientation="vertical"

            android:layout_height="match_parent" >


             <Button

                android:text="隐藏菜单"

                android:onClick="hideMenu"

                android:layout_width="wrap_content"

         android:layout_height="wrap_content"/>

            <Button

                android:text="显示左菜单"

                android:onClick="showLeftMenu"

                android:layout_width="wrap_content"

         android:layout_height="wrap_content"/>

            <Button

                android:text="菜单项3"

                android:id="@+id/button3"

                android:onClick="changeTab3"

                android:layout_width="wrap_content"

         android:layout_height="wrap_content"/>

            <Button

                android:text="菜单项4"

                android:id="@+id/button4"

                 android:onClick="changeTab4"

                android:layout_width="wrap_content"

         android:layout_height="wrap_content"/>

            <Button

                android:text="这个按钮证明宽度是自适应的"

                android:id="@+id/button4"

                 android:onClick="changeTab4"

                android:layout_width="wrap_content"

         android:layout_height="wrap_content"/>

        </LinearLayout>

    </com.example.slidingmenutestOne.SlidingMenuView>


</LinearLayout>

~~~~~~~~~~~~~~~~~~~~~~~~~~~主Activity~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public class MainActivity extends ActivityGroup implements OnItemClickListener {


private ListView lv_main_listview;

private ArrayList<String> list;

private ArrayAdapter<String> adapter;

private SlidingMenuView sliding_menu_view;

private ViewGroup sliding_body;

private final Class[] activity = { TestOne.class };


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

initView();

}


private void initView() {


lv_main_listview = (ListView) findViewById(R.id.lv_main_listview);

data();

adapter = new ArrayAdapter<String>(this,

android.R.layout.simple_list_item_1, list);

lv_main_listview.setAdapter(adapter);

lv_main_listview.setOnItemClickListener(this);


sliding_menu_view = (SlidingMenuView) findViewById(R.id.sliding_menu_view);

sliding_body = (ViewGroup) findViewById(R.id.sliding_body);//来显示主内容的布局View

showDefaultTab();//默认加载的布局


}


private void showDefaultTab() {

// TODO Auto-generated method stub

Intent intent = new Intent(this, activity[0]);

LocalActivityManager lam = getLocalActivityManager();

View v = lam.startActivity(TestOne.class.getName(), intent)

.getDecorView();

sliding_body.removeAllViews();

sliding_body.addView(v);

}


private void data() {

// TODO Auto-generated method stub

list = new ArrayList<String>();

for (int i = 0; i < 5; i++) {

list.add("item" + i);

}

}


@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

return true;

}


@Override

public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {


Intent intent = new Intent(this, activity[arg2]);

LocalActivityManager lam = getLocalActivityManager();

View v = lam.startActivity(TestOne.class.getName(), intent)

.getDecorView();

sliding_body.removeAllViews();

sliding_body.addView(v);

}


public void hideMenu(View v) {

sliding_menu_view.snapToScreen(1);

}


public void showLeftMenu(View v) {


sliding_menu_view.snapToScreen(0); 

}


public void changeTab3(View v) {


}


public void changeTab4(View v) {


}


}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值