Android使用MvvM+kotlin實現(xiàn)簡單WanAndroid

? 最近在學(xué)習(xí)mvvm,利用空閑時間寫了一個簡單版的wanAndroid項目.介紹就不說了欲虚,直接上代碼.

? 1.引入:在App——build.gradle目錄引入以下代碼即可:

dataBinding{

? ? enabled true

}

?

2.配置gradle.properties

android.useAndroidX=true

android.enableJetifier=true

3.WanAndroid項目主要有首頁、知識幢竹、導(dǎo)航莫换、項目四個模塊,采用MvvM+Kotlin方式

主MainActivity代碼如下:

/**

* @作者: njb

* @時間: 2020/1/13 12:51

* @描述: 主界面

*/

open class MainActivity : BaseActivity() {

? ? private val fragmentList: MutableList<Fragment> =

? ? ? ? ArrayList()

? ? private val strings =

? ? ? ? arrayOf("首頁", "知識", "導(dǎo)航", "項目")

? ? override val layoutId: Int

? ? ? ? get() = R.layout.activity_main

? ? override fun initView() {

? ? ? ? fragmentList.add(HomeFragment())

? ? ? ? fragmentList.add(KnowledgeFragment())

? ? ? ? fragmentList.add(NavigationFragment())

? ? ? ? fragmentList.add(ProjectFragment())

? ? ? ? viewPager!!.adapter = object : FragmentStateAdapter(this) {

? ? ? ? ? ? override fun createFragment(position: Int): Fragment {

? ? ? ? ? ? ? ? return fragmentList[position]

? ? ? ? ? ? }

? ? ? ? ? ? override fun getItemCount(): Int {

? ? ? ? ? ? ? ? return fragmentList.size

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? viewPager.offscreenPageLimit = 3

? ? ? ? val tabLayoutMediator = TabLayoutMediator(

? ? ? ? ? ? tab_layout,

? ? ? ? ? ? viewPager,

? ? ? ? ? ? TabConfigurationStrategy { tab: TabLayout.Tab, position: Int ->

? ? ? ? ? ? ? ? tab.text = strings[position]

? ? ? ? ? ? }

? ? ? ? )

? ? ? ? tabLayoutMediator.attach()

? ? ? ? initToolBar()

? ? }

? ? private fun initToolBar() {

? ? ? ? setSupportActionBar(toolbar)

? ? ? ? supportActionBar!!.setDisplayHomeAsUpEnabled(false)

? ? ? ? supportActionBar!!.setHomeButtonEnabled(false)

? ? ? ? iv_search.setImageResource(R.drawable.ic_baseline_search_24)

? ? }

? ? override fun addListener() {

? ? ? ? iv_search.setOnClickListener(View.OnClickListener {

? ? ? ? ? ? startActivity(

? ? ? ? ? ? ? ? Intent(

? ? ? ? ? ? ? ? ? ? this@MainActivity,

? ? ? ? ? ? ? ? ? ? SearchActivity::class.java

? ? ? ? ? ? ? ? )

? ? ? ? ? ? )

? ? ? ? })

? ? }

}

4.首頁Fragment代碼:

/**

* @作者: njb

* @時間: 2020/1/10 18:19

* @描述: 首頁

*/

class HomeFragment : Fragment(), CompletedListener {

? ? private var mBinding: ViewDataBinding? = null

? ? private var artListAdapter: ArtListAdapter? = null

? ? private var viewModel: HomeViewModel? = null

? ? private var layoutManager: LinearLayoutManager? = null

? ? private var page: Int = 1

? ? private var viewHead: View? = null

? ? private var banner: Banner? = null

? ? private var bannerModel: List<BannerModel>? = null

? ? private var viewModels:BannerViewModel ? = null

? ? override fun onCreateView(

? ? ? ? inflater: LayoutInflater,

? ? ? ? container: ViewGroup?,

? ? ? ? savedInstanceState: Bundle?

? ? ): View? {

? ? ? ? mBinding = DataBindingUtil.inflate(inflater, R.layout.fm_home, container, false)

? ? ? ? val view = mBinding!!.root

? ? ? ? viewHead = LayoutInflater.from(context).inflate(R.layout.item_home_banner, null)

? ? ? ? initBanner()

? ? ? ? initView(view)

? ? ? ? initListener(view)

? ? ? ? return mBinding!!.root

? ? }

? ? /**

? ? * 初始化view

? ? */

? ? private fun initView(view: View) {

? ? ? ? artListAdapter = ArtListAdapter(null)

? ? ? ? layoutManager = LinearLayoutManager(activity!!)

? ? ? ? layoutManager!!.orientation = LinearLayoutManager.VERTICAL

? ? ? ? view.rv_home.layoutManager = layoutManager

? ? ? ? artListAdapter!!.addHeaderView(viewHead)

? ? ? ? view.rv_home.addItemDecoration(DividerDecoration(ContextCompat.getColor(activity!!,R.color.ce7e7e7),2))

? ? ? ? view.rv_home.adapter = artListAdapter

? ? ? ? viewModel = HomeViewModel(artListAdapter!!, this)

? ? ? ? //顯示加載動畫

? ? ? ? viewModel!!.getArtCircleList(page)

? ? }

? ? private fun initBanner() {

? ? ? ? banner = viewHead!!.findViewById(R.id.home_banner)

? ? ? ? //設(shè)置banner樣式

? ? ? ? banner!!.setBannerStyle(BannerConfig.CIRCLE_INDICATOR)

? ? ? ? //設(shè)置圖片加載器

? ? ? ? banner!!.setImageLoader(GlideImageLoader())

? ? ? ? //設(shè)置banner動畫效果

? ? ? ? banner!!.setBannerAnimation(Transformer.Default)

? ? ? ? //設(shè)置自動輪播响蕴,默認(rèn)為true

? ? ? ? banner!!.isAutoPlay(true)

? ? ? ? //設(shè)置輪播時間

? ? ? ? banner!!.setDelayTime(3000)

? ? ? ? //設(shè)置指示器位置(當(dāng)banner模式中有指示器時)

? ? ? ? banner!!.setIndicatorGravity(BannerConfig.CENTER)

? ? ? ? //banner設(shè)置方法全部調(diào)用完畢時最后調(diào)用

? ? ? ? banner!!.start()

? ? ? ? viewModels = BannerViewModel(banner!!,this)

? ? ? ? viewModels!!.getBannerList()

? ? }

? ? /**

? ? * 初始化事件

? ? */

? ? private fun initListener(view: View) {

? ? ? ? artListAdapter!!.setOnItemClickListener{

? ? ? ? ? ? listener,View,position ->

? ? ? ? ? ? Intent(context, WebViewActivity::class.java).run {

? ? ? ? ? ? ? ? putExtra(AppConstant.WEBVIEW_TITLE_KEY, artListAdapter!!.data[position].title)

? ? ? ? ? ? ? ? putExtra(AppConstant.WEBVIEW_ID_KEY, artListAdapter!!.data[position].id)

? ? ? ? ? ? ? ? putExtra(AppConstant.WEBVIEW_URL_KEY, artListAdapter!!.data[position].link)

? ? ? ? ? ? ? ? startActivity(this, null)

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? view.rf_home.setOnRefreshListener {

? ? ? ? ? ? page = 1

? ? ? ? ? ? viewModel!!.getArtCircleList(page)

? ? ? ? ? ? view.rf_home.finishRefresh(200)

? ? ? ? }

? ? ? ? view.rf_home.setOnLoadMoreListener {

? ? ? ? ? ? page++

? ? ? ? ? ? viewModel!!.getArtCircleList(page)

? ? ? ? ? ? view.rf_home.finishLoadMore(200)

? ? ? ? }

? ? }

? ? override fun onCompleted() {

? ? }

}

HomeViewModel

/**

*@作者: njb

*@時間: 2020/1/10 17:55

*@描述:

*/

class HomeViewModel(

? ? private val adapter: ArtListAdapter,

? ? private val completedListener: CompletedListener

) {

? ? private var observer: Observer<BaseModel<ArticleListModel>>? = null

? ? private var repository = HomeRepository()

? ? fun getArtCircleList(page:Int) {

? ? ? ? observer = object : Observer<BaseModel<ArticleListModel>> {

? ? ? ? ? ? override fun onComplete() {

? ? ? ? ? ? ? ? completedListener.onCompleted()

? ? ? ? ? ? }

? ? ? ? ? ? override fun onSubscribe(d: Disposable) {

? ? ? ? ? ? }

? ? ? ? ? ? override fun onNext(t: BaseModel<ArticleListModel>) {

? ? ? ? ? ? ? ? if (t.errorCode == 0) {

? ? ? ? ? ? ? ? ? ? t.data?.let {

? ? ? ? ? ? ? ? ? ? ? ? if(page == 1){

? ? ? ? ? ? ? ? ? ? ? ? ? ? adapter.setNewData(it.datas)

? ? ? ? ? ? ? ? ? ? ? ? }else{

? ? ? ? ? ? ? ? ? ? ? ? ? ? adapter.addData(it.datas!!)

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? override fun onError(e: Throwable) {

? ? ? ? ? ? ? ? completedListener.onCompleted()

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? repository.getArcticList(page,

? ? ? ? ? ? observer as Observer<BaseModel<ArticleListModel>>

? ? ? ? )

? ? }

}

首頁請求HomeRespository

/**

*@作者: njb

*@時間: 2020/1/10 18:00

*@描述:

*/

class HomeRepository :BaseRepository(){

? ? fun getArcticList(

? ? ? ? page: Int,

? ? ? ? observer: Observer<BaseModel<ArticleListModel>>) {

? ? ? ? apiServer.articleList(page).subscribeOn(Schedulers.io())

? ? ? ? ? ? .observeOn(AndroidSchedulers.mainThread())

? ? ? ? ? ? .subscribe(observer)

? ? }

}

首頁文章列表適配器

/**

*@author: njb

*@date:? 2020/2/11 0011 16:47

*@desc:? 文章列表適配器

*/

class ArtListAdapter (data:List<ArticleListModel.DatasBean>?):

? ? BaseQuickAdapter<ArticleListModel.DatasBean,BaseViewHolder>(R.layout.item_home,data){

? ? override fun convert(helper: BaseViewHolder, item: ArticleListModel.DatasBean) {

? ? ? ? val itemBinding = DataBindingUtil.bind<ItemHomeBinding>(helper.itemView)!!

? ? ? ? itemBinding.homebean = item

? ? ? ? itemBinding.executePendingBindings()

? ? }

}

首頁布局:

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

<layout xmlns:android="http://schemas.android.com/apk/res/android">

? ? <LinearLayout

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="match_parent"

? ? ? ? android:orientation="vertical">

? ? ? ? <com.ning.mvvmplayandroid.weight.MyRefreshLayout

? ? ? ? ? ? android:id="@+id/rf_home"

? ? ? ? ? ? android:layout_width="match_parent"

? ? ? ? ? ? android:layout_height="match_parent">

? ? ? ? ? ? <androidx.recyclerview.widget.RecyclerView

? ? ? ? ? ? ? ? android:id="@+id/rv_home"

? ? ? ? ? ? ? ? android:layout_width="match_parent"

? ? ? ? ? ? ? ? android:layout_height="match_parent" />

? ? ? ? </com.ning.mvvmplayandroid.weight.MyRefreshLayout>

? ? </LinearLayout>

</layout>

首頁Banner布局加在文章列表頭部谆焊,Banner廣告布局:

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

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"

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

? ? android:layout_width="match_parent"

? ? android:layout_height="match_parent">

? ? <com.youth.banner.Banner

? ? ? ? android:id="@+id/home_banner"

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="200dp"

? ? ? ? app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

首頁文章列表item布局:

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

<layout xmlns:tools="http://schemas.android.com/tools"

? ? xmlns:android="http://schemas.android.com/apk/res/android"

? ? xmlns:app="http://schemas.android.com/apk/res-auto">

? ? <data>

? ? ? ? <variable

? ? ? ? ? ? name="homebean"

? ? ? ? ? ? type="fule.com.playandroidkotlin.ui.model.ArticleListModel.DatasBean" />

? ? </data>

? ? <androidx.constraintlayout.widget.ConstraintLayout

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:padding="10dp"

? ? ? ? tools:ignore="MissingConstraints">

? ? ? ? <TextView

? ? ? ? ? ? android:id="@+id/tv_username"

? ? ? ? ? ? android:layout_width="wrap_content"

? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? app:layout_constraintLeft_toLeftOf="parent"

? ? ? ? ? ? android:layout_marginRight="20dp"

? ? ? ? ? ? android:text="@{homebean.author}"

? ? ? ? ? ? android:textColor="@color/colorPrimary"

? ? ? ? ? ? android:textSize="12sp" />

? ? ? ? <TextView

? ? ? ? ? ? android:id="@+id/tv_time"

? ? ? ? ? ? android:layout_width="wrap_content"

? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? app:layout_constraintEnd_toEndOf="parent"

? ? ? ? ? ? android:text="@{String.valueOf(homebean.niceDate)}"

? ? ? ? ? ? android:textColor="@color/colorPrimary"

? ? ? ? ? ? android:textSize="12sp" />

? ? ? ? <androidx.cardview.widget.CardView

? ? ? ? ? ? android:id="@+id/cv_content"

? ? ? ? ? ? android:layout_width="100dp"

? ? ? ? ? ? android:layout_height="80dp"

? ? ? ? ? ? app:layout_constraintTop_toBottomOf="@+id/tv_username"

? ? ? ? ? ? android:layout_marginTop="10dp"

? ? ? ? ? ? android:elevation="0dp"

? ? ? ? ? ? app:cardCornerRadius="4dp"

? ? ? ? ? ? app:cardElevation="0dp">

? ? ? ? ? ? <ImageView

? ? ? ? ? ? ? ? android:id="@+id/iv_content"

? ? ? ? ? ? ? ? android:layout_width="100dp"

? ? ? ? ? ? ? ? android:layout_height="80dp"

? ? ? ? ? ? ? ? android:scaleType="centerCrop"

? ? ? ? ? ? ? ? app:home_image="@{homebean.envelopePic}"/>

? ? ? ? </androidx.cardview.widget.CardView>

? ? ? ? <TextView

? ? ? ? ? ? android:id="@+id/tv_content"

? ? ? ? ? ? android:layout_width="0dp"

? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? android:layout_marginStart="12dp"

? ? ? ? ? ? android:layout_marginTop="10dp"

? ? ? ? ? ? android:ellipsize="end"

? ? ? ? ? ? android:gravity="top|start"

? ? ? ? ? ? android:lineSpacingExtra="2dp"

? ? ? ? ? ? android:maxLines="2"

? ? ? ? ? ? android:text="@{homebean.title}"

? ? ? ? ? ? android:textColor="@color/black"

? ? ? ? ? ? android:textSize="14sp"

? ? ? ? ? ? app:layout_constraintLeft_toRightOf="@+id/cv_content"

? ? ? ? ? ? app:layout_constraintRight_toRightOf="parent"

? ? ? ? ? ? app:layout_constraintTop_toBottomOf="@+id/tv_username" />

? ? ? ? <TextView

? ? ? ? ? ? android:id="@+id/tv_type"

? ? ? ? ? ? android:layout_width="wrap_content"

? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? android:layout_marginStart="10dp"

? ? ? ? ? ? android:layout_marginTop="10dp"

? ? ? ? ? ? android:layout_toRightOf="@+id/cv_content"

? ? ? ? ? ? android:gravity="center"

? ? ? ? ? ? android:padding="4dp"

? ? ? ? ? ? android:text="@{homebean.chapterName}"

? ? ? ? ? ? android:background="@drawable/shape_article_type_bg"

? ? ? ? ? ? android:textColor="@color/white"

? ? ? ? ? ? android:textSize="12sp"

? ? ? ? ? ? app:layout_constraintLeft_toRightOf="@+id/cv_content"

? ? ? ? ? ? app:layout_constraintTop_toBottomOf="@+id/tv_content" />

? ? ? ? <ImageView

? ? ? ? ? ? android:layout_width="wrap_content"

? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? app:layout_constraintTop_toBottomOf="@+id/tv_content"

? ? ? ? ? ? app:layout_constraintEnd_toEndOf="parent"

? ? ? ? ? ? android:layout_marginTop="10dp"

? ? ? ? ? ? app:srcCompat="@drawable/ic_favorite_black_24dp" />

? ? </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

?從下圖可以看到數(shù)據(jù)是和視圖綁定到一起的,數(shù)據(jù)發(fā)生變化浦夷,視圖也會改變.其他三個模塊的代碼都是和首頁一樣辖试,創(chuàng)建view,綁定視圖劈狐,請求數(shù)據(jù)罐孝,數(shù)據(jù)請求成功后直接顯示.這里就不寫重復(fù)贅述了。

?

5.遇到的問題:

(1)databinding綁定圖片和一般的用法不一樣肥缔,一般的直接設(shè)置背景圖片就可以莲兢,拿到數(shù)據(jù)后直接用glide顯示,這里是和視圖綁定的,所以我們得新建一個圖片顯示的工具類本文暫定ImageUtil,方法必須和布局中的名稱一致续膳,否則會報錯.

我們在ImageUitl中新建一個顯示首頁文章列表圖片的方法:

?

??????

@BindingAdapter("image_view")

public static void setImageView(ImageView imageView, String urlString) {

? ? Glide.with(imageView.getContext()).load(urlString).into(imageView);

}


?

(2)當(dāng)實體類有一個list我們好處理改艇,但是如果又嵌套一個的話比較麻煩,本博主也是參考網(wǎng)上的方法坟岔,找了很多資料才找到這個辦法谒兄,剛開始一直獲取到的第一個數(shù)據(jù).

我們這里就以知識模塊為例.返回的數(shù)據(jù)是一個知識體系列表,然后這個體系列表里面又有一個體系文章標(biāo)題列表

?<data>

? ? <variable

? ? ? ? name="knowledge"

? ? ? ? type="fule.com.playandroidkotlin.ui.model.KnowledgeModel.DataBean" />

? ? <!導(dǎo)入一個list!>

? ? <import type="java.util.List" />

? ? <variable

? ? ? ? name="knowList"

? ? ? ? type="List&lt;fule.com.playandroidkotlin.ui.model.ChildrenModel>" />

? ? <!表示list的位置!>

? ? <variable

? ? ? ? name="index"

? ? ? ? type="int" />

</data>

下圖中一個表示知識體系列表社付,一個表示體系列表下的欄目列表?

?

(3)剛開始在fragment布局中l(wèi)ayout設(shè)置了寬和高會一直報錯

圖(1)是錯誤的寫法承疲,會一直報錯,這是我作為一個初學(xué)者啥也不懂踩的坑

?

圖(2)才是正確的寫法

?

6.實現(xiàn)的效果圖如下:

?

7.最后鸥咖,項目的完整源碼地址:https://gitee.com/jackning_admin/MvvmPlayAndroid

當(dāng)然纪隙,這個小demo還有很多問題需要處理,比如登錄注冊功能扛或,點贊收藏等等绵咱,后面有時間會慢慢補(bǔ)上,歡迎各位大佬前來討論,指出小弟的問題悲伶,如有問題艾恼,及時提示,我會及時改正.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末麸锉,一起剝皮案震驚了整個濱河市钠绍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌花沉,老刑警劉巖柳爽,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異碱屁,居然都是意外死亡磷脯,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門娩脾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赵誓,“玉大人,你說我怎么就攤上這事柿赊×┕Γ” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵碰声,是天一觀的道長诡蜓。 經(jīng)常有香客問我,道長胰挑,這世上最難降的妖魔是什么蔓罚? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮洽腺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘覆旱。我一直安慰自己蘸朋,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布扣唱。 她就那樣靜靜地躺著藕坯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪噪沙。 梳的紋絲不亂的頭發(fā)上炼彪,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機(jī)與錄音正歼,去河邊找鬼辐马。 笑死,一個胖子當(dāng)著我的面吹牛局义,可吹牛的內(nèi)容都是我干的喜爷。 我是一名探鬼主播冗疮,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼檩帐!你這毒婦竟也來了术幔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤湃密,失蹤者是張志新(化名)和其女友劉穎诅挑,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體泛源,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拔妥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了俩由。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片毒嫡。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖幻梯,靈堂內(nèi)的尸體忽然破棺而出兜畸,到底是詐尸還是另有隱情,我是刑警寧澤碘梢,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布咬摇,位于F島的核電站,受9級特大地震影響煞躬,放射性物質(zhì)發(fā)生泄漏肛鹏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一恩沛、第九天 我趴在偏房一處隱蔽的房頂上張望在扰。 院中可真熱鬧,春花似錦雷客、人聲如沸芒珠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽皱卓。三九已至,卻和暖如春部逮,著一層夾襖步出監(jiān)牢的瞬間娜汁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工兄朋, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留掐禁,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像穆桂,于是被迫代替她去往敵國和親宫盔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344