Modify:创建ViewPager2的基础adapter封装。Fragment,Activity的数据状态帮助类重写封装。

This commit is contained in:
Dboy
2021-08-05 17:45:42 +08:00
parent 9e8863ea28
commit c89d700fac
13 changed files with 523 additions and 119 deletions

View File

@ -1,13 +1,16 @@
package com.quyunshuo.module.home.activity
import android.os.Bundle
import androidx.activity.viewModels
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.fragment.app.FragmentActivity
import com.quyunshuo.androidbaseframemvvm.base.mvvm.vm.EmptyViewModel
import com.quyunshuo.androidbaseframemvvm.common.ui.BaseActivity
import com.quyunshuo.androidbaseframemvvm.common.ui.BaseFragmentStateAdapter
import com.quyunshuo.module.home.databinding.HomeActivityInternalLayoutBinding
import com.quyunshuo.module.home.fragment.InternalFragment
import dagger.hilt.android.AndroidEntryPoint
import kotlin.random.Random
/**
* @author DBoy 2021/7/6 <p>
@ -18,28 +21,73 @@ class InternalPagerActivity : BaseActivity<HomeActivityInternalLayoutBinding, Em
override val mViewModel: EmptyViewModel by viewModels()
private val mCreateFragmentData = mutableListOf<String>()
private var mAdapter: InternalPagerFragmentAdapter? = null
override fun HomeActivityInternalLayoutBinding.initView() {
addFragment.setOnClickListener {
//添加一个随机页面
mAdapter?.addData("Pager ID:${Random.nextInt()}")
}
removeFragment.setOnClickListener {
//移除当前展示页面
// mAdapter?.removeData("更多")
mAdapter?.removeData(viewPager.currentItem)
}
initPager()
}
private fun initPager() {
val fragments = mutableListOf<Fragment>(
InternalFragment(),
InternalFragment(),
InternalFragment(),
InternalFragment(),
InternalFragment(),
InternalFragment(),
InternalFragment()
)
mBinding.viewPager.adapter = object : FragmentStateAdapter(this) {
override fun getItemCount(): Int = fragments.size
override fun createFragment(position: Int): Fragment = fragments[position]
}
mCreateFragmentData.add("首页")
mCreateFragmentData.add("我的")
mCreateFragmentData.add("设置")
mCreateFragmentData.add("更多")
mCreateFragmentData.add("动态")
mAdapter = InternalPagerFragmentAdapter(this, mCreateFragmentData)
mBinding.viewPager.adapter = mAdapter
}
override fun initObserve() {}
override fun initRequestData() {}
class InternalPagerFragmentAdapter(activity: FragmentActivity, data: MutableList<String> = mutableListOf()) :
BaseFragmentStateAdapter<String>(activity, data) {
override fun createFragment(item: String, position: Int): Fragment {
val bundle = Bundle().apply {
putString("What", item)
}
return when (item) {
"首页" -> {
//假装首页
InternalFragment()
}
"我的" -> {
//假装我的
InternalFragment()
}
"设置" -> {
//假装设置
InternalFragment()
}
"更多" -> {
//假装更多
InternalFragment()
}
else -> {
//另外动态item创建类型
InternalFragment()
}
}.apply {
//设置传递参数bundle
arguments = bundle
}
}
}
}

View File

@ -1,6 +1,9 @@
package com.quyunshuo.module.home.fragment
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.viewModels
import com.quyunshuo.androidbaseframemvvm.base.utils.status.ViewStatusHelper
import com.quyunshuo.androidbaseframemvvm.common.ui.BaseFragment
import com.quyunshuo.module.home.databinding.HomeFragmentInternalLayoutBinding
import dagger.hilt.android.AndroidEntryPoint
@ -14,9 +17,26 @@ class InternalFragment : BaseFragment<HomeFragmentInternalLayoutBinding, Interna
override val mViewModel by viewModels<InternalViewModel>()
/**
* 页面状态数据管理帮助类
*/
private lateinit var mInternalFragmentStatusHelper: InternalFragmentStatusHelper
/***
* 注册帮助类
*/
override fun onRegisterStatusHelper(): ViewStatusHelper? {
mInternalFragmentStatusHelper = InternalFragmentStatusHelper(super.onRegisterStatusHelper())
return mInternalFragmentStatusHelper
}
override fun HomeFragmentInternalLayoutBinding.initView() {}
override fun initObserve() {
mViewModel.increase(mInternalFragmentStatusHelper.rebuildSize)
val s = arguments?.getString("What") ?: ""
mBinding.toolBarTitle.text = s
mViewModel.recreatedCont.observe(viewLifecycleOwner) {
mBinding.recreateContTv.text = "重建次数 $it"
}
@ -33,12 +53,33 @@ class InternalFragment : BaseFragment<HomeFragmentInternalLayoutBinding, Interna
}
override fun initRequestData() {
//每次重建都会累加数据
mViewModel.increase()
//当页面重建的时候不再重新请求数据,且当前页面数据数据有且没有刷新逻辑的情况下不再请求数据。
if (isRecreate() && mViewModel.firstData.value != null) {
return
}
mViewModel.getData()
}
/**
* 当前Fragment重建帮助类
*/
internal class InternalFragmentStatusHelper(parentViewStatusHelper: ViewStatusHelper?) : ViewStatusHelper(parentViewStatusHelper) {
/**
* 重建次数
*/
var rebuildSize = 0
private val KEY_REBUILD = "com.quyunshuo.module.home.fragment.InternalFragment.InternalFragmentStatusHelper.rebuild"
override fun onRestoreInstanceStatus(savedInstanceState: Bundle?) {
super.onRestoreInstanceStatus(savedInstanceState)
rebuildSize = (savedInstanceState?.getInt(KEY_REBUILD) ?: 0) + 1
}
override fun onSaveInstanceState(bundle: Bundle) {
super.onSaveInstanceState(bundle)
bundle.putInt(KEY_REBUILD, rebuildSize)
}
}
}

View File

@ -4,6 +4,7 @@ import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.quyunshuo.androidbaseframemvvm.base.mvvm.vm.BaseViewModel
import com.quyunshuo.androidbaseframemvvm.base.utils.status.ViewStatusHelper
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
@ -15,12 +16,17 @@ import javax.inject.Inject
/**
* @author DBoy 2021/7/6 <p>
* - 文件描述 :
* - 文件描述 : ViewModel再ViewPager2的Fragment中会随着Fragment执行[Fragment.onDestory]一同销毁。
* 所以一些需要长期保存的变量数据不适合保存再ViewModel考虑使用[ViewStatusHelper]保存页面上部分数据,
* 页面恢复的时候再交给ViewModel处理,例如[recreatedCont]
*/
@HiltViewModel
class InternalViewModel @Inject constructor(private val repository: InternalRepository) :
class InternalViewModel @Inject constructor() :
BaseViewModel() {
@Inject
lateinit var repository: InternalRepository
/**
* 重建计数
*/
@ -34,9 +40,8 @@ class InternalViewModel @Inject constructor(private val repository: InternalRepo
/**
* 累加重建次数
*/
fun increase() {
val value = recreatedCont.value ?: 0
recreatedCont.value = value + 1
fun increase(size: Int) {
recreatedCont.value = size
}
/**
@ -57,8 +62,4 @@ class InternalViewModel @Inject constructor(private val repository: InternalRepo
}
}
override fun onCleared() {
super.onCleared()
Log.d("DJC", "InternalViewModel Clear")
}
}

View File

@ -1,12 +1,45 @@
<?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">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
app:layout_constraintBottom_toTopOf="@id/bottomAction"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="0dp" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/bottomAction"
android:layout_width="match_parent"
android:layout_height="44dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent">
<Button
android:id="@+id/removeFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:shadowColor="#A82424"
android:text="删除当前Fragment"
android:textAllCaps="false"
android:translationZ="@dimen/dp_10" />
<Button
android:id="@+id/addFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:shadowColor="#000"
android:text="添加一个新的Fragment"
android:textAllCaps="false"
android:translationZ="@dimen/dp_10" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,18 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="#fff"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="46dp"
android:layout_gravity="top"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/toolBarTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#262A30"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
app:layout_constraintBottom_toBottomOf="parent"
android:background="#D1D0D0"
android:layout_width="match_parent"
android:layout_height="1dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/loadingStatusTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="50dp"
android:textColor="#333"
android:textSize="28sp"
android:textSize="20sp"
tools:text="Loging" />
@ -20,6 +49,7 @@
android:id="@+id/loadDataTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:textColor="#333"
android:textSize="28sp"
@ -29,7 +59,8 @@
android:id="@+id/recreateContTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:textColor="#333"
android:textSize="28sp"
tools:text="重建计数" />