协程,构建,一个MVVM的frame #
先是构建器
object ServiceCreator {
private const val BASE_URL="http://124.93.196.45:10001"
private val retrofot: Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
fun <T> create(serviceClass:Class<T>): T= retrofot.create(serviceClass)
inline fun <reified T>create():T= create(T::class.java)
}
然后是接口
interface NewsService {
@GET("/prod-api/press/category/list")
fun getNewsType(): Call<NewsType>
@GET("/prod-api/press/press/list")
fun getNewsList(@Query("id") id:String,@Query("hot") hot:String):Call<NewsList>
}
写一个Network
object SmartCityNetwork {
private val userService= ServiceCreator.create<UserService>()
suspend fun login(data: LoginData) = userService.loginService(data).await()
private val AdvService=ServiceCreator.create<MetroService>()
suspend fun getAdv()=AdvService.getAdv().await()
private val newsService=ServiceCreator.create<NewsService>()
suspend fun getNewsType()=newsService.getNewsType().await()
suspend fun getNewsList(id :String,hot:String)= newsService.getNewsList(id,hot).await()
private suspend fun <T> Call<T>.await(): T {
return suspendCoroutine {
enqueue(object : Callback<T> {
override fun onResponse(call: Call<T>, response: Response<T>) {
val body = response.body()
if (body != null) it.resume(body)
else it.resumeWithException(RuntimeException("response body is null"))
}
override fun onFailure(call: Call<T>, t: Throwable) {
it.resumeWithException(t)
}
}) }
}
}
处理返回数据,其实可以分开写不同的接口
object Repository {
fun login(data:LoginData) = fire(Dispatchers.IO) {
val loginResponse =SmartCityNetwork.login(data)
if (loginResponse.code == 200) {
val token = loginResponse.token
Result.success(token)
} else {
// Result.success(loginResponse.msg)
Result.failure(RuntimeException("response status is${loginResponse.msg}"))
}
}
fun getAdv()= fire(Dispatchers.IO){
val loginResponse =SmartCityNetwork.getAdv()
if (loginResponse.code == 200) {
val rows = loginResponse.rows
Result.success(rows)
} else {
Result.failure(RuntimeException("response status is${loginResponse.msg}"))
}
}
fun getNewsType()= fire(Dispatchers.IO){
val type=SmartCityNetwork.getNewsType()
if(type.code==200){
val rows=type.rows
Result.success(rows)
}else{
Result.failure(RuntimeException("response status is${type.msg}"))
}
}
fun getNewsList(id:String,hot:String)= fire(Dispatchers.IO){
val resp=SmartCityNetwork.getNewsList(id,hot)
if(resp.code==200){
var rows=resp.rows
//限定20个
if(resp.rows.size>20){
rows=resp.rows.subList(0,20)
}
Result.success(rows)
}else{
Result.failure(RuntimeException("response status is${resp.msg}"))
}
}
private fun <T> fire(context: CoroutineContext, block: suspend () -> Result<T>) =
liveData<Result<T>>(context) {
val result = try {
block()
} catch (e: Exception) {
Result.failure<T>(e)
}
emit(result)
}
}
viewModel
class HomeViewModel : ViewModel() {
private val imgFlag = MutableLiveData<String>()
private val newsListData= MutableLiveData<String>()
private var newsTypeFlag=MutableLiveData<String>()
val adv=imgFlag.switchMap { Repository.getAdv() }
val newsType=imgFlag.switchMap { Repository.getNewsType()}
val newsList=newsListData.switchMap { Repository.getNewsList(it,"true") }
//这里没有参数,给一个go,让switchMap观察到
fun getAdv(){
this.imgFlag.value="go"
}
fun getNewsType(){
this.newsTypeFlag.value="go"
}
fun getNewsList(id:String){
this.newsListData.value= id
}
}
view层
val homeViewModel =
ViewModelProvider(this)[HomeViewModel::class.java]
_binding = FragmentHomeBinding.inflate(inflater, container, false)
val root: View = binding.root
//加载轮播图
homeViewModel.getAdv()
val banner = binding.banner
homeViewModel.adv.observe(this) {
val resp = it.getOrNull()
var imgs = mutableListOf<DataBean>()
val baseUrl = "http://124.93.196.45:10001"
if (resp != null) {
for (i in resp) {
Log.d("img", i.advImg)
imgs.add(DataBean(baseUrl + i.advImg))
}
banner.setAdapter(object :
BannerImageAdapter<DataBean>(imgs) {
override fun onBindView(
holder: BannerImageHolder,
data: DataBean,
position: Int,
size: Int
) {
//图片加载自己实现
Glide.with(holder.itemView)
.load(data.imageUrl)
.apply(RequestOptions.bitmapTransform(RoundedCorners(30)))
.into(holder.imageView)
}
}).addBannerLifecycleObserver(this).indicator = CircleIndicator(context)
banner.setOnBannerListener { any, i ->
when (i) {
0 -> Toast.makeText(myContext, (1).toString(), Toast.LENGTH_SHORT).show()
1 -> Toast.makeText(myContext, (i + 1).toString(), Toast.LENGTH_SHORT)
.show()
else -> Toast.makeText(myContext, "yiya~", Toast.LENGTH_SHORT).show()
}
}
}
}
只能临时抱佛脚了
饼图
class MyPieChart : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my_pie_chart)
// 创建数据集合
val entries = ArrayList<PieEntry>()
entries.add(PieEntry(3f, "苹果"))
entries.add(PieEntry(4f, "香蕉"))
entries.add(PieEntry(2f, "橙子"))
entries.add(PieEntry(1f, "葡萄"))
// 创建数据集
val dataSet = PieDataSet(entries, "水果分布")
dataSet.colors = ColorTemplate.COLORFUL_COLORS.toMutableList()
dataSet.setDrawIcons(false)
// dataSet.isus
// 创建数据对象
val pieData = PieData(dataSet)
// 设置图表数据
pie_chart.data = pieData
// 设置图表属性
pie_chart.invalidate() // 刷新图表
}
}