android开源项目(一) AndroidSideMenu

来源:互联网 发布:人工智能技术发展方向 编辑:程序博客网 时间:2024/04/30 19:24

SlidingMenu实现的效果如下:


   

       最近直接拿来用!很火的android开源项目真的很牛,作为菜鸟我也要学习大神们的经验,牛顿曾说过:“如果说我看的远,那是因为站在巨人的肩膀上”

AndroidSideMenu的来源是github 代码库中的开源项目:路径如下:git://github.com/dmitry-zaitsev/AndroidSideMenu.git

    那么怎样把github代码仓库中的项目导入到我们常用的Eclipse中呢?详细步骤请看下面:

1.首先安装EGit插件,如果已有可以略过。

   在eclipse的help中选择Eclipse Marketplace 在find中输入egit就会出现如下界面

 

点击install, 等待安装完毕

 

然后接受安装协议

然后eclipse就开始安装EGit

片刻后,EGit就可以安装好了,


2.克隆Git仓库上的代码到本地电脑,并在Eclipse中查看Git中的工程

1.步骤如下:file—Import---Git--ProjectFromGit--URI


2.从git://github.com/dmitry-zaitsev/AndroidSideMenu.git 地址中clone  androidslidingMenu项目,

默认next 后出现以下,


继续默认next,选择克隆代码存放的位置


clon完毕后会出现以下选择界面


这样就可以导入从Git上下载的工程了


在eclipse中的布局如下


当我们导入从Git中下载好后的东西,我们却发现运行不了,我在网上也收了很多方法,可惜可有收到怎样解决的方法,如果谁有好的方法可以给我说说,

我的解决方法如下:

3.创建android工程

新建一个android工程,然后将布局,实现的代码等复制进去,修改修改最后终于给弄好了,不过呢,这个android工程要求建立的版本的在android 3.0之上的才可以运行,我试着建立常用的2.3.3 或则3.0以下的版本,结果发现有点不兼容...不知道那些牛逼的应用中怎样解决这个兼容性的问题的...

我创建好的工程源码下载地址:点击打开链接

实现的效果如下:


实现的布局如下:

<com.nyist.net.SlideHolder xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/slideHolder"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    tools:context=".Test3Activity" >    <ScrollView        android:layout_width="280dp"        android:layout_height="fill_parent"        android:background="@drawable/navigation_background" >        <LinearLayout            android:layout_width="280dp"            android:layout_height="wrap_content"             android:drawableRight="@drawable/btn_right"            android:padding="1dp"            android:orientation="vertical" >            <Button                android:layout_width="fill_parent"                android:layout_height="wrap_content"                android:text="我的音乐" />            <Button                android:layout_width="fill_parent"                android:layout_height="wrap_content"                 android:drawableRight="@drawable/btn_right"                android:text="推荐" />            <Button                android:layout_width="fill_parent"                android:layout_height="wrap_content"                 android:drawableRight="@drawable/btn_right"                android:text="歌单" />            <Button                android:layout_width="fill_parent"                android:layout_height="wrap_content"                 android:drawableRight="@drawable/btn_right"                android:text="搜索" />            <Button                android:layout_width="fill_parent"                android:layout_height="wrap_content"                 android:drawableRight="@drawable/btn_right"                android:text="排行榜" />            <Button                android:layout_width="fill_parent"                android:layout_height="wrap_content"                 android:drawableRight="@drawable/btn_right"                android:text="歌手" />            <Button                android:layout_width="fill_parent"                android:layout_height="wrap_content"                android:drawableRight="@drawable/btn_right"                android:text="淘歌" />        </LinearLayout>    </ScrollView>    <RelativeLayout        android:layout_width="fill_parent"        android:layout_height="fill_parent" >        <TextView            android:id="@+id/textView"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerHorizontal="true"            android:layout_centerVertical="true"            android:text="@string/swipe"                       android:background="@drawable/guider_03"            android:textSize="25sp" />    </RelativeLayout></com.nyist.net.SlideHolder>

布局引用的代码如下:

package com.nyist.net;import java.util.LinkedList;import java.util.Queue;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.PorterDuff.Mode;import android.graphics.Rect;import android.graphics.Region.Op;import android.os.Build;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.animation.Animation;import android.view.animation.DecelerateInterpolator;import android.view.animation.Transformation;import android.widget.FrameLayout;public class SlideHolder extends FrameLayout {public final static int DIRECTION_LEFT = 1;public final static int DIRECTION_RIGHT = -1;protected final static int MODE_READY = 0;protected final static int MODE_SLIDE = 1;protected final static int MODE_FINISHED = 2;private Bitmap mCachedBitmap;private Canvas mCachedCanvas;private Paint mCachedPaint;private View mMenuView;private int mMode = MODE_READY;private int mDirection = DIRECTION_LEFT;private int mOffset = 0;private int mStartOffset;private int mEndOffset;private boolean mEnabled = true;private boolean mInterceptTouch = true;private boolean mAlwaysOpened = false;private boolean mDispatchWhenOpened = false;private Queue<Runnable> mWhenReady = new LinkedList<Runnable>();private OnSlideListener mListener;public SlideHolder(Context context) {super(context);initView();}public SlideHolder(Context context, AttributeSet attrs) {super(context, attrs);initView();}public SlideHolder(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);initView();}private void initView() {mCachedPaint = new Paint(Paint.ANTI_ALIAS_FLAG| Paint.FILTER_BITMAP_FLAG| Paint.DITHER_FLAG);}@Overridepublic void setEnabled(boolean enabled) {mEnabled = enabled;}@Overridepublic boolean isEnabled() {return mEnabled;}/** *  * @param direction - direction in which SlideHolder opens. Can be: DIRECTION_LEFT, DIRECTION_RIGHT */public void setDirection(int direction) {closeImmediately();mDirection = direction;}/** *  * @param allow - if false, SlideHolder won't react to swiping gestures (but still will be able to work by manually invoking mathods) */public void setAllowInterceptTouch(boolean allow) {mInterceptTouch = allow;}public boolean isAllowedInterceptTouch() {return mInterceptTouch;}/** *  * @param dispatch - if true, in open state SlideHolder will dispatch touch events to main layout (in other words - it will be clickable) */public void setDispatchTouchWhenOpened(boolean dispatch) {mDispatchWhenOpened = dispatch;}public boolean isDispatchTouchWhenOpened() {return mDispatchWhenOpened;}/** *  * @param opened - if true, SlideHolder will always be in opened state (which means that swiping won't work) */public void setAlwaysOpened(boolean opened) {mAlwaysOpened = opened;requestLayout();}public int getMenuOffset() {return mOffset;}public void setOnSlideListener(OnSlideListener lis) {mListener = lis;}public boolean isOpened() {return mAlwaysOpened || mMode == MODE_FINISHED;}public void toggle(boolean immediately) {if(immediately) {toggleImmediately();} else {toggle();}}public void toggle() {if(isOpened()) {close();} else {open();}}public void toggleImmediately() {if(isOpened()) {closeImmediately();} else {openImmediately();}}public boolean open() {if(isOpened() || mAlwaysOpened || mMode == MODE_SLIDE) {return false;}if(!isReadyForSlide()) {mWhenReady.add(new Runnable() {@Overridepublic void run() {open();}});return true;}initSlideMode();Animation anim = new SlideAnimation(mOffset, mEndOffset);anim.setAnimationListener(mOpenListener);startAnimation(anim);invalidate();return true;}public boolean openImmediately() {if(isOpened() || mAlwaysOpened || mMode == MODE_SLIDE) {return false;}if(!isReadyForSlide()) {mWhenReady.add(new Runnable() {@Overridepublic void run() {openImmediately();}});return true;}mMenuView.setVisibility(View.VISIBLE);mMode = MODE_FINISHED;requestLayout();if(mListener != null) {mListener.onSlideCompleted(true);}return true;}public boolean close() {if(!isOpened() || mAlwaysOpened || mMode == MODE_SLIDE) {return false;}if(!isReadyForSlide()) {mWhenReady.add(new Runnable() {@Overridepublic void run() {close();}});return true;}initSlideMode();Animation anim = new SlideAnimation(mOffset, mEndOffset);anim.setAnimationListener(mCloseListener);startAnimation(anim);invalidate();return true;}public boolean closeImmediately() {if(!isOpened() || mAlwaysOpened || mMode == MODE_SLIDE) {return false;}if(!isReadyForSlide()) {mWhenReady.add(new Runnable() {@Overridepublic void run() {closeImmediately();}});return true;}mMenuView.setVisibility(View.GONE);mMode = MODE_READY;requestLayout();if(mListener != null) {mListener.onSlideCompleted(false);}return true;}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {final int parentLeft = 0;final int parentTop = 0;final int parentRight = r - l;final int parentBottom = b - t;View menu = getChildAt(0);int menuWidth = menu.getMeasuredWidth();if(mDirection == DIRECTION_LEFT) {menu.layout(parentLeft, parentTop, parentLeft+menuWidth, parentBottom);} else {menu.layout(parentRight-menuWidth, parentTop, parentRight, parentBottom);}if(mAlwaysOpened) {if(mDirection == DIRECTION_LEFT) {mOffset = menuWidth;} else {mOffset = 0;}} else if(mMode == MODE_FINISHED) {mOffset = mDirection*menuWidth;} else if(mMode == MODE_READY) {mOffset = 0;}View main = getChildAt(1);main.layout(parentLeft + mOffset,parentTop,parentLeft + mOffset + main.getMeasuredWidth(),parentBottom);invalidate();Runnable rn;        while((rn = mWhenReady.poll()) != null) {        rn.run();        }}private boolean isReadyForSlide() {return (getWidth() > 0 && getHeight() > 0);}@Override    protected void onMeasure(int wSp, int hSp) {mMenuView = getChildAt(0);        if(mAlwaysOpened) {            View main = getChildAt(1);                        if(mMenuView != null && main != null) {            measureChild(mMenuView, wSp, hSp);                LayoutParams lp = (LayoutParams) main.getLayoutParams();                                if(mDirection == DIRECTION_LEFT) {                lp.leftMargin = mMenuView.getMeasuredWidth();                } else {                lp.rightMargin = mMenuView.getMeasuredWidth();                }            }        }                super.onMeasure(wSp, hSp);    }private byte mFrame = 0;@Overrideprotected void dispatchDraw(Canvas canvas) {try {if(mMode == MODE_SLIDE) {View main = getChildAt(1);if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {/* * On new versions we redrawing main layout only * if it's marked as dirty  */if(main.isDirty()) {mCachedCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);main.draw(mCachedCanvas);}} else {/* * On older versions we just redrawing our cache * every 5th frame */if(++mFrame % 5 == 0) {mCachedCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);main.draw(mCachedCanvas);}}/* * Draw only visible part of menu */View menu = getChildAt(0);final int scrollX = menu.getScrollX();final int scrollY = menu.getScrollY();canvas.save();if(mDirection == DIRECTION_LEFT) {canvas.clipRect(0, 0, mOffset, menu.getHeight(), Op.REPLACE);} else {int menuWidth = menu.getWidth();int menuLeft = menu.getLeft();canvas.clipRect(menuLeft+menuWidth+mOffset, 0, menuLeft+menuWidth, menu.getHeight());}canvas.translate(menu.getLeft(), menu.getTop());canvas.translate(-scrollX, -scrollY);menu.draw(canvas);canvas.restore();canvas.drawBitmap(mCachedBitmap, mOffset, 0, mCachedPaint);} else {if(!mAlwaysOpened && mMode == MODE_READY) {        mMenuView.setVisibility(View.GONE);        }super.dispatchDraw(canvas);}} catch(IndexOutOfBoundsException e) {/* * Possibility of crashes on some devices (especially on Samsung). * Usually, when ListView is empty. */}}private int mHistoricalX = 0;private boolean mCloseOnRelease = false;@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {if(((!mEnabled || !mInterceptTouch) && mMode == MODE_READY) || mAlwaysOpened) {return super.dispatchTouchEvent(ev);}if(mMode != MODE_FINISHED) {onTouchEvent(ev);if(mMode != MODE_SLIDE) {super.dispatchTouchEvent(ev);} else {MotionEvent cancelEvent = MotionEvent.obtain(ev);cancelEvent.setAction(MotionEvent.ACTION_CANCEL);super.dispatchTouchEvent(cancelEvent);cancelEvent.recycle();}return true;} else {final int action = ev.getAction();Rect rect = new Rect();View menu = getChildAt(0);menu.getHitRect(rect);if(!rect.contains((int) ev.getX(), (int) ev.getY())) {if (action == MotionEvent.ACTION_UP && mCloseOnRelease && !mDispatchWhenOpened) {close();mCloseOnRelease = false;} else {if(action == MotionEvent.ACTION_DOWN && !mDispatchWhenOpened) {mCloseOnRelease = true;}onTouchEvent(ev);}if(mDispatchWhenOpened) {super.dispatchTouchEvent(ev);}return true;} else {onTouchEvent(ev);ev.offsetLocation(-menu.getLeft(), -menu.getTop());menu.dispatchTouchEvent(ev);return true;}}}private boolean handleTouchEvent(MotionEvent ev) {if(!mEnabled) {return false;}float x = ev.getX();if(ev.getAction() == MotionEvent.ACTION_DOWN) {mHistoricalX = (int) x;return true;}if(ev.getAction() == MotionEvent.ACTION_MOVE) {float diff = x - mHistoricalX;if((mDirection*diff > 50 && mMode == MODE_READY) || (mDirection*diff < -50 && mMode == MODE_FINISHED)) {mHistoricalX = (int) x;initSlideMode();} else if(mMode == MODE_SLIDE) {mOffset += diff;mHistoricalX = (int) x;if(!isSlideAllowed()) {finishSlide();}} else {return false;}}if(ev.getAction() == MotionEvent.ACTION_UP) {if(mMode == MODE_SLIDE) {finishSlide();}mCloseOnRelease = false;return false;}return mMode == MODE_SLIDE;}@Overridepublic boolean onTouchEvent(MotionEvent ev) {boolean handled = handleTouchEvent(ev);invalidate();return handled;}private void initSlideMode() {mCloseOnRelease = false;View v = getChildAt(1);if(mMode == MODE_READY) {mStartOffset = 0;mEndOffset = mDirection*getChildAt(0).getWidth();} else {mStartOffset = mDirection*getChildAt(0).getWidth();mEndOffset = 0;}mOffset = mStartOffset;if(mCachedBitmap == null || mCachedBitmap.isRecycled() || mCachedBitmap.getWidth() != v.getWidth()) {mCachedBitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);mCachedCanvas = new Canvas(mCachedBitmap);} else {mCachedCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);}v.setVisibility(View.VISIBLE);mCachedCanvas.translate(-v.getScrollX(), -v.getScrollY());v.draw(mCachedCanvas);mMode = MODE_SLIDE;mMenuView.setVisibility(View.VISIBLE);}private boolean isSlideAllowed() {return (mDirection*mEndOffset > 0 && mDirection*mOffset < mDirection*mEndOffset && mDirection*mOffset >= mDirection*mStartOffset)|| (mEndOffset == 0 && mDirection*mOffset > mDirection*mEndOffset && mDirection*mOffset <= mDirection*mStartOffset);}private void completeOpening() {mOffset = mDirection*mMenuView.getWidth();requestLayout();post(new Runnable() {@Overridepublic void run() {mMode = MODE_FINISHED;mMenuView.setVisibility(View.VISIBLE);}});if(mListener != null) {mListener.onSlideCompleted(true);}}private Animation.AnimationListener mOpenListener = new Animation.AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationRepeat(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {completeOpening();}};private void completeClosing() {mOffset = 0;requestLayout();post(new Runnable() {@Overridepublic void run() {mMode = MODE_READY;mMenuView.setVisibility(View.GONE);}});if(mListener != null) {mListener.onSlideCompleted(false);}}private Animation.AnimationListener mCloseListener = new Animation.AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationRepeat(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {completeClosing();}};private void finishSlide() {if(mDirection*mEndOffset > 0) {if(mDirection*mOffset > mDirection*mEndOffset/2) {if(mDirection*mOffset > mDirection*mEndOffset) mOffset = mEndOffset;Animation anim = new SlideAnimation(mOffset, mEndOffset);anim.setAnimationListener(mOpenListener);startAnimation(anim);} else {if(mDirection*mOffset < mDirection*mStartOffset) mOffset = mStartOffset;Animation anim = new SlideAnimation(mOffset, mStartOffset);anim.setAnimationListener(mCloseListener);startAnimation(anim);}} else {if(mDirection*mOffset < mDirection*mStartOffset/2) {if(mDirection*mOffset < mDirection*mEndOffset) mOffset = mEndOffset;Animation anim = new SlideAnimation(mOffset, mEndOffset);anim.setAnimationListener(mCloseListener);startAnimation(anim);} else {if(mDirection*mOffset > mDirection*mStartOffset) mOffset = mStartOffset;Animation anim = new SlideAnimation(mOffset, mStartOffset);anim.setAnimationListener(mOpenListener);startAnimation(anim);}}}private class SlideAnimation extends Animation {private static final float SPEED = 0.6f;private float mStart;private float mEnd;public SlideAnimation(float fromX, float toX) {mStart = fromX;mEnd = toX;setInterpolator(new DecelerateInterpolator());float duration = Math.abs(mEnd - mStart) / SPEED;setDuration((long) duration);}@Overrideprotected void applyTransformation(float interpolatedTime, Transformation t) {super.applyTransformation(interpolatedTime, t);float offset = (mEnd - mStart) * interpolatedTime + mStart;mOffset = (int) offset;postInvalidate();}}public static interface OnSlideListener {public void onSlideCompleted(boolean opened);}}


ps:这个工程要求是在android 3.0之上的版本

原创粉丝点击