SlidingDrawerDemo.java:

package org.lee.android;import org.lee.android.ExpoInterpolator.EasingType;import org.lee.android.ExpoInterpolator.ExpoInterpolator;import org.lee.android.widget.Panel;import org.lee.android.widget.Panel.OnPanelListener;import android.app.Activity;import android.os.Bundle;import android.util.Log;public class SlidingDrawerDemo extends Activity implements OnPanelListener{@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);super.setContentView(R.layout.sildingdrawer);Panel panel;                panel = (Panel) findViewById(R.id.topPanel);        panel.setOnPanelListener(this);        panel.setInterpolator(new ExpoInterpolator(EasingType.OUT));        }public void onPanelClosed(Panel panel) {String panelName = getResources().getResourceEntryName(panel.getId());Log.d("TestPanels", "Panel [" + panelName + "] closed");}public void onPanelOpened(Panel panel) {String panelName = getResources().getResourceEntryName(panel.getId());Log.d("TestPanels", "Panel [" + panelName + "] opened");}}

sildingdrawer.xml:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:panel="http://schemas.android.com/apk/res/org.lee.android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:background="#ffffff"    android:orientation="vertical" >    <RelativeLayout        android:id="@+id/listHeader"        android:layout_width="fill_parent"        android:layout_height="48dp"        android:layout_alignParentTop="true"        android:background="#F7BAD6" >        <ImageView            android:id="@+id/header_back"            android:layout_width="12dp"            android:layout_height="30dp"            android:layout_centerVertical="true"            android:layout_marginLeft="12px"            android:background="@drawable/header_back" />        <TextView            android:id="@+id/shop_title"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerVertical="true"            android:layout_marginLeft="15px"            android:layout_toRightOf="@id/header_back"            android:text="标题"            android:textColor="#ffffff"            android:textSize="28px" />        <ImageView            android:id="@+id/three_rect"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:layout_centerVertical="true"            android:layout_marginRight="12dp"            android:background="@drawable/three_rect" />    </RelativeLayout>    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@id/listHeader"        android:orientation="vertical" >        <!-- tab标签栏 -->        <LinearLayout            android:id="@+id/header"            android:layout_width="fill_parent"            android:layout_height="40dp"            android:background="#FFFFFF" >            <TextView                android:id="@+id/text1"                android:layout_width="fill_parent"                android:layout_height="fill_parent"                android:layout_weight="1.0"                android:gravity="center"                android:text="页卡1"                android:textColor="#000000"                android:textSize="22.0dip" />            <View                android:layout_width="2dip"                android:layout_height="30dip"                android:layout_gravity="center_vertical"                android:background="#D7D7D7" />            <TextView                android:id="@+id/text2"                android:layout_width="fill_parent"                android:layout_height="fill_parent"                android:layout_weight="1.0"                android:gravity="center"                android:text="页卡2"                android:textColor="#000000"                android:textSize="22.0dip" />            <View                android:layout_width="2dip"                android:layout_height="30dip"                android:layout_gravity="center_vertical"                android:background="#D7D7D7" />            <TextView                android:id="@+id/text3"                android:layout_width="fill_parent"                android:layout_height="fill_parent"                android:layout_weight="1.0"                android:gravity="center"                android:text="页卡3"                android:textColor="#000000"                android:textSize="22.0dip" />            <View                android:layout_width="2dip"                android:layout_height="30dip"                android:layout_gravity="center_vertical"                android:background="#D7D7D7" />            <TextView                android:id="@+id/text4"                android:layout_width="fill_parent"                android:layout_height="fill_parent"                android:layout_weight="1.0"                android:gravity="center"                android:text="页卡4"                android:textColor="#000000"                android:textSize="22.0dip" />            <!-- 最右侧分类标识 -->            <FrameLayout                android:layout_width="50dp"                android:layout_height="fill_parent"                android:layout_marginRight="5dp" >            </FrameLayout>        </LinearLayout>        <TextView            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:layout_below="@id/header"            android:background="#ff6600"            android:text="和哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈和"            android:textColor="#ffffff"            android:textSize="18sp"            android:textStyle="bold" />        <org.lee.android.widget.Panel            android:id="@+id/topPanel"            android:layout_width="fill_parent"            android:layout_height="wrap_content"            android:gravity="top|right"            android:paddingBottom="4dip"            panel:animationDuration="1200"            panel:content="@+id/panelContent"            panel:handle="@+id/panelHandle"            panel:linearFlying="true"            panel:position="top" >            <TextView                android:id="@+id/panelHandle"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_marginRight="10dp"                android:background="@drawable/up"                android:gravity="center"                android:padding="5dp"                android:text="分类"                android:textColor="#ffffff"                android:textSize="15sp" />            <LinearLayout                android:id="@+id/panelContent"                android:layout_width="fill_parent"                android:layout_height="wrap_content"                android:orientation="vertical" >                <CheckBox                    android:layout_width="fill_parent"                    android:layout_height="60dip"                    android:background="#688"                    android:gravity="center"                    android:text="top check box" />                <TextView                    android:layout_width="fill_parent"                    android:layout_height="wrap_content"                    android:background="#323299"                    android:gravity="center"                    android:padding="4dip"                    android:text="Bounce\nInterpolator"                    android:textColor="#eee"                    android:textSize="16dip"                    android:textStyle="bold" />            </LinearLayout>        </org.lee.android.widget.Panel>    </RelativeLayout></RelativeLayout>

EasingType.java:

package org.lee.android.ExpoInterpolator;public class EasingType {public static final int IN = 0;public static final int OUT = 1;public static final int INOUT = 2;}

ExpoInterpolator.java:

package org.lee.android.ExpoInterpolator;/* * * Open source under the BSD License.  *  * Copyright © 2001 Robert Penner * All rights reserved. *  * Redistribution and use in source and binary forms, with or without modification,  * are permitted provided that the following conditions are met: *  * Redistributions of source code must retain the above copyright notice, this list of  * conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list  * of conditions and the following disclaimer in the documentation and/or other materials  * provided with the distribution. *  * Neither the name of the author nor the names of contributors may be used to endorse  * or promote products derived from this software without specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  * OF THE POSSIBILITY OF SUCH DAMAGE.  * */import android.view.animation.Interpolator;public class ExpoInterpolator implements Interpolator {private int type;public ExpoInterpolator(int type) {this.type = type;}public float getInterpolation(float t) {if (type == EasingType.IN) {return in(t);} elseif (type == EasingType.OUT) {return out(t);} elseif (type == EasingType.INOUT) {return inout(t);}return 0;}private float in(float t) {return (float) ((t==0) ? 0 : Math.pow(2, 10 * (t - 1)));}private float out(float t) {return (float) ((t>=1) ? 1 : (-Math.pow(2, -10 * t) + 1));}private float inout(float t) {if (t == 0) {return 0;}if (t >= 1) {return 1;}t *= 2;if (t < 1) {return (float) (0.5f * Math.pow(2, 10 * (t - 1)));} else {return (float) (0.5f * (-Math.pow(2, -10 * --t) + 2));}}}

Panel.java:

package org.lee.android.widget;import org.lee.android.R;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.util.Log;import android.view.GestureDetector;import android.view.GestureDetector.OnGestureListener;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.ViewParent;import android.view.animation.Animation;import android.view.animation.Animation.AnimationListener;import android.view.animation.Interpolator;import android.view.animation.LinearInterpolator;import android.view.animation.TranslateAnimation;import android.widget.FrameLayout;import android.widget.LinearLayout;public class Panel extends LinearLayout {    private static final String TAG = "Panel";/**     * Callback invoked when the panel is opened/closed.     */    public static interface OnPanelListener {        /**         * Invoked when the panel becomes fully closed.         */        public void onPanelClosed(Panel panel);        /**         * Invoked when the panel becomes fully opened.         */        public void onPanelOpened(Panel panel);    }        private boolean mIsShrinking;private int mPosition;private int mDuration;private boolean mLinearFlying;private int mHandleId;private int mContentId;private View mHandle;private View mContent;private Drawable mOpenedHandle;private Drawable mClosedHandle;private float mTrackX;private float mTrackY;private float mVelocity;private OnPanelListener panelListener;public static final int TOP = 0;public static final int BOTTOM = 1;public static final int LEFT = 2;public static final int RIGHT = 3;private enum State {ABOUT_TO_ANIMATE,ANIMATING,READY,TRACKING,FLYING,};private State mState;private Interpolator mInterpolator;private GestureDetector mGestureDetector;private int mContentHeight;private int mContentWidth;private int mOrientation;private float mWeight;private PanelOnGestureListener mGestureListener;private boolean mBringToFront;public Panel(Context context, AttributeSet attrs) {super(context, attrs);TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Panel);mDuration = a.getInteger(R.styleable.Panel_animationDuration, 750);// duration defaults to 750 msmPosition = a.getInteger(R.styleable.Panel_position, BOTTOM);// position defaults to BOTTOMmLinearFlying = a.getBoolean(R.styleable.Panel_linearFlying, false);// linearFlying defaults to falsemWeight = a.getFraction(R.styleable.Panel_weight, 0, 1, 0.0f);// weight defaults to 0.0if (mWeight < 0 || mWeight > 1) {mWeight = 0.0f;Log.w(TAG, a.getPositionDescription() + ": weight must be > 0 and <= 1");}mOpenedHandle = a.getDrawable(R.styleable.Panel_openedHandle);mClosedHandle = a.getDrawable(R.styleable.Panel_closedHandle);RuntimeException e = null;mHandleId = a.getResourceId(R.styleable.Panel_handle, 0);if (mHandleId == 0) {e = new IllegalArgumentException(a.getPositionDescription() + ": The handle attribute is required and must refer to a valid child.");}mContentId = a.getResourceId(R.styleable.Panel_content, 0);if (mContentId == 0) {e = new IllegalArgumentException(a.getPositionDescription() + ": The content attribute is required and must refer to a valid child.");}a.recycle();if (e != null) {throw e;}mOrientation = (mPosition == TOP || mPosition == BOTTOM)? VERTICAL : HORIZONTAL;setOrientation(mOrientation);mState = State.READY;mGestureListener = new PanelOnGestureListener();mGestureDetector = new GestureDetector(mGestureListener);mGestureDetector.setIsLongpressEnabled(false);// i DON'T really know why i need this...setBaselineAligned(false);}    /**     * Sets the listener that receives a notification when the panel becomes open/close.     *     * @param onPanelListener The listener to be notified when the panel is opened/closed.     */    public void setOnPanelListener(OnPanelListener onPanelListener) {        panelListener = onPanelListener;    }        /**     * Gets Panel's mHandle     *      * @return Panel's mHandle     */    public View getHandle() {return mHandle;}        /**     * Gets Panel's mContent     *      * @return Panel's mContent      */    public View getContent() {return mContent;}        /**     * Sets the acceleration curve for panel's animation.     *      * @param i The interpolator which defines the acceleration curve      */    public void setInterpolator(Interpolator i) {    mInterpolator = i;     }    /** * Set the opened state of Panel.     *      * @param open True if Panel is to be opened, false if Panel is to be closed. * @param animate True if use animation, false otherwise. * * @return True if operation was performed, false otherwise. *  */public boolean setOpen(boolean open, boolean animate) {if (mState == State.READY && isOpen() ^ open) {mIsShrinking = !open;if (animate) {mState = State.ABOUT_TO_ANIMATE;if (!mIsShrinking) {// this could make flicker so we test mState in dispatchDraw()// to see if is equal to ABOUT_TO_ANIMATEmContent.setVisibility(VISIBLE);}post(startAnimation);} else {mContent.setVisibility(open? VISIBLE : GONE);postProcess();}return true;}return false;}    /**     * Returns the opened status for Panel.     *      * @return True if Panel is opened, false otherwise.     */public boolean isOpen() {return mContent.getVisibility() == VISIBLE;}@Overrideprotected void onFinishInflate() {super.onFinishInflate();mHandle = findViewById(mHandleId);if (mHandle == null) {String name = getResources().getResourceEntryName(mHandleId);            throw new RuntimeException("Your Panel must have a child View whose id attribute is 'R.id." + name + "'");}mHandle.setOnTouchListener(touchListener);mHandle.setOnClickListener(clickListener);mContent = findViewById(mContentId);if (mContent == null) {String name = getResources().getResourceEntryName(mHandleId);            throw new RuntimeException("Your Panel must have a child View whose id attribute is 'R.id." + name + "'");}// reposition childrenremoveView(mHandle);removeView(mContent);if (mPosition == TOP || mPosition == LEFT) {addView(mContent);addView(mHandle);} else {addView(mHandle);addView(mContent);}if (mClosedHandle != null) {mHandle.setBackgroundDrawable(mClosedHandle);}mContent.setClickable(true);mContent.setVisibility(GONE);if (mWeight > 0) {ViewGroup.LayoutParams params = mContent.getLayoutParams();if (mOrientation == VERTICAL) {params.height = ViewGroup.LayoutParams.FILL_PARENT;} else {params.width = ViewGroup.LayoutParams.FILL_PARENT;}mContent.setLayoutParams(params);}}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();ViewParent parent = getParent();if (parent != null && parent instanceof FrameLayout) {mBringToFront = true;}}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {if (mWeight > 0 && mContent.getVisibility() == VISIBLE) {View parent = (View) getParent();if (parent != null) {if (mOrientation == VERTICAL) {heightMeasureSpec = MeasureSpec.makeMeasureSpec((int) (parent.getHeight() * mWeight), MeasureSpec.EXACTLY);} else {widthMeasureSpec = MeasureSpec.makeMeasureSpec((int) (parent.getWidth() * mWeight), MeasureSpec.EXACTLY);}}}super.onMeasure(widthMeasureSpec, heightMeasureSpec);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);mContentWidth = mContent.getWidth();mContentHeight = mContent.getHeight();}@Overrideprotected void dispatchDraw(Canvas canvas) {//String name = getResources().getResourceEntryName(getId());//Log.d(TAG, name + " ispatchDraw " + mState);// this is why 'mState' was added:// avoid flicker before animation startif (mState == State.ABOUT_TO_ANIMATE && !mIsShrinking) {int delta = mOrientation == VERTICAL? mContentHeight : mContentWidth;if (mPosition == LEFT || mPosition == TOP) {delta = -delta;}if (mOrientation == VERTICAL) {canvas.translate(0, delta);} else {canvas.translate(delta, 0);}}if (mState == State.TRACKING || mState == State.FLYING) {canvas.translate(mTrackX, mTrackY);}super.dispatchDraw(canvas);}private float ensureRange(float v, int min, int max) {v = Math.max(v, min);v = Math.min(v, max);return v;}OnTouchListener touchListener = new OnTouchListener() {float touchX, touchY;public boolean onTouch(View v, MotionEvent event) {if (mState == State.ANIMATING) {// we are animatingreturn false;}int action = event.getAction();if (action == MotionEvent.ACTION_DOWN) {if (mBringToFront) {bringToFront();}touchX = event.getX();touchY = event.getY();}if (!mGestureDetector.onTouchEvent(event)) {if (action == MotionEvent.ACTION_UP) {// tup up after scrollingint size = (int) (Math.abs(touchX - event.getX()) + Math.abs(touchY - event.getY()));if (size == mContentWidth || size == mContentHeight) {mState = State.ABOUT_TO_ANIMATE;//Log.e("size", String.valueOf(size));//Log.e(String.valueOf(mContentWidth),String.valueOf(mContentHeight));}post(startAnimation);}}return false;}};OnClickListener clickListener = new OnClickListener() {public void onClick(View v) {if (mBringToFront) {bringToFront();}if (initChange()) {post(startAnimation);}}};public boolean initChange() {if (mState != State.READY) {// we are animating or just about to animatereturn false;}mState = State.ABOUT_TO_ANIMATE;mIsShrinking = mContent.getVisibility() == VISIBLE;if (!mIsShrinking) {// this could make flicker so we test mState in dispatchDraw()// to see if is equal to ABOUT_TO_ANIMATEmContent.setVisibility(VISIBLE);}return true;}Runnable startAnimation = new Runnable() {public void run() {// this is why we post this Runnable couple of lines above:// now its save to use mContent.getHeight() && mContent.getWidth()TranslateAnimation animation;int fromXDelta = 0, toXDelta = 0, fromYDelta = 0, toYDelta = 0;if (mState == State.FLYING) {mIsShrinking = (mPosition == TOP || mPosition == LEFT) ^ (mVelocity > 0);}int calculatedDuration;if (mOrientation == VERTICAL) {int height = mContentHeight;if (!mIsShrinking) {fromYDelta = mPosition == TOP? -height : height;} else {toYDelta = mPosition == TOP? -height : height;}if (mState == State.TRACKING) {if (Math.abs(mTrackY - fromYDelta) < Math.abs(mTrackY - toYDelta)) {mIsShrinking = !mIsShrinking;toYDelta = fromYDelta;}fromYDelta = (int) mTrackY;} elseif (mState == State.FLYING) {fromYDelta = (int) mTrackY;}// for FLYING events we calculate animation duration based on flying velocity// also for very high velocity make sure duration >= 20 msif (mState == State.FLYING && mLinearFlying) {calculatedDuration = (int) (1000 * Math.abs((toYDelta - fromYDelta) / mVelocity));calculatedDuration = Math.max(calculatedDuration, 20);} else {calculatedDuration = mDuration * Math.abs(toYDelta - fromYDelta) / mContentHeight;}} else {int width = mContentWidth;if (!mIsShrinking) {fromXDelta = mPosition == LEFT? -width : width;} else {toXDelta = mPosition == LEFT? -width : width;}if (mState == State.TRACKING) {if (Math.abs(mTrackX - fromXDelta) < Math.abs(mTrackX - toXDelta)) {mIsShrinking = !mIsShrinking;toXDelta = fromXDelta;}fromXDelta = (int) mTrackX;} elseif (mState == State.FLYING) {fromXDelta = (int) mTrackX;}// for FLYING events we calculate animation duration based on flying velocity// also for very high velocity make sure duration >= 20 msif (mState == State.FLYING && mLinearFlying) {calculatedDuration = (int) (1000 * Math.abs((toXDelta - fromXDelta) / mVelocity));calculatedDuration = Math.max(calculatedDuration, 20);} else {calculatedDuration = mDuration * Math.abs(toXDelta - fromXDelta) / mContentWidth;}}mTrackX = mTrackY = 0;if (calculatedDuration == 0) {mState = State.READY;if (mIsShrinking) {mContent.setVisibility(GONE);}postProcess();return;}animation = new TranslateAnimation(fromXDelta, toXDelta, fromYDelta, toYDelta);animation.setDuration(calculatedDuration);animation.setAnimationListener(animationListener);if (mState == State.FLYING && mLinearFlying) {animation.setInterpolator(new LinearInterpolator());} elseif (mInterpolator != null) {animation.setInterpolator(mInterpolator);}startAnimation(animation);}};private AnimationListener animationListener = new AnimationListener() {public void onAnimationEnd(Animation animation) {mState = State.READY;if (mIsShrinking) {mContent.setVisibility(GONE);}postProcess();}public void onAnimationRepeat(Animation animation) {}public void onAnimationStart(Animation animation) {mState = State.ANIMATING;}};private void postProcess() {if (mIsShrinking && mClosedHandle != null) {mHandle.setBackgroundDrawable(mClosedHandle);} elseif (!mIsShrinking && mOpenedHandle != null) {mHandle.setBackgroundDrawable(mOpenedHandle);}// invoke listener if anyif (panelListener != null) {if (mIsShrinking) {panelListener.onPanelClosed(Panel.this);} else {panelListener.onPanelOpened(Panel.this);}}}class PanelOnGestureListener implements OnGestureListener {float scrollY;float scrollX;public void setScroll(int initScrollX, int initScrollY) {scrollX = initScrollX;scrollY = initScrollY;}public boolean onDown(MotionEvent e) {scrollX = scrollY = 0;initChange();return true;}public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {mState = State.FLYING;mVelocity = mOrientation == VERTICAL? velocityY : velocityX;post(startAnimation);return true;}public void onLongPress(MotionEvent e) {// not used}public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {mState = State.TRACKING;float tmpY = 0, tmpX = 0;if (mOrientation == VERTICAL) {scrollY -= distanceY;if (mPosition == TOP) {tmpY = ensureRange(scrollY, -mContentHeight, 0);} else  {tmpY = ensureRange(scrollY, 0, mContentHeight);}} else {scrollX -= distanceX;if (mPosition == LEFT) {tmpX = ensureRange(scrollX, -mContentWidth, 0);} else {tmpX = ensureRange(scrollX, 0, mContentWidth);}}if (tmpX != mTrackX || tmpY != mTrackY) {mTrackX = tmpX;mTrackY = tmpY;invalidate();}return true;}public void onShowPress(MotionEvent e) {// not used}public boolean onSingleTapUp(MotionEvent e) {// not usedreturn false;}}}

attrs.xml:

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="Panel">        <!-- Defines panel animation duration in ms. -->        <attr name="animationDuration" format="integer" />        <!-- Defines panel position on the screen. -->        <attr name="position">        <!-- Panel placed at top of the screen. -->            <enum name="top" value="0" />            <!-- Panel placed at bottom of the screen. -->            <enum name="bottom" value="1" />            <!-- Panel placed at left of the screen. -->            <enum name="left" value="2" />            <!-- Panel placed at right of the screen. -->            <enum name="right" value="3" />        </attr>        <!-- Identifier for the child that represents the panel's handle. -->        <attr name="handle" format="reference" />        <!-- Identifier for the child that represents the panel's content. -->        <attr name="content" format="reference" />        <!-- Defines if flying gesture forces linear interpolator in animation. -->        <attr name="linearFlying" format="boolean" />        <!-- Defines size relative to parent (must be in form: nn%p). -->        <attr name="weight" format="fraction" />        <!-- Defines opened handle (drawable/color). -->        <attr name="openedHandle" format="reference|color" />        <!-- Defines closed handle (drawable/color). -->        <attr name="closedHandle" format="reference|color" />    </declare-styleable>        </resources>

更多相关文章

  1. 监听电话
  2. 在代码中设置RelativeLayout布局中标签的android:layout_toLeftO
  3. 搞清android.support.v4.app.Fragment和android.app.Fragment区
  4. java中采用Pull解析器对XML文件进行解析
  5. Android之TabLayout常见问题解决+TabLayout+ViewPager实现标签页
  6. Android官方文档之App Resources(下)
  7. Android(安卓)TabHost(简易用法)
  8. Android动画分类
  9. android tabHost布局之一 继承TabActivity并以activity布局

随机推荐

  1. android之layout布局和ListView中的一些
  2. android多播
  3. android xml解析之SAX
  4. 老罗Android开发视频教程 (android常用UI
  5. Android(安卓)SQLite数据库操作实例
  6. SlidingDrawer 使用
  7. Android和PHP开发最佳实践
  8. Android移动应用开发_基础页面布局总结
  9. 轻松学Android开发
  10. Android判断当前的android设备是否处于联