安卓自定义View----实现TextView可设置drawable宽高度

前言


图片发自简书App


如上图所示,相信可爱的安卓程序猿们在开发中经常会遇到这种样式的UI开发。其实上面这种布局很简单,没有难度,只不过是繁杂的view嵌套而已。通常我们在实现上面这种效果的时候会有3种方式:

方式一:

一层一层的搭建,首先外层是一个横向的LinearLayout,然后里面包裹着四个LinearLayout作为子View, 每一个Linearlayout里面再写上一个ImageView和一个TextView.如此简单的一个布局我们竟然需要父View和子View一共13个View来实现。视图的层级已经达到了3层。这种方式笨重,低效,耗能。

方式二:

继承一个布局文件,实现自定义的tabView.这是自定义view中的一种。首先针对上图中的一个tab写一个布局文件abc.xml,很简单,一个LinearLayout装着一个ImageView和一个TextView,.然后对这个布局文件进行封装,添加自定义的属性。这样在实现上述布局时只要写一个LinearLayout,里面添加4个TabView就好了。然而,这种方式看起来是简单了。但实际上和方式一是没有什么差别的,加载View时,视图层级依然是3层。 只是看起来简单了而已。

方式三:

使用TextView的drawableTop属性。明明有这么方便优雅的实现方式我们却不用,太是暴殄天物了。于是乎,我们写一个LinearLayout,里面添上4个TextView,在布局文件中为每一个TextView设置android:drawableTop="@drawable/haha.png"

然后呢,就没然后了。已经完成了!上述的那个布局样式就这么轻松加愉快的实现了。视图层级从原来得分3层变成了现在的两层,不要小看这一层,在加载xml文件的时候,层级的增加会大大增加对资源和时间的消耗。其次,view个数从原来的13个变成了现在的5个。太棒了。

可是意外就像bug,总在你想不到的地方出现。这么完美的实现方式,到最后我们竟然无法设置TextView加载的drawable的大小!!也就是说资源文件本身宽高多大就只能多大。安卓没有提供修改这个drawable大小的API.惊不惊喜,意不意外。

那么问题来了。我们到底能不能修改他的大小呢,答案当然是能,这就需要我们通过继承TextView来改造一下他的方法来实现。接下来我就向大家介绍一下我的思考过程和实现方式,一起看看每一步是否是合理的。

drawable大小的实现原理

首先当然是阅读源码了,对此我们需要有一个突破口,这里我就从TextVIew的drawableTop属性开始。我们在文件中设置了这个属性,源码中肯定要有相对应的操作。在TextView的源码里我们搜索drawableTop,

第一步:

在TextView的构造方法里系统获取了drawableTop属性,并复制给drawableTop变量。 源码:

casecom.android.internal.R.styleable.TextView_drawableTop:drawableTop = a.getDrawable(attr);break;

第二步:

我们查找DrawableTop变量。顺着代码往下一路走来,依然是在构造方法里。当获取完了上下左右四个drawable后,系统执行了下面这行代码:

setCompoundDrawablesWithIntrinsicBounds(drawableLeft, drawableTop, drawableRight, drawableBottom);

显而易见,这个方法对上下左右四个drawable做了处理。

第三步:

进入setCompoundDrawablesWithIntrinsicBounds方法:下面是系统的源码,代码不长,主要看四个if判断, 其实就是为四个drawable分别设置各自的大小。

/** * Sets the Drawables (if any) to appear to the left of, above, to the * right of, and below the text. Use {@code null} if you do not want a * Drawable there. The Drawables' bounds will be set to their intrinsic * bounds. *

* Calling this method will overwrite any Drawables previously set using

* {@link #setCompoundDrawablesRelative} or related methods.

*

* @attr ref android.R.styleable#TextView_drawableLeft

* @attr ref android.R.styleable#TextView_drawableTop

* @attr ref android.R.styleable#TextView_drawableRight

* @attr ref android.R.styleable#TextView_drawableBottom

*/

@android.view.RemotableViewMethod

public void setCompoundDrawablesWithIntrinsicBounds(@Nullable Drawable left,

@Nullable Drawable top, @Nullable Drawable right, @Nullable Drawable bottom) {

if (left != null) {

left.setBounds(0, 0, left.getIntrinsicWidth(), left.getIntrinsicHeight());

}

if (right != null) {

right.setBounds(0, 0, right.getIntrinsicWidth(), right.getIntrinsicHeight());

}

if (top != null) {

top.setBounds(0, 0, top.getIntrinsicWidth(), top.getIntrinsicHeight());

}

if (bottom != null) {

bottom.setBounds(0, 0, bottom.getIntrinsicWidth(), bottom.getIntrinsicHeight());

}

setCompoundDrawables(left, top, right, bottom);

}

这个方法很好理解,核心就是setBounds(0,0, top.getIntrinsicWidth(),top.getIntrinsicHeight());

这句话。到这里,就已经很清晰了,系统获取了我们为TextView设置的drawable,然后就根据drawable自身的大小来设置了要绘制时的边界大小。所以我们在为TextVIew设置drawable时,图片是多大,就显示多大,真是童叟无欺啊。只是苦了我们搬砖的,还得小心翼翼的找UI大大给切图。

既然问题找到了。那解决就很容易了。我们实现一个自定义TextView,重写setCompoundDrawablesWithIntrinsicBounds方法,在里面将setBound方法的传值改为我们设置的大小就OK了。

自定义TextView----XXDrawableTextView

千里之行,始于足下,开始自定义XXDrawableTextView。

第一步:

在style.xml文件中设置XXDrawableTextView的属性,添加下面代码:

<attrname="drawableWidth_left"format="dimension"/><attrname="drawableHeight_left"format="dimension"/><attrname="drawableWidth_top"format="dimension"/><attrname="drawableHeight_top"format="dimension"/><attrname="drawableWidth_right"format="dimension"/><attrname="drawableHeight_right"format="dimension"/><attrname="drawableWidth_bottom"format="dimension"/><attrname="drawableHeight_bottom"format="dimension"/>

这里我把上下左右四个为止的drawable都纳入处理的范围了,其实逻辑都一样。

然后再添加下面这段:

<declare-styleable name="XXDrawableTextView"> <attrname="drawableWidth_left"/>

<attrname="drawableHeight_left"/>

<attrname="drawableWidth_top"/>

<attrname="drawableHeight_top"/>

<attrname="drawableWidth_right"/>

<attrname="drawableHeight_right"/>

<attrname="drawableWidth_bottom"/>

<attrname="drawableHeight_bottom"/>

</declare-styleable>

第二步:

继承TextView ,获取自定义的drawable得宽高度属性值。

*获得我们所定义的自定义样式属性

*/TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.XXDrawableTextView, defStyleAttr,0);intn = a.getIndexCount();for(inti =0; i < n; i++){intattr = a.getIndex(i);switch(attr) {caseR.styleable.XXDrawableTextView_drawableWidth_left:leftDrawableWidth= a.getDimensionPixelSize(attr,10);break;caseR.styleable.XXDrawableTextView_drawableHeight_left:leftDrawableHeight= a.getDimensionPixelSize(attr,10);break;caseR.styleable.XXDrawableTextView_drawableWidth_top:topDrawableWidth= a.getDimensionPixelSize(attr,10);break;caseR.styleable.XXDrawableTextView_drawableHeight_top:topDrawableHeight= a.getDimensionPixelSize(attr,10);break;caseR.styleable.XXDrawableTextView_drawableWidth_right:rightDrawableWidth= a.getDimensionPixelSize(attr,10);break;caseR.styleable.XXDrawableTextView_drawableHeight_right:rightDrawableHeight= a.getDimensionPixelSize(attr,10);break;caseR.styleable.XXDrawableTextView_drawableWidth_bottom:bottomDrawableWidth= a.getDimensionPixelSize(attr,10);break;caseR.styleable.XXDrawableTextView_drawableHeight_bottom:bottomDrawableHeight= a.getDimensionPixelSize(attr,10);break; }}a.recycle();

第三步:

重写setCompoundDrawablesWithIntrinsicBounds方法,为各个drawable宝宝们设置宽度和高度。


@Overridepublic voidsetCompoundDrawablesWithIntrinsicBounds(@NullableDrawable left,@NullableDrawable top,@NullableDrawable right,@NullableDrawable bottom) {this.left= left;this.top= top;this.right= right;this.bottom= bottom; System.out.println("啦啦啦啦啦啦啦");if(left !=null) { left.setBounds(0,0,leftDrawableWidth,leftDrawableHeight); }if(right !=null) { right.setBounds(0,0,rightDrawableWidth,rightDrawableHeight); }if(top !=null) { top.setBounds(0,0,topDrawableWidth,topDrawableHeight); }if(bottom !=null) { bottom.setBounds(0,0,bottomDrawableWidth,bottomDrawableHeight); } setCompoundDrawables(left, top, right, bottom);}

你看 ,其实最关键的还是setBound方法,将我们获取到的宽高度传了进去。

第四步:

到这,自定义View的基本工作已经做完了,我们可以在布局文件中使用了,

注意 ,因为是自定义view,一定不要忘记在布局文件头部添加

xmlns:app="http://schemas.android.com/apk/res-auto"哦。

最后写一个LinearLayout,里面就替换成四个我们自定义的XXDrawableTextView,轻轻的为每一个XXDrawableTextView设置drawableHeight和drawableWidth属性。就像下面这样:

<com.xiaxiao.xiaoandroid.customview.XXDrawableTextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="天气不错"android:drawableTop="@drawable/tab2"app:drawableHeight_top="40dp"app:drawableWidth_top="40dp"android:gravity="center_horizontal"android:layout_weight="1"/>

静悄悄的,简洁的就像什么都没发生一样,然而一切却变了,我们优雅的实现了tab导航栏的效果,层级依然是2,view个数依然是最少的5个。App的运行效率和性能就这么不经意的被我们提高了那么一丢丢。

下面是具体的自定义XXDrawableTextView类:

XXDrawableTextView.java

[java]view plaincopy

packagecom.xiaxiao.xiaoandroid.customview;

importandroid.annotation.TargetApi;

importandroid.content.Context;

importandroid.content.res.TypedArray;

importandroid.graphics.Canvas;

importandroid.graphics.Paint;

importandroid.graphics.Rect;

importandroid.graphics.drawable.Drawable;

importandroid.os.Build;

importandroid.support.annotation.Nullable;

importandroid.util.AttributeSet;

importandroid.widget.TextView;

importcom.xiaxiao.xiaoandroid.R;

/**

*Createdbyxiaxiaoon2017/9/13.

*

*用来解决文字和图片组合时造成的view层级过多的问题。

*比如上图标下文字,下图标上文字,尤其是在实现一组tab均匀平铺的效果时出现的大量view层级

*比如各app的底部栏,本类只要一层view既可。

*

*注意:必须设置drawable的宽高度。

*

*/

publicclassXXDrawableTextViewextendsTextView{

publicfinalstaticintPOSITION_LEFT=0;

publicfinalstaticintPOSITION_TOP=1;

publicfinalstaticintPOSITION_RIGHT=2;

publicfinalstaticintPOSITION_BOTTOM=3;

intleftDrawableWidth=10;

intleftDrawableHeight=10;

inttopDrawableWidth=10;

inttopDrawableHeight=10;

intrightDrawableWidth=10;

intrightDrawableHeight=10;

intbottomDrawableWidth=10;

intbottomDrawableHeight=10;

PaintmPaint;

PaintmPaint2;

RectmBound;

Drawableleft;

Drawabletop;

Drawableright;

Drawablebottom;

publicXXDrawableTextView(Contextcontext){

this(context,null,0);

}

publicXXDrawableTextView(Contextcontext,AttributeSetattrs){

this(context,attrs,0);

}

publicXXDrawableTextView(Contextcontext,AttributeSetattrs,intdefStyleAttr){

super(context,attrs,defStyleAttr);

getAttributes(context,attrs,defStyleAttr);

}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)

publicXXDrawableTextView(Contextcontext,AttributeSetattrs,intdefStyleAttr,intdefStyleRes){

super(context,attrs,defStyleAttr,defStyleRes);

getAttributes(context,attrs,defStyleAttr);

}

publicvoidgetAttributes(Contextcontext,AttributeSetattrs,intdefStyleAttr){

/**

*获得我们所定义的自定义样式属性

*/

TypedArraya=context.getTheme().obtainStyledAttributes(attrs,R.styleable.XXDrawableTextView,defStyleAttr,0);

intn=a.getIndexCount();

for(inti=0;i<n;i++)

{

intattr=a.getIndex(i);

switch(attr)

{

caseR.styleable.XXDrawableTextView_drawableWidth_left:

leftDrawableWidth=a.getDimensionPixelSize(attr,10);

break;

caseR.styleable.XXDrawableTextView_drawableHeight_left:

leftDrawableHeight=a.getDimensionPixelSize(attr,10);

break;

caseR.styleable.XXDrawableTextView_drawableWidth_top:

topDrawableWidth=a.getDimensionPixelSize(attr,10);

break;

caseR.styleable.XXDrawableTextView_drawableHeight_top:

topDrawableHeight=a.getDimensionPixelSize(attr,10);

break;

caseR.styleable.XXDrawableTextView_drawableWidth_right:

rightDrawableWidth=a.getDimensionPixelSize(attr,10);

break;

caseR.styleable.XXDrawableTextView_drawableHeight_right:

rightDrawableHeight=a.getDimensionPixelSize(attr,10);

break;

caseR.styleable.XXDrawableTextView_drawableWidth_bottom:

bottomDrawableWidth=a.getDimensionPixelSize(attr,10);

break;

caseR.styleable.XXDrawableTextView_drawableHeight_bottom:

bottomDrawableHeight=a.getDimensionPixelSize(attr,10);

break;

caseR.styleable.XXDrawableTextView_testnumber:

System.out.println("啦啦啦啦啦啦啦TextView2_testnumber:"+a.getDimensionPixelSize(attr,10));

break;

caseR.styleable.XXDrawableTextView_teststring:

System.out.println("啦啦啦啦啦啦啦TextView2_teststring:"+a.getString(attr));

}

}

a.recycle();

/*

*setCompoundDrawablesWithIntrinsicBounds方法会首先在父类的构造方法中执行,

*彼时执行时drawable的大小还都没有开始获取,都是0,

*这里获取完自定义的宽高属性后再次调用这个方法,插入drawable的大小

**/

setCompoundDrawablesWithIntrinsicBounds(

left,top,right,bottom);

}

/**

*SetstheDrawables(ifany)toappeartotheleftof,above,tothe

*rightof,andbelowthetext.Use{@codenull}ifyoudonotwanta

*Drawablethere.TheDrawables'boundswillbesettotheirintrinsic

*bounds.

*

*CallingthismethodwilloverwriteanyDrawablespreviouslysetusing

*{@link#setCompoundDrawablesRelative}orrelatedmethods.

*这里重写这个方法,来设置上下左右的drawable的大小

*

*@attrrefandroid.R.styleable#TextView_drawableLeft

*@attrrefandroid.R.styleable#TextView_drawableTop

*@attrrefandroid.R.styleable#TextView_drawableRight

*@attrrefandroid.R.styleable#TextView_drawableBottom

*/

@Override

publicvoidsetCompoundDrawablesWithIntrinsicBounds(@NullableDrawableleft,

@NullableDrawabletop,@NullableDrawableright,@NullableDrawablebottom){

this.left=left;

this.top=top;

this.right=right;

this.bottom=bottom;

System.out.println("啦啦啦啦啦啦啦");

if(left!=null){

left.setBounds(0,0,leftDrawableWidth,leftDrawableHeight);

}

if(right!=null){

right.setBounds(0,0,rightDrawableWidth,rightDrawableHeight);

}

if(top!=null){

top.setBounds(0,0,topDrawableWidth,topDrawableHeight);

}

if(bottom!=null){

bottom.setBounds(0,0,bottomDrawableWidth,bottomDrawableHeight);

}

setCompoundDrawables(left,top,right,bottom);

}

/*

*代码中动态设置drawable的宽高度

**/

publicvoidsetDrawableSize(intwidth,intheight,intposition){

if(position==this.POSITION_LEFT){

leftDrawableWidth=width;

leftDrawableHeight=height;

}

if(position==this.POSITION_TOP){

topDrawableWidth=width;

topDrawableHeight=height;

}

if(position==this.POSITION_RIGHT){

rightDrawableWidth=width;

rightDrawableHeight=height;

}

if(position==this.POSITION_BOTTOM){

bottomDrawableWidth=width;

bottomDrawableHeight=height;

}

setCompoundDrawablesWithIntrinsicBounds(

left,top,right,bottom);

}

@Override

protectedvoidonDraw(Canvascanvas){

//Drawthebackgroundforthisview

super.onDraw(canvas);

/*

测试圆角的

Bitmapbitmap=Bitmap.createBitmap(getWidth(),getHeight(),Bitmap.Config.ARGB_8888);

Canvascanvas2=newCanvas(bitmap);

super.onDraw(canvas2);

mPaint=newPaint();

mPaint.setColor(Color.RED);

mPaint.setAntiAlias(true);

//16种状态

mPaint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.DST_OUT));

mPaint2=newPaint();

mPaint2.setColor(Color.YELLOW);

mPaint2.setXfermode(null);

intradius=100;

Pathpath=newPath();

path.moveTo(0,radius);

path.lineTo(0,0);

path.lineTo(radius,0);

//arcTo的第二个参数是以多少度为开始点,第三个参数-90度表示逆时针画弧,正数表示顺时针

path.arcTo(newRectF(0,0,radius*2,radius*2),-90,-90);

path.close();

canvas2.drawPath(path,mPaint);

canvas.drawBitmap(bitmap,0,0,mPaint2);

bitmap.recycle();*/

/*

finalintcompoundPaddingLeft=getCompoundPaddingLeft();

finalintcompoundPaddingTop=getCompoundPaddingTop();

finalintcompoundPaddingRight=getCompoundPaddingRight();

finalintcompoundPaddingBottom=getCompoundPaddingBottom();

finalintscrollX=getScrollX();

finalintscrollY=getScrollY();

finalintright=getRight();

finalintleft=getLeft();

finalintbottom=getBottom();

finalinttop=getTop();

finalintoffset=0;

finalintleftOffset=0;

finalintrightOffset=0;

*//*

*0-1-2-3

*left-top-right-bottom

**//*

Drawable[]drawables=getCompoundDrawables();

*//*

*Compound,notextended,becausetheiconisnotclipped

*ifthetextheightissmaller.

*//*

intvspace=bottom-top-compoundPaddingBottom-compoundPaddingTop;

inthspace=right-left-compoundPaddingRight-compoundPaddingLeft;

//IMPORTANT:ThecoordinatescomputedarealsousedininvalidateDrawable()

//MakesuretoupdateinvalidateDrawable()whenchangingthiscode.

if(drawables[0]!=null){

canvas.save();

canvas.translate(scrollX+getPaddingLeft()+leftOffset,

scrollY+compoundPaddingTop+

(vspace-leftDrawableHeight)/2);

drawables[0].draw(canvas);

canvas.restore();

}

//IMPORTANT:ThecoordinatescomputedarealsousedininvalidateDrawable()

//MakesuretoupdateinvalidateDrawable()whenchangingthiscode.

if(dr.mShowing[Drawables.RIGHT]!=null){

canvas.save();

canvas.translate(scrollX+right-left-mPaddingRight

-dr.mDrawableSizeRight-rightOffset,

scrollY+compoundPaddingTop+(vspace-dr.mDrawableHeightRight)/2);

dr.mShowing[Drawables.RIGHT].draw(canvas);

canvas.restore();

}

//IMPORTANT:ThecoordinatescomputedarealsousedininvalidateDrawable()

//MakesuretoupdateinvalidateDrawable()whenchangingthiscode.

if(dr.mShowing[Drawables.TOP]!=null){

canvas.save();

canvas.translate(scrollX+compoundPaddingLeft+

(hspace-dr.mDrawableWidthTop)/2,scrollY+mPaddingTop);

dr.mShowing[Drawables.TOP].draw(canvas);

canvas.restore();

}

//IMPORTANT:ThecoordinatescomputedarealsousedininvalidateDrawable()

//MakesuretoupdateinvalidateDrawable()whenchangingthiscode.

if(dr.mShowing[Drawables.BOTTOM]!=null){

canvas.save();

canvas.translate(scrollX+compoundPaddingLeft+

(hspace-dr.mDrawableWidthBottom)/2,

scrollY+bottom-top-mPaddingBottom-dr.mDrawableSizeBottom);

dr.mShowing[Drawables.BOTTOM].draw(canvas);

canvas.restore();

}

canvas.restore();*/

}

}

其中注释掉的是设置drawable为圆角的尝试,可忽略。

我还添加了个修改宽高度的方法,可以运行时在代码中设置drawable的宽高。

其次还需要注意一下setCompoundDrawablesWithIntrinsicBounds方法的调用位置。

因为这个方法是在父类的构造方法中调用的,也就是说当执行XXDrawableTextView的构造方法时,

首先会执行父类的构造方法,在执行super方法时,这个方法已经进行了。这时候getAttribute方法还没调用呢,

也就是说各个宽高度属性值都还没获得,所以需要在执行完getArttribute方法后再调用一遍

setCompoundDrawablesWithIntrinsicBounds。

总结:

优点呢,简洁明了,就那么回事,缺点呢就是不能针对其中的drawable再做进一步的处理了,比如设置成圆角之类。尝试了一下自定义,发现太麻烦了。如果真的出现图片设置成圆角的场景,

恐怕还得使用TextView加自定义的圆角ImageView。或者,找UI大大们了。

如果帮到你了,给个赞吧。

另:
简书的编辑环境咋就这么差劲呢,代码连个换行都不行,瞧这排版,醉了。

观看友好版请移步:http://blog.csdn.net/xx23x/article/details/77997565

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,290评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,399评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,021评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,034评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,412评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,651评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,902评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,605评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,339评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,586评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,076评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,400评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,060评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,851评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,685评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,595评论 2 270

推荐阅读更多精彩内容