Android(Kotlin版本)MVC框架的实例以及代码
本文地址:https://blog.csdn.net/qq_40785165/article/details/112135944,转载需附上此地址
代码也许是枯燥的,但是创造永远能让人心血澎湃,这大概就是热情吧!
大家好,我是小黑,一个还没秃头的程序员~~~
近日较忙,但是也不能忘记了写文章的初心,就是为了记录自己一段时间内的学习以及改变,今日内容为Android开发中MVC的框架设计,由于最近在学习kotlin,所以本文章将使用kotlin作为开发语言,先来看看效果图
Demo中的功能很简单,就是个模拟登录的过程,以及登录成功后调用数据接口开发列表,由于想把MVC架构与数据请求一起写了,又想节约篇幅,所以登录模块的代码就不贴出来了,这里只展示列表的设计代码,想要其他代码的同学可以到Demo的github地址手动下载,话不多说,下面开始正文。
MVC框架由一下三个部分组成:Model|(模型层)、View(视图层)、Controller(控制层)
1.Model:负责请求接口,进行数据处理,将结果通过回调告知Controller层并进行视图更新。
2.View:视图设计,在这里一般指layout中的xml视图代码
3.Controller:控制层,通常指Activity/Fragment,持有Model对象,通过监听Model状态改变进行UI的更新
项目结构如图所示:
(一)先设计视图xml文件即View层,activity_wechat_official_account.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">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
列表子项item_office_account.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="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="40dp" />
</LinearLayout>
(二)、设计Activity代码,即Controller层,WeChatOfficialAccountListActivity.kt代码如下:
class WeChatOfficialAccountListActivity : AppCompatActivity(), WeChatOfficeAccountListener {
private val mList: MutableList<OfficeAccountBean> = ArrayList()
private val weChatOfficeAccountModel by lazy {
WeChatOfficeAccountModel()
}
private val weChatOfficialAccountAdapter by lazy {
WeChatOfficialAccountAdapter(this, mList)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_wechat_official_account)
rv_list.layoutManager = LinearLayoutManager(this)
rv_list.adapter = weChatOfficialAccountAdapter
weChatOfficeAccountModel.loadData(this)
}
override fun onLoading() {
Toast.makeText(this, "正在加载中", Toast.LENGTH_SHORT).show()
}
override fun onLoadSuccess(list: MutableList<OfficeAccountBean>?) {
runOnUiThread(Thread {
Toast.makeText(this, "加载成功", Toast.LENGTH_SHORT).show()
if (list != null && list.size > 0) {
mList.addAll(list)
}
weChatOfficialAccountAdapter.notifyDataSetChanged()
})
}
override fun onLoadFail(msg: String?) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
}
}
从代码中可以得知,Controller层持有了一个Model对象,并实现了一个接口,实现了其中的回调,通过回调进行主线程的UI更新,列表的子项适配器WeChatOfficialAccountAdapter.kt代码如下:
class WeChatOfficialAccountAdapter(var context: Context, var list: MutableList<OfficeAccountBean>) :
RecyclerView.Adapter<WeChatOfficialAccountAdapter.ViewHolder>() {
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
var tvName: TextView = view.findViewById(R.id.tv_name)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_office_account,
null,
false
)
)
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.tvName.text = list[position].name
}
}
回调的接口WeChatOfficeAccountListener.kt代码如下:
interface WeChatOfficeAccountListener {
fun onLoading()
fun onLoadSuccess(list: MutableList<OfficeAccountBean>? = null)
fun onLoadFail(msg: String? = "")
}
(三)、设计Model层,实现数据处理,调用接口等操作,并通过回调通知控制层更新UI,WeChatOfficeAccountModel.kt代码如下:
class WeChatOfficeAccountModel {
private val weChatOfficeAccountApi by lazy {
WeChatOfficeAccountApi()
}
fun loadData(callback: WeChatOfficeAccountListener) {
weChatOfficeAccountApi.loadData(callback)
}
}
我的Model层里并没有接口调用、数据处理等操作,那是因为我把调用接口都放到了WeChatOfficeAccountApi.kt文件中,代码如下:
class WeChatOfficeAccountApi {
private val gson by lazy {
GsonBuilder().serializeNulls().create()
}
fun loadData(callback: WeChatOfficeAccountListener) {
callback.onLoading()
//拿到OkhttpClient对象
var okHttpClient = OkHttpClient()
//构造request对象,get方式,传入接口地址
var url = Request.Builder()
.get()
.url("https://wanandroid.com/wxarticle/chapters/json")
.build()
var newCall = okHttpClient.newCall(url)
newCall.enqueue(object : Callback {
override fun onFailure(call: Call?, e: IOException?) {
callback.onLoadFail()
}
override fun onResponse(call: Call?, response: Response?) {
var string = response?.body()?.string()
Log.e("Tag", string)
var result = gson.fromJson<DataResult<MutableList<OfficeAccountBean>>>(
string,
object : TypeToken<DataResult<MutableList<OfficeAccountBean>>>() {}.type
)
Log.e("Tag", result.toString())
callback.onLoadSuccess(result.data)
}
})
}
}
上述代码中,如果不喜欢这种写法的也可以直接在Model中调用接口,因人而异,调用的接口是玩Android的开放接口,使用的是okhttp网络请求框架,使用gson解析数据,需要依赖的库有:
implementation 'com.squareup.okhttp3:okhttp:3.5.0'
implementation 'com.google.code.gson:gson:2.8.6'
需要的权限有:
<uses-permission android:name="android.permission.INTERNET" />
好了,到此为止Android的MVC框架就搭建好了,这是我个人对MVC的了解和实践,有不同意见或者建议的可以在下方评论,我们共同进步,效果图和源代码都在开头!最后,祝大家新年快乐,岁岁欢愉!
来源:oschina
链接:https://my.oschina.net/u/4363105/blog/4883068