UI组件-实用组件

前言

我们听过无数的道理,却仍旧过不好这一生。

Toast组件

Toast是一种非常方便的提示消息框,它会在程序界面上显示一个简单的提示信息。它具有如下两个特点。
  • Toast提示信息不会获得焦点。

  • Toast提示信息过一段时间会自动消失。

使用Toast来生成提示消息也非常简单,只要如下几个步骤。
  • 调用Toast的构造器或makeText()静态方法创建一个Toast对象。

  • 调用Toast的方法来设置该消息的对齐方式、页边距等。

  • 调用Toast的show()方法将它显示出来。

除此之外,Toast不仅可以显示文本,还可以显示图片、列表之类的复杂提示。

代码示例

toast.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center_horizontal" >
    <Button
        android:id="@+id/bt1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="显示简单提示"
        />
    <Button
        android:id="@+id/bt2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="显示图片提示"
        />
</LinearLayout>

MainActivity.java
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.toast);
        Button simple = (Button) findViewById(R.id.bt1);
        //为按钮的单击事件绑定事件监听器
        simple.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                //创建一个Toast提示消息                                         //设置该Toast提示信息的持续时间
                Toast toast = Toast.makeText(MainActivity.this, "简单的提示信息", Toast.LENGTH_SHORT);
                toast.show();
            }
        });

        Button imageBt = (Button) findViewById(R.id.bt2);
        imageBt.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                //创建一个Toast提示信息
                Toast toast = new Toast(MainActivity.this);
                //设置Toast的显示位置
                toast.setGravity(Gravity.CENTER, 0, 0);
                //创建一个ImageView
                ImageView image = new ImageView(MainActivity.this);
                image.setImageResource(R.drawable.ic_launcher);
                //创建一个LinearLayout容器
                LinearLayout ll = new LinearLayout(MainActivity.this);
                //向LinearLayout中添加图片、原有的View
                ll.addView(image);
                //创建一个TextView
                TextView textView = new TextView(MainActivity.this);
                textView.setText("带图片的提示信息");
                textView.setTextSize(24);
                textView.setTextColor(Color.BLUE);
                ll.addView(textView);
                //设置Toast显示自定义View
                toast.setView(ll);
                //设置Toast的显示时间、
                toast.setDuration(Toast.LENGTH_LONG);
                toast.show();
            }
        });
    }
}

效果

Screenshot_20171023-104940.png

提示

建议使用对话框来完成图片提示及其列表显示之类的复杂提示

CalendarView组件

日历视图(CalendarView)用于显示和选择日期,用户既可以选择日期,也可通过触摸来滚动日历。

代码示例

calendarview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="选择您的生日:"
        />
    <!-- 设置以星期二作为每周的第一天,设置该组件总共显示4个星期,并对该组件的日期时间进行了定制 -->
    <CalendarView
        android:id="@+id/calendarView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:firstDayOfWeek="3"
        android:shownWeekCount="4"
        android:focusedMonthDateColor="#f9f"
        android:weekSeparatorLineColor="#ff0"
        android:unfocusedMonthDateColor="#f00"
        />
</LinearLayout>

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.calendarview);
        CalendarView cv = (CalendarView) findViewById(R.id.calendarView);

        cv.setOnDateChangeListener(new OnDateChangeListener() {

            @Override
            public void onSelectedDayChange(CalendarView view, int year, int month, int dayOfMonth) {

                //使用Toast显示用户选择的日期
                Toast.makeText(MainActivity.this, "您的生日是" + year + "年" + month + "月" + dayOfMonth + "日",
                        Toast.LENGTH_SHORT).show();
            }
        });
    }
}

MainActivity.java

效果

Screenshot_20171023-111302.png

提示

android:dataTextAppearance属性,设置该日历视图的日期文字的样式。
android:firstDayOfWeek属性,设置每周的第一天。
android:showWeekNumber属性,设置是否显示第几周。
android:设置该日历组件总共显示几个星期。

DatePicker和TimePicker组件

日期、时间选择器是两个简单的组件,由FrameLayout派生而来,其中DatePicker供用户选择日期;TimePicker供用户选择时间。

代码示例

picker.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="选择购买本书的具体时间"
        />

    <DatePicker
        android:id="@+id/datePicker"
        android:layout_width="wrap_content"
        android:layout_height="200dp"
        android:layout_gravity="center_horizontal"
        android:startYear="2000"
        android:endYear="2018"
        android:calendarViewShown="true"
        android:spinnersShown="true"
        />
    <TimePicker
        android:id="@+id/timePicker"
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:layout_gravity="center_horizontal"
        />

    <EditText
        android:id="@+id/show"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:editable="false"
        android:cursorVisible="false"
        />

</LinearLayout>

public class MainActivity extends Activity {

    private int year;
    private int month;
    private int day;
    private int hour;
    private int minute;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.picker);
        DatePicker datePicker = (DatePicker) findViewById(R.id.datePicker);
        TimePicker timePicker = (TimePicker) findViewById(R.id.timePicker);

        //获取当年的年、月、日、小时、分钟
        Calendar c = Calendar.getInstance();
        year = c.get(Calendar.YEAR);
        month = c.get(Calendar.MONTH);
        day = c.get(Calendar.DAY_OF_MONTH);
        hour = c.get(Calendar.HOUR);
        minute = c.get(Calendar.MINUTE);

        //初始化DatePicker组件,初始化指定监听器
        datePicker.init(year, month, day, new OnDateChangedListener() {

            @Override
            public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {

                MainActivity.this.year = year;
                MainActivity.this.month = monthOfYear;
                MainActivity.this.day =dayOfMonth;
                //显示当前日期、时间、
                showDate(year, month, day, hour, minute);
            }
        });

        //为TimePicker指定监听器
        timePicker.setOnTimeChangedListener(new OnTimeChangedListener() {

            @Override
            public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {

                MainActivity.this.hour = hourOfDay;
                MainActivity.this.minute = minute;
                //显示当前日期、时间、
                showDate(year, month, day, hour, minute);
            }
        });
    }

    //定义在EditText中显示当前日期、时间的方法
    private void showDate(int year, int month,
            int day, int hour, int minute)
    {
        EditText show = (EditText) findViewById(R.id.show);
        show.setText("您的购买日期为:" + year + "年" + (month + 1) + "月" + day + "日" + hour + "时" + minute +"分");
    }

}

MainActivity.java

效果

Screenshot_20171023-124453.png

提示

android:calendarViewShown属性,设置该日期选择器是否显示CalendarView组件。
android:endYear属性,设置日期选择器允许选择的最后一年。
android:startYear属性,设置日期选择器允许选择的第一年。
android:spinnersShown属性,设置该日期选择器是否显示Spinner日期选择组件。

NumberPicker组件

数值选择器用于让用户输入数值,用户既可以通过键盘输入数值,也可以通过拖动来选择数值。使用该组件常用的方法如下。
  • setMinValue(int minVal):设置该组件支持的最小值。

  • setMaxValue(int maxVal):设置该组件支持的最大值。

  • setValue(int value):设置该组件的当前值。

代码示例

numberpicker.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >
    <TableRow
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <TextView
            android:text="选择低价:"
            android:layout_width="120dp"
            android:layout_height="wrap_content"
            />

        <NumberPicker
            android:id="@+id/np1"
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:focusable="true"
            android:focusableInTouchMode="true"
            />
    </TableRow>
    <TableRow
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <TextView
            android:text="选择高价:"
            android:layout_width="120dp"
            android:layout_height="wrap_content"
            />
        <NumberPicker
            android:id="@+id/np2"
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:focusable="true"
            android:focusableInTouchMode="true"
            />
    </TableRow>
</TableLayout>

MainActivity.java
public class MainActivity extends Activity {

    NumberPicker np1,np2;
    //定义最低价格、最高价格的初始值

    int minPrice = 25, maxPrice = 75;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.numberpicker);

        np1 = (NumberPicker) findViewById(R.id.np1);
        //设置np1的最大值和最小值
        np1.setMinValue(10);
        np1.setMaxValue(50);
        //设置np1的当前值
        np1.setValue(minPrice);
        np1.setOnValueChangedListener(new OnValueChangeListener() {
            //当NumberPicker的值发生改变时,将会激发该方法
            @Override
            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {

                minPrice = newVal;
                showSelectedPrice();
            }
        });

        np2 = (NumberPicker) findViewById(R.id.np2);
        //设置np2的最小值和最大值
        np2.setMinValue(60);
        np2.setMaxValue(100);
        //设置np2的当前值
        np2.setValue(maxPrice);
        np2.setOnValueChangedListener(new OnValueChangeListener() {

            @Override
            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {

                maxPrice = newVal;
                showSelectedPrice();
            }
        });
    }

    private void showSelectedPrice() {

        Toast.makeText(this, "您选择最低价格为: " + minPrice +
                ",最高价格为: " + maxPrice, Toast.LENGTH_SHORT).show();
    }
}

效果

Screenshot_20171023-131415.png

SearchView组件

SearchView是搜索框组件,它可以让用户在文本框内输入文字,并允许通过监听器监控用户输入,当用户输入完成后提交搜索时,也可以通过监听器执行实际的搜索。使用SearchView时可使用如下常用的方法。
  • setIconifiedByDefault(boolean iconified):设置该搜索框默认是否自动缩小为图标。

  • setSubmitButtonEnabled(boolean enable):设置是否显示搜索按钮。

  • setQueryHint(CharSequence hint):设置搜索框内默认显示的提示文本。

  • setOnQueryTextListener(SearchView.OnQueryTextListener listener):为该搜索设置监听事件。

如果为SearchView增加一个配套的ListView,则可以为SearchView增加自动完成的功能。

代码示例

searchview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <SearchView
        android:id="@+id/sv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
    <ListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        />
</LinearLayout>

MainActivity.java
public class MainActivity extends Activity {

    private SearchView sv;
    private ListView lv;

    // 自动完成的列表
    private final String[] mString = { "aaaaa", "bbbbbb", "cccccc" };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.searchview);

        lv = (ListView) findViewById(R.id.lv);
        lv.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
                mString));

        //设置ListView启用过滤器
        lv.setTextFilterEnabled(true);
        sv = (SearchView) findViewById(R.id.sv);
        //设置该SearchView默认是否自动缩小为图标
        sv.setIconifiedByDefault(true);
        //设置该SearchView显示搜索按钮
        sv.setSubmitButtonEnabled(true);
        //设置该SearchView内默认显示的提示文本
        sv.setQueryHint("查找");
        //为该组件设置监听器
        sv.setOnQueryTextListener(new OnQueryTextListener() {

            //单击搜索按钮时激发该方法
            @Override
            public boolean onQueryTextSubmit(String query) {

                //实际应用中应该在该方法中执行查询
                Toast.makeText(MainActivity.this, "您的选择是:" + query, Toast.LENGTH_SHORT).show();
                return false;
            }

            //用户输入字符时激活该方法
            @Override
            public boolean onQueryTextChange(String newText) {

                //如果newText不是长度为0的字符串
                if(TextUtils.isEmpty(newText)) {
                    //清楚ListView的过滤
                    lv.clearTextFilter();
                }
                else {
                    //使用用户输入的内容对ListView的列表项进行过滤
                    lv.setFilterText(newText);
                }
                return true;
            }
        });
    }
}

效果

Screenshot_20171023-134249.png

TabHost组件

选项卡(TabHost)是一种非常实用的组件,TabHost可以很方便地在窗口上放置多个标签页,每个标签页相当于获得了一个与外部容器相同大小的组件摆放区域。通过这种方式,就可以在一个容器里放置更多的组件,例如手机系统都会在同一个窗口中定义多个标签页来显示通话记录。
使用TabHost的一般步骤如下。
  • 在界面布局文件中定义TabHost组件,并为该组件定义该选项卡的内容。

  • Activity应该继承TabActivity。

  • 调用TabActivity的getTabHost()方法获取TabHost对象。

  • 通过TabHost对象的方法来创建、添加选项卡。

代码示例

tabhost.xml
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <!-- 定义第一个标签页内容 -->

            <LinearLayout
                android:id="@+id/tab01"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical" >

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="已拨电话" />
            </LinearLayout>

            <!-- 定义第二个标签页内容 -->

            <LinearLayout
                android:id="@+id/tab02"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical" >

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="未接电话" />
            </LinearLayout>

            <!-- 定义第三个标签内容 -->
            <LinearLayout
                android:id="@+id/tab03"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical" >

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="语音信箱" />
            </LinearLayout>
        </FrameLayout>
    </LinearLayout>
</TabHost>
MainActivity.java
public class MainActivity extends TabActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tabhost);

        // 获取该Activity里面的TabHost组件

        TabHost tabHost = getTabHost();
        // 创建第一个Tab界面

        TabSpec tab1 = tabHost.newTabSpec("tab1").setIndicator("已接电话")// 设置标题
                .setContent(R.id.tab01);// 设置内容

        // 添加第一个标签页
        tabHost.addTab(tab1);

        TabSpec tab2 = tabHost.newTabSpec("tab2").setIndicator("未接电话")// 设置标题
                .setContent(R.id.tab02);// 设置内容

        // 添加第二个标签页
        tabHost.addTab(tab2);

        TabSpec tab3 = tabHost.newTabSpec("tab3").setIndicator("语音信箱")// 设置标题
                .setContent(R.id.tab03);// 设置内容

        // 添加第三个标签页
        tabHost.addTab(tab3);
    }
}

效果

Screenshot_20171023-141612.png

提示

最新版本的Anroid平台已经不再推荐使用TabActivity,而是推荐使用Fragement来代替TabActivity。

ScrollView和HorizontalScrollView组件

ScrollView由FrameLayout派生而出,它就是一个用于为普通组件添加滚动条的组件。ScrollView的作用是为该组件添加垂直滚动条,HorizontalScrollView的作用是为该组件添加水平滚动条。

代码示例

<?xml version="1.0" encoding="utf-8"?>
<!-- 定义ScrollView,为里面的组件添加垂直滚动条 -->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <!-- 定义HorizontalScrollView,为里面的组件添加水平滚动条 -->
    <HorizontalScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >
            ....若干个TextView
        </LinearLayout>
    </HorizontalScrollView>
</ScrollView>

效果

Screenshot_20171023-143018.png

Notification组件

Notification是显示在手机状态栏的通知——手机状态栏位于手机屏幕的最上方,它是一种具有全局效果的通知。程序一般通过NotificationManager服务来发送Notification。

代码示例

notification.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="发送"
        android:onClick="send"
        android:layout_gravity="center_horizontal"
        />

     <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="取消"
        android:onClick="cancel"
        android:layout_gravity="center_horizontal"
        />
</LinearLayout>

MainActivity.java
public class MainActivity extends Activity {

    static final int NOTIFICATION_ID = 0x123;
    NotificationManager nm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.notification);

        //获取系统的NotificationManager服务
        nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    }

    public void send(View v)
    {
        //创建一个启动其他Activity的Intent
        Intent intent = new Intent(MainActivity.this,OtherActivity.class);

        PendingIntent pi = PendingIntent.getActivity(MainActivity.this, 0, intent, 0);

        Notification notify = new Notification.Builder(this)
                //设置打开该通知,该通知自动取消
                .setAutoCancel(true)
                //设置显示在状态栏的通知提示信息
                .setTicker("有新消息")
                //设置通知内容的图标
                .setSmallIcon(R.drawable.ic_launcher)
                //设置通知内容的标题、
                .setContentTitle("一条新通知")
                //设置通知内容
                .setContentText("你好,halo")
                //设置使用系统默认的声音、默认LED灯
                .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS)
                //设置通知将要启动的Intent
                .setContentIntent(pi).build();
        //发送通知
        nm.notify(NOTIFICATION_ID, notify);
    }
    public void cancel(View v)
    {
        nm.cancel(NOTIFICATION_ID);
    }
}

效果

Screenshot_20171023-150114.png

提示

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

推荐阅读更多精彩内容