Android - 沉浸式状态栏(2022.01.09更新)

2022.01.09 优化兼容Android12

 * 设置状态栏和导航栏的颜色和状态栏文本模式
 * @param statusBarColor 状态栏颜色, 如果该值为完全透明系颜色,那么标识DecorView是全屏显示的
 * @param isStatusBarLightMode 是否是黑色文字状态栏,默认:TRUE
 * @param navigationBarColor 底部导航栏颜色,默认:黑色 [Color.BLACK]
 * @param isNavigationBarLightMode 是否是黑色按钮导航栏,默认:FALSE
 */
@Suppress("DEPRECATION")
fun Activity.setSystemBarStyle(
    @ColorInt statusBarColor: Int,
    isStatusBarLightMode: Boolean = true,
    @ColorInt navigationBarColor: Int = Color.BLACK,
    isNavigationBarLightMode: Boolean = false
) {
    val decorView = window.decorView
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
    if (Build.VERSION.SDK_INT in
        arrayOf(Build.VERSION_CODES.LOLLIPOP, Build.VERSION_CODES.LOLLIPOP_MR1)
    ) window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
    if (statusBarColor == Color.WHITE || statusBarColor == Color.TRANSPARENT) {
        when {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> {
                WindowCompat.setDecorFitsSystemWindows(window, false)
                decorView.setOnApplyWindowInsetsListener { view, insets ->
                    val navigationBars = insets.getInsets(WindowInsetsCompat.Type.navigationBars())
                    view.findViewById<View>(android.R.id.content)
                        .updatePadding(bottom = navigationBars.bottom)
                    val insetsCompat = WindowInsetsCompat.toWindowInsetsCompat(insets)
                    ViewCompat.onApplyWindowInsets(view, insetsCompat).toWindowInsets()
                }
            }
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ->
                changeStatusBarMode(isStatusBarLightMode)
            else -> window.setFlags(
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
            )
        }
    }
    when {
        Build.VERSION.SDK_INT < Build.VERSION_CODES.R -> {
            decorView.systemUiVisibility = decorView.systemUiVisibility or
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
                decorView.systemUiVisibility =
                    decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
                if (!isNavigationBarLightMode) {
                    decorView.systemUiVisibility =
                        decorView.systemUiVisibility xor View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
                }
            }
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R && navigationBarColor == Color.TRANSPARENT) {
                decorView.systemUiVisibility =
                    decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            }
        }
        else -> with(WindowInsetsControllerCompat(window, decorView)) {
            isAppearanceLightStatusBars = isStatusBarLightMode
            isAppearanceLightNavigationBars =
                if (navigationBarColor == Color.TRANSPARENT) true else isNavigationBarLightMode
            show(WindowInsetsCompat.Type.systemBars())
        }
    }
    window.statusBarColor = statusBarColor
    window.navigationBarColor = navigationBarColor
}

2021.07.08更新如下,如果觉得好用,请给个赞,话不多说,上代码:


/**
 * 设置状态栏和导航栏的颜色和状态栏文本模式
 * @param statusBarColor 状态栏颜色, 如果该值为完全透明系颜色,那么标识DecorView是全屏显示的
 * @param isStatusBarLightMode 是否是黑色文字状态栏,默认:TRUE
 * @param navigationBarColor 底部导航栏颜色,默认:黑色 [Color.BLACK]
 * @param isNavigationBarLightMode 是否是黑色按钮导航栏,默认:FALSE
 */
fun Activity.setSystemBarStyle(
    @ColorInt statusBarColor: Int,
    isStatusBarLightMode: Boolean = true,
    @ColorInt navigationBarColor: Int = Color.BLACK,
    isNavigationBarLightMode: Boolean = false
) {
    val rootView = window.decorView
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
    if (statusBarColor == Color.WHITE || statusBarColor == Color.TRANSPARENT) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            changeStatusBarMode(isStatusBarLightMode)
        } else window.setFlags(
            WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
            WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
        )
        if (Build.VERSION.SDK_INT in arrayOf(
                Build.VERSION_CODES.LOLLIPOP,
                Build.VERSION_CODES.LOLLIPOP_MR1
            )
        ) {
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        }
    }
    // 如果状态栏是透明色,那么必然是布局全屏的设置,所以有如下设置
    if (statusBarColor == Color.TRANSPARENT) {
        window.statusBarColor = Color.TRANSPARENT
        rootView.systemUiVisibility = rootView.systemUiVisibility or
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
    } else {
        window.statusBarColor = statusBarColor
    }
    if (navigationBarColor == Color.TRANSPARENT) {
        rootView.systemUiVisibility =
            rootView.systemUiVisibility or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        rootView.systemUiVisibility =
            rootView.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
        if (!isNavigationBarLightMode) {
            rootView.systemUiVisibility =
                rootView.systemUiVisibility xor View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
        }
    }
    window.navigationBarColor = navigationBarColor
}

/**
 * 设置状态栏和导航栏的颜色和状态栏文本模式
 * @param statusBarColorId 状态栏颜色ID, 如果该值为完全透明系颜色ID [android.R.color.transparent],那么标识DecorView是全屏显示的
 * @param isStatusBarLightMode 是否是黑色文字状态栏,默认:TRUE
 * @param navigationBarColorId 底部导航栏颜色ID,默认:黑色 [android.R.color.black]
 * @param isNavigationBarLightMode 是否是黑色按钮导航栏,默认:FALSE
 */
fun Activity.setSystemBarStyleWithResources(
    @ColorRes statusBarColorId: Int,
    isStatusBarLightMode: Boolean = true,
    @ColorRes navigationBarColorId: Int = android.R.color.black,
    isNavigationBarLightMode: Boolean = false
) = setSystemBarStyle(
    getColorById(statusBarColorId),
    isStatusBarLightMode,
    getColorById(navigationBarColorId),
    isNavigationBarLightMode
)

/** 修改状态栏上文字图标的颜色 **/
@RequiresApi(Build.VERSION_CODES.M)
fun Activity.changeStatusBarMode(isLightMode: Boolean) = with(window.decorView) {
    systemUiVisibility = systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
    if (!isLightMode) {
        systemUiVisibility = systemUiVisibility xor View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
    }
}

====================== OLD CODE =========================

Android - 让视图文件显示到状态栏下,且不受底部导航虚拟按键影响

最新需要实现这个功能,琢磨了半天,网上也查找了一些资料,不过都是零零散散的,而且大部分是xml实现的,现在我用代码大致来实现一下这个功能。

效果图

第一步,获取状态栏高度,底部虚拟导航按键高度

/**
     * 获取状态栏高度
     *
     * @param context 上下文对象
     */
    @SuppressLint("PrivateApi")
    @JvmStatic
    fun getStatusBarHeight(context: Context): Int = try {
        val c: Class<*>? = Class.forName("com.android.internal.R\$dimen")
        val obj: Any? = c?.newInstance()
        val field: Field? = c?.getField("status_bar_height")
        if (obj != null && field != null) {
            field.isAccessible = true
            val x = Integer.parseInt(field.get(obj).toString())
            context.resources.getDimensionPixelSize(x)
        } else {
            75
        }
    } catch (e1: Exception) {
        Log.d("ApkUtil", "get status bar height fail")
        e1.printStackTrace()
        75
    }

    /**
     * 获取底部导航栏高度
     *
     * @param context
     * @return
     */
    @JvmStatic
    fun getNavigationBarHeight(context: Context): Int {
        if (!isHasNavBar(context)) return 0
        val resourceId: Int
        val rid = context.resources.getIdentifier("config_showNavigationBar", "bool", "android")
        return if (rid != 0) {
            resourceId = context.resources.getIdentifier("navigation_bar_height", "dimen", "android")
            context.resources.getDimensionPixelSize(resourceId)
        } else {
            0
        }
    }

    /**
     * 判断虚拟按键栏是否重写
     *
     * @return
     */
    private val navBarOverride: String?
        @SuppressLint("PrivateApi")
        get() {
            var sNavBarOverride: String? = null
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                try {
                    val c = Class.forName("android.os.SystemProperties")
                    val m = c.getDeclaredMethod("get", String::class.java)
                    m.isAccessible = true
                    sNavBarOverride = m.invoke(null, "qemu.hw.mainkeys") as String
                } catch (e: Throwable) {
                }

            }
            return sNavBarOverride
        }

    /**
     * 检查是否存在虚拟按键栏
     *
     * @param context
     * @return
     */
    @JvmStatic
    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    fun isHasNavBar(context: Context): Boolean {
        val res = context.resources
        val resourceId = res.getIdentifier("config_showNavigationBar", "bool", "android")
        return when {
            resourceId != 0 -> {
                var hasNav = res.getBoolean(resourceId)
                // check override flag
                val sNavBarOverride = navBarOverride
                if ("1" == sNavBarOverride) {
                    hasNav = false
                } else if ("0" == sNavBarOverride) {
                    hasNav = true
                }
                hasNav
            }
            else -> // fallback
                !ViewConfiguration.get(context).hasPermanentMenuKey()
        }
    }

第二步,处理Activity的Window的Flag属性

override fun onCreate(...){
    window.requestFeature(Window.FEATURE_NO_TITLE)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                   
  window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
                window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
                window.statusBarColor = Color.TRANSPARENT
                window.navigationBarColor = Color.BLACK
            }
}

第三步,添加视图到Activity的RootView(DecorView)中

  setContentView(
                        contentView,
                        WindowManager.LayoutParams(
                            WindowManager.LayoutParams.MATCH_PARENT,
                            WindowManager.LayoutParams.MATCH_PARENT
                        )
                    )

第四步,动态监听布局变化,动态设置导航栏高度

/** 根据导航栏高度判断页面布局 **/
    private fun setContentViewLayoutParamsByNavigationBarHeight() {
        val navigationBarHeight by lazy { ApkUtil.getNavigationBarHeight(this@PActivity) }
        val lp: FrameLayout.LayoutParams?
        if (navigationBarHolderView == null) {
            navigationBarHolderView = View(this)
            navigationBarHolderView?.setBackgroundColor(Color.BLACK)
            lp = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, navigationBarHeight)
            lp.gravity = Gravity.BOTTOM
            this@PActivity.rootView.addView(navigationBarHolderView, lp)
        } else {
            lp = navigationBarHolderView?.layoutParams as? FrameLayout.LayoutParams
            lp?.height = navigationBarHeight
            navigationBarHolderView?.layoutParams = lp
        }
        binder.root.setPadding(0, 0, 0, navigationBarHeight)
    }

    override fun onGlobalLayout() {
        if (isContentViewAttachScreenTop)
            setContentViewLayoutParamsByNavigationBarHeight()
    }

    override fun onResume() {
        if (isContentViewAttachScreenTop)
            rootView.viewTreeObserver.addOnGlobalLayoutListener(this)
        super.onResume()
    }

    override fun onStop() {
        super.onStop()
        if (isContentViewAttachScreenTop) {
            @Suppress("DEPRECATION")
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
                rootView.viewTreeObserver.removeOnGlobalLayoutListener(this)
            else
                rootView.viewTreeObserver.removeGlobalOnLayoutListener(this)
        }
    }

先写成这个样子,后面我有时间会再来修改的!经过一段时间的使用,发现以上的代码并不能很好的解决问题,于是又改进了一套,这次使用的经过了考验,感觉不错!

open class PopcornActivity<B : ViewDataBinding> : AppCompatActivity() {

    protected lateinit var ctx: Context
    protected lateinit var activity: Activity
    protected lateinit var rootView: FrameLayout
    protected lateinit var binder: B
    protected var imgBackground: ImageView? = null

    /** 状态栏的高度 **/
    protected val statusBarHeight by lazy { ApkUtil.getStatusBarHeight(this) }

    /** ActionBar的高度 **/
    protected val actionBarHeight by lazy { resources.getDimensionPixelSize(R.dimen.abc_action_bar_default_height_material) }

    /** 布局文件是否顶到屏幕的顶端,即:状态栏是透明可见的,能显示布局文件, 且@ContentView中statusBarColor参数失效。默认值为false **/
    protected open val isContentViewAttachScreenTop: Boolean = false

    /** 标识参数,方式ViewTree多次添加GlobalListener **/
    private val isSetContentViewAttachScreenTopTag: AtomicBoolean = AtomicBoolean(false)

    /** 导航栏的颜色资源ID,默认为黑色[android.R.color.black] **/
    protected var navigationBarColorResId: Int = android.R.color.black
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ctx = this; activity = this; rootView = window.decorView as FrameLayout
        if (isContentViewAttachScreenTop) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                window.statusBarColor = Color.TRANSPARENT
                rootView.systemUiVisibility =
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            }
        }
        initActivityUI() //初始化ActivityUI视图
        EventBus.getDefault().register(this) //注册Activity
    }

    /** 初始化ActivityUI视图 **/
    @SuppressLint("InlinedApi")
    private fun initActivityUI() {
        val value = ViewUtil.inflateLayoutId(this)
        when {
            value?.size == 3 -> {
                navigationBarColorResId = value[2] //获取导航栏的颜色资源ID
                binder = DataBindingUtil.setContentView(activity, value[0])
                setToolbar() //设置Toolbar的相关属性
                setImmersiveStatusBar(value[1]) //设置沉浸式状态栏
                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)
                    window.navigationBarColor =
                        ContextCompat.getColor(this, navigationBarColorResId)
            }
            else -> {
                throw Exception("错误:Cannot find layoutId & StatusBarResId")
            }
        }
    }

    /** 针对有Toolbar对象的Activity,点击Toolbar返回图标后的操作 **/
    protected open fun onNavigationBackClick() =
        Router.back(this, enterAnimRes = R.anim.slide_in_left, exitAnimRes = R.anim.slide_out_right)

    override fun onBackPressed() {
        with(javaClass.getAnnotation(BackHandler::class.java)) {
            if (this != null) {
                finish()
                overridePendingTransition(
                    when {
                        enterAnimResId < 0 || enterAnimResId == android.R.anim.slide_in_left -> R.anim.slide_in_left
                        else -> enterAnimResId
                    },
                    when {
                        exitAnimResId < 0 || exitAnimResId == android.R.anim.slide_out_right -> R.anim.slide_out_right
                        else -> exitAnimResId
                    }
                )
                return
            }
        }
        super.onBackPressed()
    }

    /** 接收到通知关闭当前的页面的事件,默认为关闭页面 **/
    @Subscribe
    open fun onReceivedActivityFinishEvent(event: ActivityFinishEvent) = finish()

    override fun onDestroy() {
        EventBus.getDefault().unregister(this)
        super.onDestroy()
    }

    /** 设置Toolbar对象 **/
    private fun setToolbar() {
        try {
            val toolbarId = ApkUtil.getIdentifierId(this, "toolbar", "id")
            when (toolbarId > 0) {
                true -> {
                    val toolbar = findViewById<Toolbar>(toolbarId)
                    toolbar?.let {
                        it.title = ""
                        setSupportActionBar(it)
                        it.setNavigationOnClickListener { onNavigationBackClick() }
                    }
                }
                else -> Log.i(javaClass.simpleName, "Toolbar is not exists!")
            }
        } catch (e: Exception) {
            e.printStackTrace()
            Log.i(
                javaClass.simpleName,
                "Something is erro, when the program execute a method called setToolbar!"
            )
        }
    }

    /**
     * 设置背景图片资源
     * @param imgUri 图片资源
     */
    protected fun setBackgroundImage(imgUri: Any): Unit = setBackgroundImage(imgUri, null)

    /**
     * 设置背景图片资源
     * @param imgUri          图片资源
     * @param onClickListener 点击事件
     */
    protected fun setBackgroundImage(imgUri: Any, onClickListener: View.OnClickListener?) {
        if (imgBackground == null) {
            imgBackground = ImageView(this)
            rootView.addView(
                imgBackground, 0,
                FrameLayout.LayoutParams(
                    FrameLayout.LayoutParams.MATCH_PARENT,
                    FrameLayout.LayoutParams.MATCH_PARENT
                )
            )
        }
        when (imgUri) {
            is Drawable -> imgBackground?.setImageDrawable(imgUri)
            is Int -> imgBackground?.setImageResource(imgUri)
            is File -> {
                imgBackground?.setImageURI(
                    when {
                        Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> FileProvider.getUriForFile(
                            this,
                            "$packageName.FileProvider",
                            imgUri
                        )
                        else -> Uri.fromFile(imgUri)
                    }
                )
            }
            is Bitmap -> imgBackground?.setImageBitmap(imgUri)
            is String -> ImageLoader.displayImage(this, uri = imgUri, target = imgBackground!!)
        }
        imgBackground?.scaleType = ImageView.ScaleType.CENTER_CROP
        if (onClickListener != null)
            imgBackground?.setOnClickListener(onClickListener)
        }
    }

       /**謤
     * 设置沉浸式状态栏
     * @param colorResId 状态栏颜色
     */
    @SuppressLint("ObsoleteSdkInt")
    protected fun setImmersiveStatusBar(colorResId: Int) {
        when {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {
                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
                val statusBarColor = ApkUtil.getColor(this, colorResId)
                window.statusBarColor = statusBarColor //设置状态栏颜色
                if (statusBarColor == Color.WHITE || statusBarColor == Color.TRANSPARENT) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) rootView.systemUiVisibility =
                        rootView.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
                    else window.setFlags(
                        WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                        WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    )
                }
     }

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

推荐阅读更多精彩内容