實(shí)現(xiàn)自定義控件

自定義控件的分類

[1]通過系統(tǒng)提供的原生控件進(jìn)行組合 來達(dá)到自定義的需求
[2]定義一個(gè)類繼承View(繼承原生的類)
定義一個(gè)類繼承ViewGroup (五大布局都繼承自viewgroup)

下拉列表(原生控件進(jìn)行組合)

Paste_Image.png

功能分析:
由edittext 按鈕 popupwindow listview 通過這樣幾個(gè)控件進(jìn)行組合達(dá)到需求

實(shí)現(xiàn)步驟
**1先畫布局定義布局 **

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    tools:context=".MainActivity" >
    <EditText
        android:id="@+id/et_number"
        android:layout_width="250dp"
        android:layout_height="wrap_content" />
    <!--去掉背景-->
    <!--android:background="@null"-->
    <ImageButton
        android:id="@+id/ib_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@id/et_number"
        android:background="@null"
        android:src="@drawable/down_arrow" />
</RelativeLayout>

2 當(dāng)點(diǎn)擊按鈕的時(shí)候彈出popupwindow

//彈出popupwindow 寬高 和Edittext寬高一樣
protected void showPopUpWindow() {
    //[0]準(zhǔn)備popupwindow 要展示的數(shù)據(jù)(listview)
    ListView contentView = initListView();
    //[1]構(gòu)造popupwindow
    Popupwindow沒必要new多次, 因此先判斷一下popupwindow是否為空
    if (popupWindow == null) {
        popupWindow = new PopupWindow(contentView, et_number.getWidth() - 8, 250, true);
        popupwindow默認(rèn)不讓獲取焦點(diǎn)(因此使用構(gòu)造方法為4個(gè)參數(shù)的)
        //參1:要展示的view 參2: 寬  參3: 高 參4:Boolean—popupwindow是否可以獲取焦點(diǎn)
//設(shè)置背景
        //點(diǎn)擊popupwindow外面popupwindow不消失,想讓popupwindow消失,因此給popupwindow設(shè)置背景
        popupWindow.setBackgroundDrawable(new ColorDrawable());

    }
    //[2]展示popupwindow  anchor:
    //參1popupwindow依賴哪個(gè)控件(展示在哪個(gè)控件下方)
    // 參2  偏移量x
    //參3  偏移量y
    //偏移量可以讓盡量popupwindow與依賴的控件對(duì)齊的一致
    popupWindow.showAsDropDown(et_number, 4, -4);

}

再設(shè)置adapter--點(diǎn)擊事件

繪制實(shí)戰(zhàn)--重寫ondraw方法中—CANVAS.DRAW畫

    //將new paint實(shí)例放在構(gòu)造方法中
    //在ondraw方法中避免申請(qǐng)paint對(duì)象,因?yàn)橛锌赡茉诋嫷倪^程中申請(qǐng)多次,最好寫在構(gòu)造方法中
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        //[1]創(chuàng)建畫筆類
        mPaint = new Paint();
    }

    //[1]畫線 兩點(diǎn)確定一條線
    canvas.drawLine(0,0,100,100,paint);
    //參1 參2   起點(diǎn)坐標(biāo) 
    //參3 參4 終點(diǎn)坐標(biāo)
    //參5 畫筆

    //[2]畫圓  需要知道圓心和半徑
    //畫圓  知道圓心 和 半徑  通過cx cy確定圓心  radius:半徑
    canvas.drawCircle(100,100,30,mPaint);
    //參1 參2  確定圓心坐標(biāo)(在view上畫圓,因此找圓心只要是view寬高的一半即可)
    //參3 半徑
    //參4 paint

    //修改畫筆的(屬性)
    //修改畫筆顏色(畫筆默認(rèn)的顏色是黑色的)
    mPaint.setColor(Color.RED);
    //設(shè)置畫筆樣式  空心(默認(rèn)實(shí)心)
    mPaint.setStyle(Style.STROKE);
    //去除鋸齒 
    mPaint.setAntiAlias(true);

    // [3]畫圖片
    //將圖片轉(zhuǎn)換成bitmap
    // 2把haha.jpg轉(zhuǎn)換成一個(gè)bitmap對(duì)象
    mBitmap=BitmapFactory.decodeResource(

    getResources(),R

    .drawable.haha);
    //畫(bitmap)
    canvas.drawBitmap(mBitmap,10,10,mPaint);
    //參1 bitmap
    //參2 距view 左邊的位置
    //參3 距view 頂部的位置
    //參4 paint

    //[4]畫三角形(畫路徑)
    //定義三個(gè)點(diǎn) 畫一個(gè)三角形
    int x1 = 100, y1 = 0;
    int x2 = 20, y2 = 180;
    int x3 = 180, y3 = 180;
    //拿到path路徑對(duì)象--先移動(dòng)到第一個(gè)點(diǎn)--然后挨個(gè)連接--有頭有尾(其實(shí)就是構(gòu)造出三角形的路徑)
    mPath=new

    Path();

    mPath.moveTo(x1,y1); //先移動(dòng)到x1 y1點(diǎn)
    mPath.lineTo(x3,y3); //連接
    mPath.lineTo(x2,y2);
    mPath.lineTo(x1,y1);
    //將構(gòu)造的路徑畫出來(畫三角形)
    //把三個(gè)點(diǎn)連起來即為三角形
    canvas.drawPath(mPath,mPaint);
    //參1 path 參2 paint


    // [5]畫扇形  畫扇形drawArc
    //rectF控制畫扇形的范圍
    canvas.drawArc(rectF,0,swapAngle,false,mPaint);
    //參1 矩形區(qū)域(通過這個(gè)矩形來限定畫的扇形的大小)
    //參2 開始的一個(gè)角度,與水平向右的夾角(順時(shí)針為正)
    //參3 掃過的的一個(gè)角度,與水平向右的夾角(順時(shí)針為正)
    //參4 bollean(true 圓弧有邊  false 圓弧沒有邊)
    //參5 paint
    //構(gòu)造矩形
    rectF=new

    RectF(5,5,170,170);

    //[6]動(dòng)態(tài)畫圓
    //通過畫扇形drawArc方法來畫圓(調(diào)用一次方法只能畫一段圓弧)
    //我們只需模擬一些數(shù)據(jù),動(dòng)態(tài)的改變參3的值即可
    //因此需要定義一個(gè)變量,接受傳來的值
    //將傳來的值傳給canvas.drawArc方法的參3(這個(gè)方法寫在ondraw中)
    //請(qǐng)求重新繪制

    //設(shè)置點(diǎn)擊事件開始—模擬數(shù)據(jù)畫圓
    // 點(diǎn)擊按鈕 動(dòng)態(tài)畫圓
    public void click(View v) {

        // 開啟一個(gè)子線程
        new Thread() {
            public void run() {
                // 模擬數(shù)據(jù)
                for (int i = 1; i <= 100; i++) {
                    // 開始畫
                    myView.startDraw(i);
                    // 睡眠50毫秒(因?yàn)楫嫷奶?開不出效果,睡一會(huì)兒)(睡眠開子線程)
                    SystemClock.sleep(50);
                }

            }

            ;
        }.start();
    }

    //找到所要畫圓的view,創(chuàng)建方法,傳遞數(shù)據(jù), 并請(qǐng)求重新繪制
    public void startDraw(int x) {
        //定義一個(gè)變量(成員變量)進(jìn)行傳值
        mprogress = x;
        //請(qǐng)求重新繪制
        // 請(qǐng)求重新繪制 --->onDraw方法就會(huì)執(zhí)行
        // invalidate();

        // 如果不是ui 線程 應(yīng)該調(diào)用下面這個(gè)方法()--請(qǐng)求重新繪制 --->onDraw方法就會(huì)執(zhí)行
        postInvalidate();

    }

    //重寫ondraw方法,畫圓弧,
    //往當(dāng)前控件上畫內(nèi)容
    @Override
    protected void onDraw(Canvas canvas) {
        // rectF控制畫扇形的范圍
        數(shù)據(jù)傳入?yún)?shù)3
        float swapAngle = mprogress / 100f * 360;

        canvas.drawArc(rectF, 0, swapAngle, false, mPaint);
        // 參1 矩形區(qū)域(通過這個(gè)矩形來限定畫的扇形的大小)
        // 參2 開始的一個(gè)角度,與水平向右的夾角(順時(shí)針為正)
        // 參3 掃過的的一個(gè)角度,與水平向右的夾角(順時(shí)針為正)
        // 參4 bollean(true 圓弧有邊 false 圓弧沒有邊)
        // 參5 paint
    }
    //構(gòu)造矩形
    rectF=new RectF(5,5,170,170);

可滑動(dòng)開關(guān) –繼承view(自定義控件)

需求分析 :實(shí)際是由2張圖片 疊加到一起組成一個(gè)View
自己做自定義控件就兩種方式,繼承view還是繼承viewgroup---如果需要包裹孩子就繼承viewgroup
定義一個(gè)類繼承view---添加兩個(gè)參數(shù)的構(gòu)造方法

public class ToogleView extends View {
    public ToogleView(Context context, AttributeSet attrs) {
        super(context, attrs);
  }
}

使用該view--在xml中聲明

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:itheima="http://schemas.android.com/apk/res/com.itheima.toogleview"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <com.itheima.toogleview.ToogleView
        android:id="@+id/toogleView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        itheima:toogleState="false" />

</RelativeLayout>

測量-根據(jù)自己的需求對(duì)當(dāng)前控件進(jìn)行測量—調(diào)用onmeasure方法

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 自己測量控件的寬和高 和當(dāng)前背景圖片一樣寬 一樣高
        setMeasuredDimension(toogleBgBitmap.getWidth(), toogleBgBitmap.getHeight());
    }

    ///把圖片變成bitmap---為了獲取背景圖片的寬高
    // [1]找到背景圖片和滑動(dòng)塊圖片 變成bitmap
    toogleBgBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.toogle_background);
    toogleSlideBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.toogle_slidebg);

不用排版,父類已經(jīng)排好版
控件上繪制內(nèi)容—重寫ondraw—拿掉super—畫好之后控件就展示上來了

// 往當(dāng)前控件上畫內(nèi)容 要重寫onDraw方法
@Override
protected void onDraw(Canvas canvas) {
    //畫開關(guān)背景--畫圖片的時(shí)候不用paint
    canvas.drawBitmap(toogleBgBitmap, 0, 0, null);
    //畫滑動(dòng)塊--畫圖片的時(shí)候不用paint
    canvas.drawBitmap(toogleSlideBitmap, slideLeftPosition, 0, null);
}

讓當(dāng)前的view處理事件—畫好開關(guān)后——需要重寫onTouchEvent—有按下 移動(dòng) 抬起 等事件—返回true(當(dāng)前view消費(fèi)事件)

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action) {
        case MotionEvent.ACTION_DOWN://按下
            break;
        case MotionEvent.ACTION_MOVE://移動(dòng)
            break;
        case MotionEvent.ACTION_UP: // 手指抬起
            break;

        }
        return true; // 代表讓當(dāng)前控件處理事件 消費(fèi)事件
    }

按鈕移動(dòng)效果
獲取按下坐標(biāo)—獲取移動(dòng)后的坐標(biāo)—算出移動(dòng)距離—讓滑塊移動(dòng)這么長的距離(移動(dòng)著么長距離其實(shí)就是重新再新的坐標(biāo)上繪制按鈕)

//1獲取手指按下的x坐標(biāo)
downX=event.getX();
//1獲取手指移動(dòng)后坐標(biāo)
float moveX = event.getX();
//2 算出移動(dòng)距離
float distanceX = moveX - downX;
//指定滑塊移動(dòng)到的位置---賦值給繪制滑塊的參數(shù)3()
slideLeftPosition+=distanceX;
//更改起始點(diǎn)
// [4]改變一下起始點(diǎn)
downX=moveX;
//請(qǐng)求重新繪制 onDraw方法就會(huì)執(zhí)行
invalidate();

限定滑塊的左右邊界

//右邊界最大值—背景寬-滑塊的寬
slideLeftMax = toogleBgBitmap.getWidth() - toogleSlideBitmap.getWidth();
//對(duì)邊界進(jìn)行判斷
if (slideLeftPosition <= 0) {
    slideLeftPosition = 0;
} else if (slideLeftPosition >= slideLeftMax) {
    slideLeftPosition = slideLeftMax;
}

當(dāng)手指抬起時(shí),滑倒一個(gè)位置,抬起后接著滑動(dòng)到左邊或者右邊

//當(dāng)手指抬起時(shí),獲取到手指在的 位置,判斷滑塊的中心店位置,過去

//1算出背景中心點(diǎn)位置
float tooglebgCenterPosition = toogleBgBitmap.getWidth() / 2;
//2 算出滑動(dòng)塊的中心點(diǎn)位置 = slideLeftPosition + 滑塊背景的一半
float sliecenterPosition = slideLeftPosition
        + toogleSlideBitmap.getWidth() / 2;
//判斷滑塊與背景的相對(duì)位置
if (sliecenterPosition <= tooglebgCenterPosition) {
    // 開關(guān)處于關(guān)
    slideLeftPosition = 0;
} else {
    slideLeftPosition = slideLeftMax;
}

View狀態(tài)發(fā)生改變時(shí)的回調(diào)事件--實(shí)現(xiàn)開關(guān)事件對(duì)應(yīng)的回調(diào)方法*

//我們想要在開關(guān)開啟或者關(guān)閉的時(shí)候,執(zhí)行一些邏輯要暴露此方法
//回調(diào)其實(shí)就是多態(tài)的一個(gè)應(yīng)用定義接口—暴回調(diào)方法
// 定義接口
public interface OnToogleViewListener {
    // 當(dāng)開關(guān)的狀態(tài)發(fā)生改變的時(shí)候調(diào)用
    void onToogleState(boolean state);
}

//開關(guān)狀態(tài)發(fā)生變化時(shí)調(diào)用該方法
//當(dāng)手指抬起且開關(guān)狀態(tài)發(fā)生變化—調(diào)用該方法判斷手指是否抬起器開關(guān)狀態(tài)是否改變定義變量判斷是否抬手
/**
 * 是否抬起手 默認(rèn)false
 */
private boolean isHandup;
//當(dāng)手指抬起的時(shí)候置為true
        isHandup = true;
//當(dāng)我們判斷為抬起之后將其設(shè)置為false
        isHandup = false;

//定義開關(guān)默認(rèn)狀態(tài)
/**
 * 代表開關(guān)的默認(rèn)狀態(tài)
 */
private boolean isOpen;

//當(dāng)手指抬起獲取滑動(dòng)后的開關(guān)狀態(tài)

//3回調(diào)我們定義接口方法
if (isHandup){
    isHandup = false;
    //4獲取滑動(dòng)后的一個(gè)狀態(tài)
    boolean isOpenTemp = slideLeftPosition>0;
    //判斷如果臨時(shí)狀態(tài)與默認(rèn)狀態(tài)不一致則說明開關(guān)狀態(tài)發(fā)生變化了
    if (isOpen!=isOpenTemp && mListener!=null) {
        //說明開關(guān)的狀態(tài)改變了 我們就要觸發(fā)我們定義的回調(diào)方法
        mListener.onToogleState(isOpenTemp);
        //發(fā)生改變后將發(fā)生改變后的狀態(tài)—賦值給默認(rèn)狀態(tài)
                isOpen = isOpenTemp;
    }
}


//當(dāng)開關(guān)狀態(tài)放生變化時(shí),觸發(fā)回調(diào)方法(返回相應(yīng)的值)
mListener.onToogleState(isOpenTemp);

//發(fā)生改變后將發(fā)生改變后的狀態(tài)—賦值給默認(rèn)狀態(tài)
        isOpen = isOpenTemp;

//給view設(shè)置監(jiān)聽—傳入接口類型(子類)—給接口類型成員變量賦值
/**
 * 設(shè)置開關(guān)的監(jiān)聽器
 */
public void setOnToogleViewListener(OnToogleViewListener l) {
    this.mListener = l;
}

//使用view的監(jiān)聽事件-- ,當(dāng)監(jiān)聽到改變后執(zhí)行觸發(fā)后的方法       toogleView.setOnToogleViewListener(new OnToogleViewListener() {
    //這個(gè)什么時(shí)候被觸發(fā)呢?
    @Override
    public void onToogleState(boolean state) {
        if (state) {
            Toast.makeText(getApplicationContext(), "開", 1).show();
        }else {
            Toast.makeText(getApplicationContext(), "關(guān)", 1).show();
        }
    }
});

設(shè)置點(diǎn)擊事件—也包含在狀態(tài)改變中
當(dāng)按下時(shí),獲取按下的時(shí)間
long startTime = System.currentTimeMillis();
當(dāng)手指抬起時(shí)記住抬起的時(shí)間
long endTime = System.currentTimeMillis();
判斷
時(shí)間間隔小于200ms為點(diǎn)擊事件
手指抬起的位置大于滑塊的右邊界
Else手指抬起的位置大于滑塊的左邊界
Else(大于200ms為滑動(dòng)事件)

    case MotionEvent.ACTION_UP: // 手指抬起

            int endTime = (int) (System.currentTimeMillis() - startTime);
            System.out.println("endTiem:" + endTime);
            if (endTime < 200 && event.getX() > toogleSlideBitmap.getWidth()) {
                // 說明是點(diǎn)擊事件
                slideLeftPosition = slideLeftMax;
            } else if (endTime < 200) {
                slideLeftPosition = 0;
            } else {
                // 1算出背景中心點(diǎn)位置
                float tooglebgCenterPosition = toogleBgBitmap.getWidth() / 2;
                // 2 算出滑動(dòng)塊的中心點(diǎn)位置 = slideLeftPosition + 滑塊背景的一半
                float sliecenterPosition = slideLeftPosition
                        + toogleSlideBitmap.getWidth() / 2;
                if (sliecenterPosition <= tooglebgCenterPosition) {
                    // 開關(guān)處于關(guān)
                    slideLeftPosition = 0;
                } else {
                    slideLeftPosition = slideLeftMax;
                }
            }

            isHandup = true;

            break;

        }

給view設(shè)置自定義屬性
在res/values下創(chuàng)建attrs.xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="toogleView">
        <attr name="toogleState" format="boolean" />
    </declare-styleable>

</resources>

在layout布局中聲明

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:kailing="http://schemas.android.com/apk/res/com.kailing.toogleview"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.kailing.toogleview.ToogleView
        android:id="@+id/toogleView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        kailing:toogleState="false" />

</RelativeLayout>

在構(gòu)造方法中獲取屬性值

// [2]通過AttributeSet獲取屬性值
String namespace = "http://schemas.android.com/apk/res/com.kailing.toogleview";
//參1 根據(jù)命名空間取值,參2屬性名,參3 缺省值(默認(rèn)值)
boolean toogleState = attrs.getAttributeBooleanValue(namespace, "toogleState", false);
//使用—屬性
// [3]調(diào)用setToogleState
setToogleState(toogleState);

//[7]view自定義屬性
//1)在values下創(chuàng)建一個(gè)attrs.xml 文件
//2)xml里面的內(nèi)容抄襲系統(tǒng)定義好的
//3)在布局中使用  自己定義一個(gè)命名空間
//4)在當(dāng)前的view的構(gòu)造方法里同AttributeSet獲取我們定義的值

ViewGroup繪制流程

定義一個(gè)類繼承viewgroup(會(huì)自動(dòng)重寫onLayout方法—就在這個(gè)方法里完成排版)

//定義一個(gè)類繼承viewgroup(會(huì)自動(dòng)重寫onLayout方法—就在這個(gè)方法里完成排版)
public class MyViewGroup extends ViewGroup {
    //添加兩個(gè)參數(shù)的構(gòu)造方法
    public MyViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
}

布局文件中使用(在這里自view還是看不見的)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <com.kailing.viewgroup.MyViewGroup
        android:id="@+id/myViewGroup1"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/hello_world" />
    </com.kailing.viewgroup.MyViewGroup>

</RelativeLayout>

自己定義的viewgroup沒有對(duì)孩子進(jìn)行測量,和排版所以group里面的孩子顯示不出來
測量—onmeasure—測量孩子
當(dāng)前重寫onmeasure是對(duì)當(dāng)前自己的groupview進(jìn)行測量,讓父類進(jìn)行測量即可

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    //1獲取viewGroup的孩子
    // 參1因?yàn)榫鸵粋€(gè)孩子--寫0即可,多個(gè)孩子for循環(huán)即可
    // for (int i = 0; i < getChildCount(); i++) {}
    View childAt = getChildAt(0);
    //2//對(duì)孩子進(jìn)行測量—實(shí)際調(diào)用孩子的measure方法
    //(參數(shù)寫0是個(gè)非法值,當(dāng)系統(tǒng)發(fā)現(xiàn)寫0會(huì)采用默認(rèn)的測量對(duì)當(dāng)前的孩子進(jìn)行測量)(默認(rèn)的測量:孩子在聲明的時(shí)候?qū)懙闹?-對(duì)應(yīng)的模式)
    childAt.measure(0, 0);// 這行代碼執(zhí)行完--測量完了
    //3 獲取孩子的寬度 高度(獲取測量之后 的寬度和高度)
    measuredWidth = childAt.getMeasuredWidth();
    measuredHeight = childAt.getMeasuredHeight();
    // getMeasuredWidth 獲取到測量之后的值 
    // getWidth()當(dāng)view排版后才可以獲取
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

排版—完成對(duì)孩子進(jìn)行排版

    // 要在這個(gè)方法里面完成對(duì)孩子進(jìn)行排版
    // 參數(shù)
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
//找到孩子
        View childAt = getChildAt(0);
//對(duì)孩子進(jìn)行排版
        childAt.layout(l, t, measuredWidth, measuredHeight);

    }

繪制—不需要重寫ondraw方法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末幌蚊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子溃卡,更是在濱河造成了極大的恐慌溢豆,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瘸羡,死亡現(xiàn)場離奇詭異漩仙,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門讯赏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來垮兑,“玉大人,你說我怎么就攤上這事漱挎∠登梗” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵磕谅,是天一觀的道長私爷。 經(jīng)常有香客問我,道長膊夹,這世上最難降的妖魔是什么衬浑? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮放刨,結(jié)果婚禮上工秩,老公的妹妹穿的比我還像新娘。我一直安慰自己进统,他們只是感情好助币,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著螟碎,像睡著了一般眉菱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上掉分,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天俭缓,我揣著相機(jī)與錄音,去河邊找鬼酥郭。 笑死华坦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的不从。 我是一名探鬼主播惜姐,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼消返!你這毒婦竟也來了载弄?” 一聲冷哼從身側(cè)響起耘拇,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤撵颊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后惫叛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體倡勇,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了妻熊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夸浅。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖扔役,靈堂內(nèi)的尸體忽然破棺而出帆喇,到底是詐尸還是另有隱情,我是刑警寧澤亿胸,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布坯钦,位于F島的核電站,受9級(jí)特大地震影響侈玄,放射性物質(zhì)發(fā)生泄漏婉刀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一序仙、第九天 我趴在偏房一處隱蔽的房頂上張望突颊。 院中可真熱鬧,春花似錦潘悼、人聲如沸律秃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽友绝。三九已至,卻和暖如春肝劲,著一層夾襖步出監(jiān)牢的瞬間迁客,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來泰國打工辞槐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留掷漱,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓榄檬,卻偏偏與公主長得像卜范,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

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