安卓自定義View----實(shí)現(xiàn)TextView可設(shè)置drawable寬高度

前言


圖片發(fā)自簡書App


如上圖所示,相信可愛的安卓程序猿們在開發(fā)中經(jīng)常會(huì)遇到這種樣式的UI開發(fā)。其實(shí)上面這種布局很簡單,沒有難度,只不過是繁雜的view嵌套而已。通常我們在實(shí)現(xiàn)上面這種效果的時(shí)候會(huì)有3種方式:

方式一:

一層一層的搭建,首先外層是一個(gè)橫向的LinearLayout,然后里面包裹著四個(gè)LinearLayout作為子View, 每一個(gè)Linearlayout里面再寫上一個(gè)ImageView和一個(gè)TextView.如此簡單的一個(gè)布局我們竟然需要父View和子View一共13個(gè)View來實(shí)現(xiàn)。視圖的層級已經(jīng)達(dá)到了3層。這種方式笨重,低效,耗能。

方式二:

繼承一個(gè)布局文件,實(shí)現(xiàn)自定義的tabView.這是自定義view中的一種。首先針對上圖中的一個(gè)tab寫一個(gè)布局文件abc.xml,很簡單,一個(gè)LinearLayout裝著一個(gè)ImageView和一個(gè)TextView,.然后對這個(gè)布局文件進(jìn)行封裝,添加自定義的屬性。這樣在實(shí)現(xiàn)上述布局時(shí)只要寫一個(gè)LinearLayout,里面添加4個(gè)TabView就好了。然而,這種方式看起來是簡單了。但實(shí)際上和方式一是沒有什么差別的,加載View時(shí),視圖層級依然是3層。 只是看起來簡單了而已。

方式三:

使用TextView的drawableTop屬性。明明有這么方便優(yōu)雅的實(shí)現(xiàn)方式我們卻不用,太是暴殄天物了。于是乎,我們寫一個(gè)LinearLayout,里面添上4個(gè)TextView,在布局文件中為每一個(gè)TextView設(shè)置android:drawableTop="@drawable/haha.png"

然后呢,就沒然后了。已經(jīng)完成了!上述的那個(gè)布局樣式就這么輕松加愉快的實(shí)現(xiàn)了。視圖層級從原來得分3層變成了現(xiàn)在的兩層,不要小看這一層,在加載xml文件的時(shí)候,層級的增加會(huì)大大增加對資源和時(shí)間的消耗。其次,view個(gè)數(shù)從原來的13個(gè)變成了現(xiàn)在的5個(gè)。太棒了。

可是意外就像bug,總在你想不到的地方出現(xiàn)。這么完美的實(shí)現(xiàn)方式,到最后我們竟然無法設(shè)置TextView加載的drawable的大小!!也就是說資源文件本身寬高多大就只能多大。安卓沒有提供修改這個(gè)drawable大小的API.驚不驚喜,意不意外。

那么問題來了。我們到底能不能修改他的大小呢,答案當(dāng)然是能,這就需要我們通過繼承TextView來改造一下他的方法來實(shí)現(xiàn)。接下來我就向大家介紹一下我的思考過程和實(shí)現(xiàn)方式,一起看看每一步是否是合理的。

drawable大小的實(shí)現(xiàn)原理

首先當(dāng)然是閱讀源碼了,對此我們需要有一個(gè)突破口,這里我就從TextVIew的drawableTop屬性開始。我們在文件中設(shè)置了這個(gè)屬性,源碼中肯定要有相對應(yīng)的操作。在TextView的源碼里我們搜索drawableTop,

第一步:

在TextView的構(gòu)造方法里系統(tǒng)獲取了drawableTop屬性,并復(fù)制給drawableTop變量。 源碼:

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

第二步:

我們查找DrawableTop變量。順著代碼往下一路走來,依然是在構(gòu)造方法里。當(dāng)獲取完了上下左右四個(gè)drawable后,系統(tǒng)執(zhí)行了下面這行代碼:

setCompoundDrawablesWithIntrinsicBounds(drawableLeft, drawableTop, drawableRight, drawableBottom);

顯而易見,這個(gè)方法對上下左右四個(gè)drawable做了處理。

第三步:

進(jìn)入setCompoundDrawablesWithIntrinsicBounds方法:下面是系統(tǒng)的源碼,代碼不長,主要看四個(gè)if判斷, 其實(shí)就是為四個(gè)drawable分別設(shè)置各自的大小。

/** * 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);

}

這個(gè)方法很好理解,核心就是setBounds(0,0, top.getIntrinsicWidth(),top.getIntrinsicHeight());

這句話。到這里,就已經(jīng)很清晰了,系統(tǒng)獲取了我們?yōu)門extView設(shè)置的drawable,然后就根據(jù)drawable自身的大小來設(shè)置了要繪制時(shí)的邊界大小。所以我們在為TextVIew設(shè)置drawable時(shí),圖片是多大,就顯示多大,真是童叟無欺啊。只是苦了我們搬磚的,還得小心翼翼的找UI大大給切圖。

既然問題找到了。那解決就很容易了。我們實(shí)現(xiàn)一個(gè)自定義TextView,重寫setCompoundDrawablesWithIntrinsicBounds方法,在里面將setBound方法的傳值改為我們設(shè)置的大小就OK了。

自定義TextView----XXDrawableTextView

千里之行,始于足下,開始自定義XXDrawableTextView。

第一步:

在style.xml文件中設(shè)置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"/>

這里我把上下左右四個(gè)為止的drawable都納入處理的范圍了,其實(shí)邏輯都一樣。

然后再添加下面這段:

<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方法,為各個(gè)drawable寶寶們設(shè)置寬度和高度。


@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);}

你看 ,其實(shí)最關(guān)鍵的還是setBound方法,將我們獲取到的寬高度傳了進(jìn)去。

第四步:

到這,自定義View的基本工作已經(jīng)做完了,我們可以在布局文件中使用了,

注意 ,因?yàn)槭亲远xview,一定不要忘記在布局文件頭部添加

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

最后寫一個(gè)LinearLayout,里面就替換成四個(gè)我們自定義的XXDrawableTextView,輕輕的為每一個(gè)XXDrawableTextView設(shè)置drawableHeight和drawableWidth屬性。就像下面這樣:

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

靜悄悄的,簡潔的就像什么都沒發(fā)生一樣,然而一切卻變了,我們優(yōu)雅的實(shí)現(xiàn)了tab導(dǎo)航欄的效果,層級依然是2,view個(gè)數(shù)依然是最少的5個(gè)。App的運(yùn)行效率和性能就這么不經(jīng)意的被我們提高了那么一丟丟。

下面是具體的自定義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.

*

*用來解決文字和圖片組合時(shí)造成的view層級過多的問題。

*比如上圖標(biāo)下文字,下圖標(biāo)上文字,尤其是在實(shí)現(xiàn)一組tab均勻平鋪的效果時(shí)出現(xiàn)的大量view層級

*比如各app的底部欄,本類只要一層view既可。

*

*注意:必須設(shè)置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方法會(huì)首先在父類的構(gòu)造方法中執(zhí)行,

*彼時(shí)執(zhí)行時(shí)drawable的大小還都沒有開始獲取,都是0,

*這里獲取完自定義的寬高屬性后再次調(diào)用這個(gè)方法,插入drawable的大小

**/

setCompoundDrawablesWithIntrinsicBounds(

left,top,right,bottom);

}

/**

*SetstheDrawables(ifany)toappeartotheleftof,above,tothe

*rightof,andbelowthetext.Use{@codenull}ifyoudonotwanta

*Drawablethere.TheDrawables'boundswillbesettotheirintrinsic

*bounds.

*

*CallingthismethodwilloverwriteanyDrawablespreviouslysetusing

*{@link#setCompoundDrawablesRelative}orrelatedmethods.

*這里重寫這個(gè)方法,來設(shè)置上下左右的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);

}

/*

*代碼中動(dòng)態(tài)設(shè)置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種狀態(tài)

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的第二個(gè)參數(shù)是以多少度為開始點(diǎn),第三個(gè)參數(shù)-90度表示逆時(shí)針畫弧,正數(shù)表示順時(shí)針

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();*/

}

}

其中注釋掉的是設(shè)置drawable為圓角的嘗試,可忽略。

我還添加了個(gè)修改寬高度的方法,可以運(yùn)行時(shí)在代碼中設(shè)置drawable的寬高。

其次還需要注意一下setCompoundDrawablesWithIntrinsicBounds方法的調(diào)用位置。

因?yàn)檫@個(gè)方法是在父類的構(gòu)造方法中調(diào)用的,也就是說當(dāng)執(zhí)行XXDrawableTextView的構(gòu)造方法時(shí),

首先會(huì)執(zhí)行父類的構(gòu)造方法,在執(zhí)行super方法時(shí),這個(gè)方法已經(jīng)進(jìn)行了。這時(shí)候getAttribute方法還沒調(diào)用呢,

也就是說各個(gè)寬高度屬性值都還沒獲得,所以需要在執(zhí)行完getArttribute方法后再調(diào)用一遍

setCompoundDrawablesWithIntrinsicBounds。

總結(jié):

優(yōu)點(diǎn)呢,簡潔明了,就那么回事,缺點(diǎn)呢就是不能針對其中的drawable再做進(jìn)一步的處理了,比如設(shè)置成圓角之類。嘗試了一下自定義,發(fā)現(xiàn)太麻煩了。如果真的出現(xiàn)圖片設(shè)置成圓角的場景,

恐怕還得使用TextView加自定義的圓角ImageView。或者,找UI大大們了。

如果幫到你了,給個(gè)贊吧。

另:
簡書的編輯環(huán)境咋就這么差勁呢,代碼連個(gè)換行都不行,瞧這排版,醉了。

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,197評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,415評論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,104評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,884評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,647評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,130評論 1 323
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,208評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,366評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,887評論 1 334
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,737評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,939評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,478評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,174評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,586評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,827評論 1 283
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,608評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,914評論 2 372

推薦閱讀更多精彩內(nèi)容