Modify:创建ViewPager2的基础adapter封装。Fragment,Activity的数据状态帮助类重写封装。
This commit is contained in:
@ -1,13 +1,17 @@
|
||||
package com.quyunshuo.androidbaseframemvvm.base.mvvm.v
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.quyunshuo.androidbaseframemvvm.base.mvvm.vm.BaseViewModel
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.*
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.BindingReflex
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusRegister
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.network.AutoRegisterNetListener
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.network.NetworkStateChangeListener
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.status.ViewStatusHelper
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.status.imp.BaseFrameViewStatusHelperImp
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.toast
|
||||
|
||||
/**
|
||||
* Activity基类
|
||||
@ -15,7 +19,7 @@ import com.quyunshuo.androidbaseframemvvm.base.utils.network.NetworkStateChangeL
|
||||
* @author Qu Yunshuo
|
||||
* @since 8/27/20
|
||||
*/
|
||||
abstract class BaseFrameActivity<VB : ViewBinding, VM : BaseViewModel> : AppCompatActivity(),
|
||||
abstract class BaseFrameActivity<VB : ViewBinding, VM : BaseViewModel> : BaseFrameStatusActivity(),
|
||||
FrameView<VB>, NetworkStateChangeListener {
|
||||
|
||||
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||
@ -25,15 +29,13 @@ abstract class BaseFrameActivity<VB : ViewBinding, VM : BaseViewModel> : AppComp
|
||||
protected abstract val mViewModel: VM
|
||||
|
||||
/**
|
||||
* activity页面重建帮助类
|
||||
* 基础UI状态管理工具 保存了是否重建的状态信息
|
||||
*/
|
||||
private var mStatusHelper: ActivityRecreateHelper? = null
|
||||
private lateinit var mStatusHelper: BaseFrameViewStatusHelperImp
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(mBinding.root)
|
||||
//处理保存的装填
|
||||
mStatusHelper?.onRestoreInstanceStatus(savedInstanceState)
|
||||
// ARouter 依赖注入
|
||||
ARouter.getInstance().inject(this)
|
||||
// 注册EventBus
|
||||
@ -77,24 +79,13 @@ abstract class BaseFrameActivity<VB : ViewBinding, VM : BaseViewModel> : AppComp
|
||||
toast(if (isConnected) "网络已连接" else "网络已断开")
|
||||
}
|
||||
|
||||
override fun isRecreate(): Boolean = mStatusHelper?.isRecreate ?: false
|
||||
override fun isRecreate(): Boolean = mStatusHelper.isRecreate
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
if (mStatusHelper == null) {
|
||||
//仅当触发重建需要保存状态时创建对象
|
||||
mStatusHelper = ActivityRecreateHelper(outState)
|
||||
} else {
|
||||
mStatusHelper?.onSaveInstanceState(outState)
|
||||
}
|
||||
super.onSaveInstanceState(outState)
|
||||
override fun onRegisterStatusHelper(): ViewStatusHelper? {
|
||||
mStatusHelper = BaseFrameViewStatusHelperImp(super.onRegisterStatusHelper())
|
||||
return mStatusHelper
|
||||
}
|
||||
|
||||
/**
|
||||
* - activity 重建帮助工具类
|
||||
*/
|
||||
private class ActivityRecreateHelper(savedInstanceState: Bundle? = null) :
|
||||
ViewRecreateHelper(savedInstanceState)
|
||||
|
||||
override fun onDestroy() {
|
||||
if (javaClass.isAnnotationPresent(EventBusRegister::class.java)) EventBusUtils.unRegister(
|
||||
this
|
||||
|
||||
@ -4,14 +4,14 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.quyunshuo.androidbaseframemvvm.base.mvvm.vm.BaseViewModel
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.BindingReflex
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusRegister
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.ViewRecreateHelper
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.status.ViewStatusHelper
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.status.imp.BaseFrameViewStatusHelperImp
|
||||
|
||||
/**
|
||||
* Fragment基类
|
||||
@ -19,7 +19,7 @@ import com.quyunshuo.androidbaseframemvvm.base.utils.ViewRecreateHelper
|
||||
* @author Qu Yunshuo
|
||||
* @since 8/27/20
|
||||
*/
|
||||
abstract class BaseFrameFragment<VB : ViewBinding, VM : BaseViewModel> : Fragment(), FrameView<VB> {
|
||||
abstract class BaseFrameFragment<VB : ViewBinding, VM : BaseViewModel> : BaseFrameStatusFragment(), FrameView<VB> {
|
||||
|
||||
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||
BindingReflex.reflexViewBinding(javaClass, layoutInflater)
|
||||
@ -28,9 +28,10 @@ abstract class BaseFrameFragment<VB : ViewBinding, VM : BaseViewModel> : Fragmen
|
||||
protected abstract val mViewModel: VM
|
||||
|
||||
/**
|
||||
* fragment状态保存工具类
|
||||
* 基础UI状态管理工具
|
||||
*/
|
||||
private var mStatusHelper: FragmentStatusHelper? = null
|
||||
private lateinit var mBaseStatusHelper: BaseFrameViewStatusHelperImp
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
@ -42,8 +43,6 @@ abstract class BaseFrameFragment<VB : ViewBinding, VM : BaseViewModel> : Fragmen
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
//处理恢复
|
||||
mStatusHelper?.onRestoreInstanceStatus(savedInstanceState)
|
||||
// ARouter 依赖注入
|
||||
ARouter.getInstance().inject(this)
|
||||
// 注册EventBus
|
||||
@ -54,28 +53,13 @@ abstract class BaseFrameFragment<VB : ViewBinding, VM : BaseViewModel> : Fragmen
|
||||
initRequestData()
|
||||
}
|
||||
|
||||
override fun isRecreate(): Boolean = mStatusHelper?.isRecreate ?: false
|
||||
override fun isRecreate(): Boolean = mBaseStatusHelper.isRecreate
|
||||
|
||||
/**
|
||||
* 页面可能重建的时候回执行此方法,进行当前页面状态保存
|
||||
*/
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
if (mStatusHelper == null) {
|
||||
//仅当触发重建需要保存状态时创建对象
|
||||
mStatusHelper = FragmentStatusHelper(outState)
|
||||
} else {
|
||||
mStatusHelper?.onSaveInstanceState(outState)
|
||||
}
|
||||
super.onSaveInstanceState(outState)
|
||||
override fun onRegisterStatusHelper(): ViewStatusHelper? {
|
||||
mBaseStatusHelper = BaseFrameViewStatusHelperImp(super.onRegisterStatusHelper())
|
||||
return mBaseStatusHelper
|
||||
}
|
||||
|
||||
/**
|
||||
* - fragment状态保存帮助类;
|
||||
* - 暂时没有其他需要保存的--空继承
|
||||
*/
|
||||
private class FragmentStatusHelper(savedInstanceState: Bundle? = null) :
|
||||
ViewRecreateHelper(savedInstanceState)
|
||||
|
||||
override fun onDestroy() {
|
||||
if (javaClass.isAnnotationPresent(EventBusRegister::class.java)) EventBusUtils.unRegister(
|
||||
this
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
package com.quyunshuo.androidbaseframemvvm.base.mvvm.v
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.status.ViewStatusHelper
|
||||
|
||||
/**
|
||||
* @author DBoy 2021/8/5 <p>
|
||||
* - 文件描述 : 基础状态管理Activity
|
||||
*/
|
||||
open class BaseFrameStatusActivity : AppCompatActivity() {
|
||||
/**
|
||||
* 基础状态管理帮助类
|
||||
*/
|
||||
private var mBaseStatusHelper: ViewStatusHelper? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
//注册状态帮助类
|
||||
mBaseStatusHelper = onRegisterStatusHelper()
|
||||
//恢复状态数据
|
||||
mBaseStatusHelper?.onRestoreInstanceStatus(savedInstanceState)
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存状态
|
||||
*/
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
mBaseStatusHelper?.onSaveInstanceState(outState)
|
||||
super.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册状态管理帮助类,子类重写此方法以注册帮助类。
|
||||
* 每一层都有可能有自己的状态管理帮助类,所以继承重写的时候,需要将super的对象传入自己的帮助类构造函数中
|
||||
*/
|
||||
protected open fun onRegisterStatusHelper(): ViewStatusHelper? {
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package com.quyunshuo.androidbaseframemvvm.base.mvvm.v
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.status.ViewStatusHelper
|
||||
|
||||
/**
|
||||
* @author DBoy 2021/8/5 <p>
|
||||
* - 文件描述 : 基础状态管理Fragment
|
||||
*/
|
||||
open class BaseFrameStatusFragment : Fragment() {
|
||||
/**
|
||||
* 基础状态管理帮助类
|
||||
*/
|
||||
private var mBaseStatusHelper: ViewStatusHelper? = null
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
//注册状态帮助类
|
||||
mBaseStatusHelper = onRegisterStatusHelper()
|
||||
//恢复状态数据
|
||||
mBaseStatusHelper?.onRestoreInstanceStatus(savedInstanceState)
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存状态
|
||||
*/
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
mBaseStatusHelper?.onSaveInstanceState(outState)
|
||||
super.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册状态管理帮助类,子类重写此方法以注册帮助类。
|
||||
* 每一层都有可能有自己的状态管理帮助类,所以继承重写的时候,需要将super的对象传入自己的帮助类构造函数中
|
||||
*/
|
||||
protected open fun onRegisterStatusHelper(): ViewStatusHelper? {
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
package com.quyunshuo.androidbaseframemvvm.base.utils
|
||||
|
||||
import android.os.Bundle
|
||||
|
||||
/**
|
||||
* @author DBoy 2021/7/8
|
||||
*
|
||||
* - 文件描述 : 视图,activity,fragment重建帮助类
|
||||
*/
|
||||
open class ViewRecreateHelper(savedInstanceState: Bundle?=null) {
|
||||
/**
|
||||
* 重建标记key
|
||||
*/
|
||||
private val KEY_RECREATE = "recreate"
|
||||
|
||||
/**
|
||||
* 是否重建
|
||||
*/
|
||||
var isRecreate = false
|
||||
private set
|
||||
|
||||
init {
|
||||
if (savedInstanceState!=null) {
|
||||
this.onSaveInstanceState(savedInstanceState)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复状态
|
||||
*/
|
||||
open fun onRestoreInstanceStatus(savedInstanceState: Bundle?) {
|
||||
isRecreate = savedInstanceState?.getBoolean(KEY_RECREATE) ?: false
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存状态
|
||||
*/
|
||||
open fun onSaveInstanceState(bundle: Bundle) {
|
||||
bundle.putBoolean(KEY_RECREATE, true)
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.quyunshuo.androidbaseframemvvm.base.utils.status
|
||||
|
||||
import android.os.Bundle
|
||||
|
||||
/**
|
||||
* @author DBoy 2021/8/5 <p>
|
||||
* - 文件描述 : 采用了一种链式调用,所有对象持有自己父级帮助类,进行场景回复时先恢复链头的数据
|
||||
*/
|
||||
abstract class ViewStatusHelper(val parentViewStatusHelper: ViewStatusHelper?) {
|
||||
|
||||
open fun onRestoreInstanceStatus(savedInstanceState: Bundle?) {
|
||||
parentViewStatusHelper?.onRestoreInstanceStatus(savedInstanceState)
|
||||
}
|
||||
|
||||
open fun onSaveInstanceState(bundle: Bundle) {
|
||||
parentViewStatusHelper?.onSaveInstanceState(bundle)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package com.quyunshuo.androidbaseframemvvm.base.utils.status.imp
|
||||
|
||||
import android.os.Bundle
|
||||
import com.quyunshuo.androidbaseframemvvm.base.utils.status.ViewStatusHelper
|
||||
|
||||
/**
|
||||
* @author DBoy 2021/7/8
|
||||
*
|
||||
* - 文件描述 : 视图,activity,fragment重建帮助类
|
||||
*/
|
||||
open class BaseFrameViewStatusHelperImp(parentViewStatusHelper: ViewStatusHelper? = null) : ViewStatusHelper(parentViewStatusHelper) {
|
||||
/**
|
||||
* 重建标记key 以包名保存数据可以防止嵌套层级出现重复Key
|
||||
*/
|
||||
private val KEY_RECREATE = "com.quyunshuo.androidbaseframemvvm.base.utils.status.BaseFrameViewStatusHelperImp.Recreate"
|
||||
|
||||
/**
|
||||
* 是否重建
|
||||
*/
|
||||
var isRecreate = false
|
||||
private set
|
||||
|
||||
|
||||
/**
|
||||
* 恢复状态
|
||||
*/
|
||||
override fun onRestoreInstanceStatus(savedInstanceState: Bundle?) {
|
||||
super.onRestoreInstanceStatus(savedInstanceState)
|
||||
isRecreate = savedInstanceState?.getBoolean(KEY_RECREATE) ?: false
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存状态
|
||||
*/
|
||||
override fun onSaveInstanceState(bundle: Bundle) {
|
||||
super.onSaveInstanceState(bundle)
|
||||
bundle.putBoolean(KEY_RECREATE, true)
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,176 @@
|
||||
package com.quyunshuo.androidbaseframemvvm.common.ui
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* @author DBoy 2021/8/5 <p>
|
||||
* - 文件描述 : ViewPager2 FragmentAdapter封装
|
||||
* - 对于元数据[mData]的增加删除操作只能通过内部提供的4种方式进行操作:
|
||||
* - [setNewData]
|
||||
* - [addNewData]
|
||||
* - [addData]
|
||||
* - [removeData]
|
||||
* - 内部使用[DiffUtil]工具实现更新UI,不需调用[notifyDataSetChanged]等一系列方法。
|
||||
*/
|
||||
abstract class BaseFragmentStateAdapter<T> : FragmentStateAdapter {
|
||||
|
||||
private val TAG = "FragmentAdapter"
|
||||
|
||||
/**
|
||||
* 记录生成的Fragment id列表
|
||||
*/
|
||||
private var mFragmentIdMap = mutableMapOf<T, Long>()
|
||||
|
||||
/**
|
||||
* 需要生成页面的数据
|
||||
*/
|
||||
var mData: MutableList<T>
|
||||
set(value) {
|
||||
field = value
|
||||
mFragmentIdMap.clear()
|
||||
createFragmentsIds(field)
|
||||
}
|
||||
|
||||
constructor(fragment: Fragment, data: MutableList<T> = mutableListOf()) : super(fragment) {
|
||||
mData = data
|
||||
}
|
||||
|
||||
constructor(activity: FragmentActivity, data: MutableList<T> = mutableListOf()) : super(
|
||||
activity
|
||||
) {
|
||||
mData = data
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要创建几个Fragment
|
||||
*/
|
||||
override fun getItemCount(): Int = mData.size
|
||||
|
||||
/**
|
||||
* 创建Fragment
|
||||
*/
|
||||
final override fun createFragment(position: Int): Fragment {
|
||||
return createFragment(mData[position], position)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建fragment 传递数据
|
||||
*/
|
||||
abstract fun createFragment(item: T, position: Int): Fragment
|
||||
|
||||
/**
|
||||
* 获取fragment 对应 id
|
||||
*/
|
||||
override fun getItemId(position: Int): Long {
|
||||
if (position >= mData.size) return RecyclerView.NO_ID
|
||||
return mFragmentIdMap[mData[position]] ?: return RecyclerView.NO_ID
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否包含这个id的数
|
||||
*/
|
||||
override fun containsItem(itemId: Long): Boolean {
|
||||
return mFragmentIdMap.values.contains(itemId)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置新数据
|
||||
*/
|
||||
fun setNewData(data: MutableList<T> = mutableListOf()) {
|
||||
val oldData = copyData()
|
||||
mData = data
|
||||
diffNotifyDataSetChanged(oldData, mData)
|
||||
}
|
||||
|
||||
/**
|
||||
* 累加新数据
|
||||
*/
|
||||
fun addNewData(data: MutableList<T> = mutableListOf()) {
|
||||
val oldData = copyData()
|
||||
mData.addAll(data)
|
||||
//创建新的对应位置的id
|
||||
createFragmentsIds(data)
|
||||
diffNotifyDataSetChanged(oldData, mData)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加数据
|
||||
*/
|
||||
fun addData(data: T) {
|
||||
val oldData = copyData()
|
||||
mData.add(data)
|
||||
//随机一个id对应当前位置Fragment,两次随机确保同id率为最低概率
|
||||
mFragmentIdMap[data] = Random.nextLong() - Random.nextInt()
|
||||
diffNotifyDataSetChanged(oldData, mData)
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除某个数据
|
||||
*/
|
||||
fun removeData(data: T): Boolean {
|
||||
val oldData = copyData()
|
||||
if (mData.remove(data)) {
|
||||
mFragmentIdMap.remove(data)
|
||||
diffNotifyDataSetChanged(oldData, mData)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除某个位置的数据
|
||||
*/
|
||||
fun removeData(position: Int): Boolean {
|
||||
if (position < mData.size && position < mFragmentIdMap.size) {
|
||||
val oldData = copyData()
|
||||
val removeItem = mData.removeAt(position)
|
||||
mFragmentIdMap.remove(removeItem)
|
||||
diffNotifyDataSetChanged(oldData, mData)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 拷贝原数据
|
||||
*/
|
||||
private fun copyData(): MutableList<T> {
|
||||
val oldData = mutableListOf<T>()
|
||||
oldData.addAll(mData)
|
||||
return oldData
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用diff工具更新UI,当前diff工具对比使用的方式是 [==] 所以如果需要精确对比不同item数据,可以重写[T]的[equals]方法.
|
||||
*/
|
||||
private fun diffNotifyDataSetChanged(oldData: MutableList<T>, newData: MutableList<T>) {
|
||||
DiffUtil.calculateDiff(object : DiffUtil.Callback() {
|
||||
|
||||
override fun getOldListSize(): Int = oldData.size
|
||||
|
||||
override fun getNewListSize(): Int = newData.size
|
||||
|
||||
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean = oldData[oldItemPosition] == newData[newItemPosition]
|
||||
|
||||
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean = oldData[oldItemPosition] == newData[newItemPosition]
|
||||
|
||||
}, true).dispatchUpdatesTo(this)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建[mData]对应Fragment的id
|
||||
*/
|
||||
private fun createFragmentsIds(data: MutableList<T>) {
|
||||
for (item in data) {
|
||||
mFragmentIdMap[item] = Random.nextLong() - Random.nextInt()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@ -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>
|
||||
@ -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="重建计数" />
|
||||
|
||||
Reference in New Issue
Block a user