Kotlin 在带有 FrameLayout 的 DialogFragment 中显示片段
Kotlin Display Fragment inside DialogFragment with FrameLayout
我正在创建一个 DialogFragment,但在该 Fragment 内部有一个 FrameLayout,它将在片段之间动态变化。
为了更好地控制所有片段,我创建了一个实例 class 来处理名为 NavigationDelegate
的片段
class NavigationDelegate(private val fragmentManager: FragmentManager, private val containerId: Int) {
init {
fragmentManager.addOnBackStackChangedListener {
val currentFragment = fragmentManager.findFragmentById(containerId)
currentFragment?.userVisibleHint = true
}
}
fun navigateTo(to: Fragment, addToBackStack: Boolean = true){
val transaction = fragmentManager.beginTransaction().replace(containerId, to)
if(addToBackStack) transaction.addToBackStack(null)
transaction.commit()
}
fun navigate(from: Fragment? = null, to: Fragment, addToBackStack: Boolean = true) {
from?.let {
from.userVisibleHint = false
val transaction = fragmentManager.beginTransaction().replace(containerId, to)
if(addToBackStack) transaction.addToBackStack(null)
transaction.commit()
}.let {
val transaction = fragmentManager.beginTransaction().add(containerId, to)
if(addToBackStack) transaction.addToBackStack(null)
transaction.commit()
}
}
}
这是我调用要创建的 DialogFragment 的部分。
val purchase = inputFragmentView!!.findViewById<MaterialButton>(R.id.purchaseButton)
purchase.setOnClickListener {
val paymentSteps: PaymentStepsFragment?
paymentSteps = PaymentStepsFragment()
paymentSteps.isCancelable = false
if (!paymentSteps.isVisible) paymentSteps.show(fragmentManager, "paymentSteps")
}
这里是 PaymentStepsFragment
class PaymentStepsFragment : DialogFragment() {
private var viewer: View? = null
lateinit var fragmentContainer: FrameLayout
lateinit var navigationDelegate: NavigationDelegate
override fun getTheme(): Int {
return R.style.SlideUpDownDialog
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
when {
viewer != null -> (viewer!!.parent as ViewGroup).removeView(viewer)
}
viewer = inflater.inflate(R.layout.fragment_steps_payment, container, false)
dialog?.window?.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
return viewer
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val imageStep = view.imageSteps
imageStep.setSteps(R.drawable.ic_wallet_step_1, R.drawable.ic_deliver_step_2, R.drawable.ic_review_step_3)
imageStep.scaleUp = 2.0f
imageStep.animationDuration = 500
view.next.setOnClickListener {
imageStep.next()
}
view.back.setOnClickListener {
imageStep.previous()
}
fragmentContainer = view.framePayment
navigationDelegate = NavigationDelegate(fragmentManager!!, fragmentContainer.id)
navigate(to = PaymentFragment(), addToBackStack = false)
}
override fun onResume() {
super.onResume()
val decorView = dialog.window.decorView
val uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
decorView.systemUiVisibility = uiOptions
}
private fun navigate(from: Fragment? = null, to: Fragment, addToBackStack: Boolean = true) {
from?.let {
navigationDelegate.navigate(from, to, addToBackStack)
}.let {
navigationDelegate.navigateTo(to, addToBackStack)
}
}
}
当我显示 DialogFragment 时,我收到此错误消息:
java.lang.IllegalArgumentException: No view found for id 0x7f08008f (ni.devotion.hisabapp:id/framePayment) for fragment PaymentFragment{7b58f52 #3 id=0x7f08008f}
但是视图存在于布局中,请知道如何解决这个问题...
<FrameLayout
android:id="@+id/framePayment"
android:layout_width="match_parent"
android:layout_height="300dp"/>
为了解决问题,我改变了:
navigationDelegate = NavigationDelegate(fragmentManager!!, fragmentContainer.id)
进入
navigationDelegate = NavigationDelegate(this.childFragmentManager, fragmentContainer.id)
我正在创建一个 DialogFragment,但在该 Fragment 内部有一个 FrameLayout,它将在片段之间动态变化。
为了更好地控制所有片段,我创建了一个实例 class 来处理名为 NavigationDelegate
的片段class NavigationDelegate(private val fragmentManager: FragmentManager, private val containerId: Int) {
init {
fragmentManager.addOnBackStackChangedListener {
val currentFragment = fragmentManager.findFragmentById(containerId)
currentFragment?.userVisibleHint = true
}
}
fun navigateTo(to: Fragment, addToBackStack: Boolean = true){
val transaction = fragmentManager.beginTransaction().replace(containerId, to)
if(addToBackStack) transaction.addToBackStack(null)
transaction.commit()
}
fun navigate(from: Fragment? = null, to: Fragment, addToBackStack: Boolean = true) {
from?.let {
from.userVisibleHint = false
val transaction = fragmentManager.beginTransaction().replace(containerId, to)
if(addToBackStack) transaction.addToBackStack(null)
transaction.commit()
}.let {
val transaction = fragmentManager.beginTransaction().add(containerId, to)
if(addToBackStack) transaction.addToBackStack(null)
transaction.commit()
}
}
}
这是我调用要创建的 DialogFragment 的部分。
val purchase = inputFragmentView!!.findViewById<MaterialButton>(R.id.purchaseButton)
purchase.setOnClickListener {
val paymentSteps: PaymentStepsFragment?
paymentSteps = PaymentStepsFragment()
paymentSteps.isCancelable = false
if (!paymentSteps.isVisible) paymentSteps.show(fragmentManager, "paymentSteps")
}
这里是 PaymentStepsFragment
class PaymentStepsFragment : DialogFragment() {
private var viewer: View? = null
lateinit var fragmentContainer: FrameLayout
lateinit var navigationDelegate: NavigationDelegate
override fun getTheme(): Int {
return R.style.SlideUpDownDialog
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
when {
viewer != null -> (viewer!!.parent as ViewGroup).removeView(viewer)
}
viewer = inflater.inflate(R.layout.fragment_steps_payment, container, false)
dialog?.window?.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
return viewer
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val imageStep = view.imageSteps
imageStep.setSteps(R.drawable.ic_wallet_step_1, R.drawable.ic_deliver_step_2, R.drawable.ic_review_step_3)
imageStep.scaleUp = 2.0f
imageStep.animationDuration = 500
view.next.setOnClickListener {
imageStep.next()
}
view.back.setOnClickListener {
imageStep.previous()
}
fragmentContainer = view.framePayment
navigationDelegate = NavigationDelegate(fragmentManager!!, fragmentContainer.id)
navigate(to = PaymentFragment(), addToBackStack = false)
}
override fun onResume() {
super.onResume()
val decorView = dialog.window.decorView
val uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
decorView.systemUiVisibility = uiOptions
}
private fun navigate(from: Fragment? = null, to: Fragment, addToBackStack: Boolean = true) {
from?.let {
navigationDelegate.navigate(from, to, addToBackStack)
}.let {
navigationDelegate.navigateTo(to, addToBackStack)
}
}
}
当我显示 DialogFragment 时,我收到此错误消息:
java.lang.IllegalArgumentException: No view found for id 0x7f08008f (ni.devotion.hisabapp:id/framePayment) for fragment PaymentFragment{7b58f52 #3 id=0x7f08008f}
但是视图存在于布局中,请知道如何解决这个问题...
<FrameLayout
android:id="@+id/framePayment"
android:layout_width="match_parent"
android:layout_height="300dp"/>
为了解决问题,我改变了:
navigationDelegate = NavigationDelegate(fragmentManager!!, fragmentContainer.id)
进入
navigationDelegate = NavigationDelegate(this.childFragmentManager, fragmentContainer.id)