<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_garden"/>
FrameLayout>
layout>
class MainActivity2 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView<ActivityMain2Binding>(this, R.layout.activity_main2)
}
}
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
app:startDestination="@id/view_pager_fragment">
<fragment
android:id="@+id/view_pager_fragment"
android:name="com.gctech.androidstudydemo.jetpack.HomeViewPagerFragment"
tools:layout="@layout/fragment_view_pager">
<action
android:id="@+id/action_view_pager_fragment_to_plant_detail_fragment"
app:destination="@id/plant_detail_fragment"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
fragment>
<fragment
android:id="@+id/plant_detail_fragment"
android:name="com.gctech.androidstudydemo.jetpack.EmptyFragment"
android:label="详情标题">
<argument
android:name="id"
app:argType="string" />
fragment>
navigation>
startDestination
destination
action
通过id指向目标
传参数 argument name
获取参数 如果传入的有参数就会生成对应的Args 然后获取到
private val args: EmptyFragmentArgs by navArgs()
nav_garden->startDestination->id->name
action->destination->id->name
包含 LiveData和ObservableField 和其他数据
观察者模式->订阅数据的变化
数据和view双向绑定
ViewModelProvider.Factory
AbstractSavedStateViewModelFactory(@NonNull SavedStateRegistryOwner owner, @Nullable Bundle defaultArgs)
页面用viewmodel item用实体类
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="hasPlantings"
type="boolean" />
<import type="android.view.View"/>
<variable
name="vm"
type="com.gctech.androidstudydemo.jetpack.viewmodels.EmptyDataViewModel" />
data>
<FrameLayout
android:id="@+id/fl_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{vm.datas.title}"
android:visibility="@{vm.datas.isGone() ? View.VISIBLE : View.INVISIBLE}" />
FrameLayout>
layout>
class EmptyFragment : Fragment() {
private val args: EmptyFragmentArgs by navArgs()
private lateinit var binding: FragmentEmptyBinding
private val viewModel: EmptyDataViewModel by viewModels {
InjectorUtils.provideCommonViewModelFactory("")
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentEmptyBinding.inflate(inflater, container, false)
binding.tvContent.setOnClickListener {
ToastUtils.showShort("========")
viewModel.datas.get()?.title ="6666"
viewModel.datas.notifyChange()
}
viewModel.datas.set(A("1", true, "434"))
binding.vm = viewModel
binding.lifecycleOwner = viewLifecycleOwner
binding.hasPlantings = true
return binding.root
}
}
interface ApiService {
/**
* 1.测试第一个接口
*/
@GET("xxx/testOne")
suspend fun testOne(): HttpResult<List<Country>>
/**
* 1.测试第二 个接口
*/
@GET("xxx/testTwo")
suspend fun testTwo(@Query("list") countries: Int): HttpResult<List<Country>>
/**
* 1.测试分页接口
*/
@GET("xxx/testPage")
fun testPage(@Query("page") page: Int, @Query("pageSize") pageSize: Int= 20): Call<HttpResult<Tx>>
}
class EmptyDataViewModel(
private val params: Any?
) : ViewModel() {
val datas = ObservableField<A>()
val firstName = ObservableField<String>()
val lastName = ObservableField<String>()
val isShowDialog = MutableLiveData<Boolean>()
val allName = object : ObservableField<String>(firstName, lastName) {
override fun get(): String? {
return "${firstName.get()} ${lastName.get()}"
}
}
//调用一个接口
fun country() = liveData(Dispatchers.IO) {
isShowDialog.postValue(true)
try {
emit(
Api.createService(ApiService::class.java)
.testOne()
)
isShowDialog.postValue(false)
} catch (e: Exception) {
isShowDialog.postValue(false)
}
}
//顺序调用接口
fun country2() = liveData(Dispatchers.IO) {
isShowDialog.postValue(true)
val d = Api.createService(ApiService::class.java)
.testOne()
val d2 = Api.createService(ApiService::class.java)
.testTwo(d.data!!.size)
try {
emit(d2)
isShowDialog.postValue(false)
} catch (e: Exception) {
isShowDialog.postValue(false)
}
}
//合并多个接口
fun country3() = liveData(Dispatchers.IO) {
isShowDialog.postValue(true)
val d = Api.createService(ApiService::class.java)
.testOne()
val d2 = Api.createService(ApiService::class.java)
.testTwo(3)
try {
emit(Triple(d, d2, null))
isShowDialog.postValue(false)
} catch (e: Exception) {
isShowDialog.postValue(false)
}
}
val title = MutableLiveData<String>()
fun addData() {
viewModelScope.launch {
//调用接口
}
datas.addOnPropertyChangedCallback(object : Observable.OnPropertyChangedCallback() {
override fun onPropertyChanged(sender: Observable?, propertyId: Int) {
}
})
}
}
// fragment中使用
binding.tvContent.setOnClickListener {
ToastUtils.showShort("========")
viewModel.country3().observe(viewLifecycleOwner) {
viewModel.datas.get()?.title = "${it.first.data?.size}"
viewModel.datas.notifyChange()
}
}
viewModel.isShowDialog.observe(viewLifecycleOwner) {
if (it) {
LoadDialogUtil.showWaitDialog(activity as Context)
} else {
LoadDialogUtil.dismissWaitDialog()
}
}
class CustomPageDataSource() :
PageKeyedDataSource<Int, A>() {
override fun loadInitial(
params: LoadInitialParams<Int>,
callback: LoadInitialCallback<Int, A>
) {
loge("loadInitial size : ${params.requestedLoadSize} ")
fetchData(LoadParams(1, 10)) {
callback.onResult(it.tx, null, 2)
}
}
override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, A>) {
loge("loadAfter size : ${params.requestedLoadSize} page:${params.key}")
fetchData(params) {
if (params.key == 3) {
callback.onResult(mutableListOf(), params.key + 1)
} else {
callback.onResult(it.tx, params.key + 1)
}
}
}
override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, A>) {
loge("loadBefore size : ${params.requestedLoadSize} page:${params.key}")
fetchData(params) {
callback.onResult(it.tx, params.key - 1)
}
}
private fun fetchData(params: LoadParams<Int>, pagingCallback: (Tx) -> Unit) {
Api.createService(ApiService::class.java)
.testPage(params.key, params.requestedLoadSize)
.enqueue(object : Callback<HttpResult<Tx>> {
override fun onFailure(call: Call<HttpResult<Tx>>, t: Throwable) {
t.printStackTrace()
}
override fun onResponse(
call: Call<HttpResult<Tx>>,
response: Response<HttpResult<Tx>>
) {
val data = response.body()
data?.let {
pagingCallback(it.data!!)
}
}
})
}
}
class CustomPageDataSourceFactory() : DataSource.Factory<Int, A>() {
override fun create(): DataSource<Int, A> {
return CustomPageDataSource()
}
}
class CommonListDataViewModel(
private val params: Any?,
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
val moreLoading = MutableLiveData<Boolean>()//上拉加载更多状态
val liveDataMerger = MediatorLiveData<Any>()
val data2 = LivePagedListBuilder(
CustomPageDataSourceFactory(), PagedList.Config.Builder()
.setPageSize(10)
.setEnablePlaceholders(true)
.setInitialLoadSizeHint(10)
.build()
).build()
val datas = MutableLiveData(MutableList(10) {
A("@it", false, "标题$it")
})
fun refresh() {
data2.value?.let {
(it.dataSource as PageKeyedDataSource).invalidate()
}
}
fun addData() {
// liveDataMerger.addSource(refreshing, Observer {
// liveDataMerger.value = it
// })
// liveDataMerger.addSource(moreLoading, Observer {
// liveDataMerger.value = it
// })
viewModelScope.launch {
//调用接口
}
}
}
// fragment中使用
private fun subscribeUi(adapter: CustomAdapter, binding: FragmentListLoadmoreBinding) {
//观察多个liveData
viewModel.data2.observe(viewLifecycleOwner) {
adapter.submitList(it)
Handler().postDelayed({
binding.isLoading = false
}, 2000)
}
binding.btnClick.setOnClickListener {
viewModel.refresh()
}
}
@BindingAdapter("visibleGone")
fun showHide(view: View, show: Boolean) {
view.visibility = if (show) View.VISIBLE else View.GONE
}
<TextView
android:id="@+id/tv_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="isLoading..."
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:visibleGone="@{isLoading}" />