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之上的版本
- android开源项目(一) AndroidSideMenu
- 开源项目:AndroidSideMenu(轻量级侧边栏)
- Android抽屉/侧滑菜单:开源AndroidSideMenu
- Android开源项目(一)
- Android开源项目(一)
- Android优秀开源项目(一)
- Android开源项目整合(一)
- Android开源项目SMSPopup学习 (一)
- Github上最火的Android开源项目(一)
- Android开源项目学习笔记(一)--ActionBarSherlock
- 最火的Android开源项目(一)
- android开源项目学习之(一)--ActionBarSherlock
- Android开源项目之Music (一)--- MusicBrowserActivity
- Android 常用开源项目及框架汇总(一)
- Android开源项目SlidingMenu的学习笔记(一)
- GitHub 优秀的 Android 开源项目(一)
- 最火的android开源项目(一)
- GitHub上最火的Android开源项目(一)
- 删除文件
- QThread 使用探讨
- 牛逼正则验证url
- OpenCV直方图用法示例
- .aidl文件注释的奇怪问题
- android开源项目(一) AndroidSideMenu
- ORACLE临时表GLOBAL TEMPORARY TABLE
- C 语言宏定义时紧跟#和##后面的宏不能展开的问题
- VS2012中的全部预定义键盘快捷键列表
- iOS图片拉伸技巧
- ViewController的生命周期
- Android/linux(earlysuspend、lateresume)睡眠唤醒机制简介
- Eclipse 使用小技巧(持续更新)
- Loopback接口和Null接口配置