哈哈,终于把滑动栏做好了,但是没有手势的滑动,只有点击按钮的效果,不过,我觉得还不错了!
这个就是我应用中用到的滑动栏的效果!,在这里我就share一下咯!
大家看代码就知道他的详细情况了:
这里我们有一个主类,这里会有两个布局文件与它相连:
这里显示main_slide布局文件:
请记住这里要用到framlayout哦!
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff" >
<!-- 左边菜单 -->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/leftmenu"
android:layout_width="250dip"
android:layout_height="fill_parent"
android:background="@drawable/background"
android:orientation="vertical"
android:visibility="invisible" >
<ImageView
android:id="@+id/imgHander"
android:layout_width="90dip"
android:layout_height="90dip"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dip" />
<TextView
android:id="@+id/text_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/imgHander"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dip"
android:text="Catherine"
android:textColor="#fff"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/text_moto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/text_name"
android:layout_centerHorizontal="true"
android:text="you never know that"
android:textColor="#fff"
android:textSize="15sp"
android:textStyle="bold" />
<Button
android:id="@+id/btn_fav"
android:layout_width="230dip"
android:layout_height="40dip"
android:layout_below="@id/text_moto"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dip"
android:background="@drawable/favourite" />
<Button
android:id="@+id/btn_set"
android:layout_width="230dip"
android:layout_height="40dip"
android:layout_below="@id/btn_fav"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dip"
android:background="@drawable/setting" />
<Button
android:id="@+id/btn_com"
android:layout_width="230dip"
android:layout_height="40dip"
android:layout_below="@id/btn_set"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dip"
android:background="@drawable/comment" />
<Button
android:id="@+id/btn_pro"
android:layout_width="230dip"
android:layout_height="40dip"
android:layout_below="@id/btn_com"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dip"
android:background="@drawable/profile" />
</RelativeLayout>
<grimbo.android.demo.slidingmenu.MyHorizontalScrollView
android:id="@+id/myScrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fadingEdge="none"
android:scrollbars="none" >
<!--
这里按钮就是控制滑图案出来的背景颜色,当然,如果这里没有了背景颜色,就会以上面的
背景颜色为主
-->
<LinearLayout
android:id="@+id/top"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
</LinearLayout>
</grimbo.android.demo.slidingmenu.MyHorizontalScrollView>
</FrameLayout>
接下来就是main布局文件:这个布局文件就是显示我们当前不做任何操作显示的界面:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/app"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#00f"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="2dip"
android:paddingTop="4dip"
>
<ImageView
android:id="@+id/leftButton"
android:layout_width="60dip"
android:layout_height="60dip" />
</RelativeLayout>
</LinearLayout>
这里就是主类:
package grimbo.android.demo.slidingmenu;
import cn.android.app.R;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
/**
* This example uses a FrameLayout to display a menu View and a
* HorizontalScrollView (HSV).
*
* The HSV has a transparent View as the first child, which means the menu will
* show through when the HSV is scrolled.
*/
public class MainActivity extends Activity {
private MyHorizontalScrollView scrollView;
private View leftMenu;
// private View rightMenu;
private View tab01;
private ImageView leftButton;
// private Button rightButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater inflater = LayoutInflater.from(this);
setContentView(inflater.inflate(R.layout.main_slide, null));
scrollView = (MyHorizontalScrollView) findViewById(R.id.myScrollView);
leftMenu = findViewById(R.id.leftmenu);
// rightMenu = findViewById(R.id.rightmenu);
tab01 = inflater.inflate(R.layout.tab01, null);
leftButton = (ImageView) main.findViewById(R.id.leftButton);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
Bitmap output = getRoundedCornerBitmap(bitmap);
leftButton.setImageBitmap(output);
leftButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
scrollView.clickLeftButton(leftButton.getMeasuredWidth());
}
});
// 以上的代码是设置我的头像为圆形的,以前找了好久,才知道,一句代码就ok啦!好吧,我
// 又想错了,其实还是需要很多的代码
View leftView = new View(this);// 左边透明视图
// View rightView = new View(this);// 右边透明视图
leftView.setBackgroundColor(Color.TRANSPARENT);
// rightView.setBackgroundColor(Color.TRANSPARENT);
// final View[] children = new View[] { leftView, tab01,rightView };
final View[] children = new View[] { leftView, tab01 };
// 初始化滚动布局
// scrollView.initViews(children, new
// SizeCallbackForMenu(leftButton),leftMenu,rightMenu);
scrollView.initViews(children, new SizeCallbackForMenu(leftButton),
leftMenu);
}
/**
* 圆形头像
*
* @param bitmap
* @param ratio
* 按照截取比例来获取圆形图片
* @return
*/
public Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
if (bitmap == null) {
bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
}
Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(outBitmap);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPX = bitmap.getWidth() / 2 < bitmap.getHeight() / 2 ? bitmap
.getWidth() : bitmap.getHeight();
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPX, roundPX, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return outBitmap;
}
}
这里是另外一个类,这些都是打辅助的了:
package grimbo.android.demo.slidingmenu;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
import android.view.GestureDetector.OnGestureListener;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.HorizontalScrollView;
import android.widget.Scroller;
/**
* A HorizontalScrollView (HSV) implementation that disallows touch events (so no scrolling can be done by the user).
*
* This HSV MUST contain a single ViewGroup as its only child, and this ViewGroup will be used to display the children Views
* passed in to the initViews() method.
*/
public class HomePageHorizontalScrollView extends HorizontalScrollView {
private final String tag = "MyHorizontalScrollView";
private HomePageHorizontalScrollView me;//当前控件
private View leftMenu;//左边菜单
private View rightMenu;//右边菜单
private boolean leftMenuOut = false;//左边菜单状态
private boolean rightMenuOut = false;//左边菜单状态
private final int ENLARGE_WIDTH = 20;//扩展宽度
public HomePageHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public HomePageHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public HomePageHorizontalScrollView(Context context) {
super(context);
init(context);
}
void init(Context context) {
// remove the fading as the HSV looks better without it
setHorizontalFadingEdgeEnabled(false);
setVerticalFadingEdgeEnabled(false);
me = this;
me.setVisibility(View.INVISIBLE);
}
/**
* @param children
* The child Views to add to parent.
* @param scrollToViewIdx
* The index of the View to scroll to after initialisation.
* @param sizeCallback
* A SizeCallback to interact with the HSV.
*/
public void initViews(View[] children, SizeCallback sizeCallback,View leftMenu,View rightMenu) {
this.leftMenu = leftMenu;
this.rightMenu = rightMenu;
ViewGroup parent = (ViewGroup) getChildAt(0);
// Add all the children, but add them invisible so that the layouts are calculated, but you can‘t see the Views
for (int i = 0; i < children.length; i++) {
children[i].setVisibility(View.INVISIBLE);
parent.addView(children[i]);
}
// Add a layout listener to this HSV
// This listener is responsible for arranging the child views.
OnGlobalLayoutListener listener = new MyOnGlobalLayoutListener(parent, children, sizeCallback);
getViewTreeObserver().addOnGlobalLayoutListener(listener);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Do not allow touch events.
return false;
}
/**
* An OnGlobalLayoutListener impl that passes on the call to onGlobalLayout to a SizeCallback, before removing all the Views
* in the HSV and adding them again with calculated widths and heights.
*/
class MyOnGlobalLayoutListener implements OnGlobalLayoutListener {
ViewGroup parent;
View[] children;
int scrollToViewPos = 0;
SizeCallback sizeCallback;
/**
* @param parent
* The parent to which the child Views should be added.
* @param children
* The child Views to add to parent.
* @param scrollToViewIdx
* The index of the View to scroll to after initialisation.
* @param sizeCallback
* A SizeCallback to interact with the HSV.
*/
public MyOnGlobalLayoutListener(ViewGroup parent, View[] children, SizeCallback sizeCallback) {
this.parent = parent;
this.children = children;
this.sizeCallback = sizeCallback;
}
@Override
public void onGlobalLayout() {
// System.out.println("onGlobalLayout");
//final HorizontalScrollView me = MyHorizontalScrollView.this;
// The listener will remove itself as a layout listener to the HSV
me.getViewTreeObserver().removeGlobalOnLayoutListener(this);
// Allow the SizeCallback to ‘see‘ the Views before we remove them and re-add them.
// This lets the SizeCallback prepare View sizes, ahead of calls to SizeCallback.getViewSize().
sizeCallback.onGlobalLayout();
parent.removeViewsInLayout(0, children.length);
final int w = me.getMeasuredWidth();
final int h = me.getMeasuredHeight();
// System.out.println("w=" + w + ", h=" + h);
// Add each view in turn, and apply the width and height returned by the SizeCallback.
int[] dims = new int[2];
scrollToViewPos = 0;
for (int i = 0; i < children.length; i++) {
sizeCallback.getViewSize(i, w, h, dims);
children[i].setVisibility(View.VISIBLE);
parent.addView(children[i], dims[0], dims[1]);
if (i == 0) {
scrollToViewPos += dims[0];
}
Log.d(tag, children[i]+": w=" + dims[0] + ", h=" + dims[1]);
Log.d(tag, "scrollToViewIdx:"+0+",scrollToViewPos:"+scrollToViewPos);
}
// For some reason we need to post this action, rather than call immediately.
// If we try immediately, it will not scroll.
new Handler().post(new Runnable() {
@Override
public void run() {
me.scrollBy(scrollToViewPos,0);
//因为这些控件默认都为隐藏,控件加载完成后,设置成显示
me.setVisibility(View.VISIBLE);
leftMenu.setVisibility(View.VISIBLE);
rightMenu.setVisibility(View.VISIBLE);
}
});
}
}
/**
* 点击左边按钮
* @param leftButtonWidth 左边按钮的宽度
*/
public void clickLeftButton(int leftButtonWidth){
//左边
rightMenu.setVisibility(View.GONE);
leftMenu.setVisibility(View.VISIBLE);
int menuWidth = leftMenu.getMeasuredWidth()-(leftButtonWidth+ENLARGE_WIDTH);
System.out.println("leftmenuWidth:"+menuWidth);
if (!leftMenuOut) {
int left = 0;
me.smoothScrollTo(left, 0);
} else {
int left = menuWidth;
me.smoothScrollTo(left, 0);
}
leftMenuOut = !leftMenuOut;
}
/**
* 点击右边按钮
* @param rightButtonWidth 右边按钮的宽度
*/
public void clickRightButton(int rightButtonWidth){
//右边
leftMenu.setVisibility(View.GONE);
rightMenu.setVisibility(View.VISIBLE);
int menuWidth = rightMenu.getMeasuredWidth() - (rightButtonWidth+ENLARGE_WIDTH);
if (!rightMenuOut) {
int right = menuWidth + me.getMeasuredWidth();
System.out.println("rightmenuWidth:"+right);
me.smoothScrollTo(right, 0);
} else {
int right = menuWidth;
System.out.println("rightmenuWidth:"+right);
me.smoothScrollTo(right, 0);
}
rightMenuOut = !rightMenuOut;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
//return super.onTouchEvent(ev);
return false;
}
/**
* Callback interface to interact with the HSV.
*/
public interface SizeCallback {
/**
* Used to allow clients to measure Views before re-adding them.
*/
public void onGlobalLayout();
/**
* Used by clients to specify the View dimensions.
*
* @param idx
* Index of the View.
* @param w
* Width of the parent View.
* @param h
* Height of the parent View.
* @param dims
* dims[0] should be set to View width. dims[1] should be set to View height.
*/
public void getViewSize(int idx, int w, int h, int[] dims);
}
}
在主类里面,我们就会用到水平滚动的一些操作:
package grimbo.android.demo.slidingmenu;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.HorizontalScrollView;
/**
* A HorizontalScrollView (HSV) implementation that disallows touch events (so
* no scrolling can be done by the user).
*
* This HSV MUST contain a single ViewGroup as its only child, and this
* ViewGroup will be used to display the children Views passed in to the
* initViews() method.
*/
public class MyHorizontalScrollView extends HorizontalScrollView {
private final String tag = "MyHorizontalScrollView";
private MyHorizontalScrollView me;// 当前控件
private View leftMenu;// 左边菜单
private boolean leftMenuOut = false;// 左边菜单状态
private final int ENLARGE_WIDTH = 20;// 扩展宽度
public MyHorizontalScrollView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public MyHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MyHorizontalScrollView(Context context) {
super(context);
init(context);
}
void init(Context context) {
// remove the fading as the HSV looks better without it
setHorizontalFadingEdgeEnabled(false);
setVerticalFadingEdgeEnabled(false);
me = this;
me.setVisibility(View.INVISIBLE);
}
/**
* @param children
* The child Views to add to parent.
* @param scrollToViewIdx
* The index of the View to scroll to after initialisation.
* @param sizeCallback
* A SizeCallback to interact with the HSV.
*/
public void initViews(View[] children, SizeCallback sizeCallback,
View leftMenu) {
this.leftMenu = leftMenu;
ViewGroup parent = (ViewGroup) getChildAt(0);
// Add all the children, but add them invisible so that the layouts are
// calculated, but you can‘t see the Views
for (int i = 0; i < children.length; i++) {
children[i].setVisibility(View.INVISIBLE);
parent.addView(children[i]);
}
// Add a layout listener to this HSV
// This listener is responsible for arranging the child views.
OnGlobalLayoutListener listener = new MyOnGlobalLayoutListener(parent,
children, sizeCallback);
getViewTreeObserver().addOnGlobalLayoutListener(listener);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
/**
* An OnGlobalLayoutListener impl that passes on the call to onGlobalLayout
* to a SizeCallback, before removing all the Views in the HSV and adding
* them again with calculated widths and heights.
*/
class MyOnGlobalLayoutListener implements OnGlobalLayoutListener {
ViewGroup parent;
View[] children;
int scrollToViewPos = 0;
SizeCallback sizeCallback;
/**
* @param parent
* The parent to which the child Views should be added.
* @param children
* The child Views to add to parent.
* @param scrollToViewIdx
* The index of the View to scroll to after initialisation.
* @param sizeCallback
* A SizeCallback to interact with the HSV.
*/
public MyOnGlobalLayoutListener(ViewGroup parent, View[] children,
SizeCallback sizeCallback) {
this.parent = parent;
this.children = children;
this.sizeCallback = sizeCallback;
}
@Override
public void onGlobalLayout() {
// System.out.println("onGlobalLayout");
// final HorizontalScrollView me = MyHorizontalScrollView.this;
// The listener will remove itself as a layout listener to the HSV
me.getViewTreeObserver().removeGlobalOnLayoutListener(this);
// Allow the SizeCallback to ‘see‘ the Views before we remove them
// and re-add them.
// This lets the SizeCallback prepare View sizes, ahead of calls to
// SizeCallback.getViewSize().
sizeCallback.onGlobalLayout();
parent.removeViewsInLayout(0, children.length);
final int w = me.getMeasuredWidth();
final int h = me.getMeasuredHeight();
// System.out.println("w=" + w + ", h=" + h);
// Add each view in turn, and apply the width and height returned by
// the SizeCallback.
int[] dims = new int[2];
scrollToViewPos = 0;
for (int i = 0; i < children.length; i++) {
sizeCallback.getViewSize(i, w, h, dims);
children[i].setVisibility(View.VISIBLE);
parent.addView(children[i], dims[0], dims[1]);
if (i == 0) {
scrollToViewPos += dims[0];
}
Log.d(tag, children[i] + ": w=" + dims[0] + ", h=" + dims[1]);
Log.d(tag, "scrollToViewIdx:" + 0 + ",scrollToViewPos:"
+ scrollToViewPos);
}
// For some reason we need to post this action, rather than call
// immediately.
// If we try immediately, it will not scroll.
new Handler().post(new Runnable() {
@Override
public void run() {
me.scrollBy(scrollToViewPos, 0);
// 因为这些控件默认都为隐藏,控件加载完成后,设置成显示
me.setVisibility(View.VISIBLE);
leftMenu.setVisibility(View.VISIBLE);
}
});
}
}
/**
* 点击左边按钮
*
* @param leftButtonWidth
* 左边按钮的宽度
*/
public void clickLeftButton(int leftButtonWidth) {
// 左边
leftMenu.setVisibility(View.VISIBLE);
int menuWidth = 90+leftMenu.getMeasuredWidth()
- (leftButtonWidth + ENLARGE_WIDTH);
System.out.println("leftmenuWidth:" + menuWidth);
if (!leftMenuOut) {
int left = 0;
me.smoothScrollTo(left, 0);
} else {
int left = menuWidth;
me.smoothScrollTo(left, 0);
}
leftMenuOut = !leftMenuOut;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
// return super.onTouchEvent(ev);
return false;
}
/**
* Callback interface to interact with the HSV.
*/
public interface SizeCallback {
/**
* Used to allow clients to measure Views before re-adding them.
*/
public void onGlobalLayout();
/**
* Used by clients to specify the View dimensions.
*
* @param idx
* Index of the View.
* @param w
* Width of the parent View.
* @param h
* Height of the parent View.
* @param dims
* dims[0] should be set to View width. dims[1] should be set
* to View height.
*/
public void getViewSize(int idx, int w, int h, int[] dims);
}
}
这里还会有一些对当前界面滑动后的界面美观维护类:
package grimbo.android.demo.slidingmenu;
import grimbo.android.demo.slidingmenu.MyHorizontalScrollView.SizeCallback;
import android.widget.ImageView;
/**
* Copyright (c) 2011,
* All rights reserved.
* 类说明
* @author 许美镇
* @version Revision:1.0 Date:(2012-5-22)
*
*/
public class SizeCallbackForMenu implements SizeCallback {
private ImageView leftButton;
private int leftButtonWidth;
public SizeCallbackForMenu(ImageView leftButton) {
super();
this.leftButton = leftButton;
}
@Override
public void onGlobalLayout() {
leftButtonWidth = leftButton.getMeasuredWidth()+8;
System.out.println("leftButtonWidth=" + leftButtonWidth);
}
@Override
public void getViewSize(int idx, int w, int h, int[] dims) {
dims[0] = w;
dims[1] = h;
if (idx != 1) {
//当视图不是中间的视图
dims[0] = w - leftButtonWidth;
}
}
}
这里其实对于大家最重要的就是动画了,所以这里我把动画公布了:
这里面的代码依次为:
第一个:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="80%p" android:toXDelta="0" android:duration="500"/>
<!--alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" /-->
</set>
第二个:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="500"/>
<!--alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" /-->
</set>
第三个:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="-100%p" android:duration="500"/>
<!--alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="300" /-->
</set>
第四个:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-100%p" android:toXDelta="0" android:duration="500"/>
<!--alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" /-->
</set>
第五个:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="80%p" android:duration="500"/>
<!--alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="300" /-->
</
第六个:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="100%p" android:duration="500"/>
<!--alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="300" /-->
</set>
但是鉴于这么多的代码,毕竟很无趣嘛,我会看情况吧源码贴出来的!谢谢支持哦!有什么好的建议随便说了!
原文:http://www.cnblogs.com/Catherine-Brain/p/3543771.html