【发布时间】:2019-07-15 09:45:55
【问题描述】:
我有一个使用片段的活动。为了从片段到活动进行通信,我使用接口。这是简化的代码:
活动:
class HomeActivity : AppCompatActivity(), DiaryFragment.IAddEntryClickedListener, DiaryFragment.IDeleteClickedListener {
override fun onAddEntryClicked() {
//DO something
}
override fun onEntryDeleteClicked(isDeleteSet: Boolean) {
//Do something
}
private val diaryFragment: DiaryFragment = DiaryFragment()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
diaryFragment.setOnEntryClickedListener(this)
diaryFragment.setOnDeleteClickedListener(this)
supportFragmentManager.beginTransaction().replace(R.id.content_frame, diaryFragment)
}
}
片段:
class DiaryFragment: Fragment() {
private var onEntryClickedListener: IAddEntryClickedListener? = null
private var onDeleteClickedListener: IDeleteClickedListener? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view: View = inflater.inflate(R.layout.fragment_diary, container, false)
//Some user interaction
onDeleteClickedListener!!.onEntryDeleteClicked()
onDeleteClickedListener!!.onEntryDeleteClicked()
return view
}
interface IAddEntryClickedListener {
fun onAddEntryClicked()
}
interface IDeleteClickedListener {
fun onEntryDeleteClicked()
}
fun setOnEntryClickedListener(listener: IAddEntryClickedListener) {
onEntryClickedListener = listener
}
fun setOnDeleteClickedListener(listener: IDeleteClickedListener) {
onDeleteClickedListener = listener
}
}
这可行,但是当片段处于活动状态并且方向从纵向更改为横向或其他方式时,侦听器为空。我不能将它们放入已保存的InstanceState,或者我可以以某种方式吗?还是有其他方法可以解决这个问题?
【问题讨论】:
-
“我无法将它们放入 savedInstanceState”——正确。 “或者有其他方法可以解决这个问题吗?” -- 现代解决方案是使用共享的
ViewModel和LiveData。片段会将事件发布到活动将观察到的LiveData。 Kotlin 风格的遗留解决方案是将requireActivity()转换为您的接口并在其上调用函数,因为您的活动是实现接口的位置。 -
@CommonsWare 如果我的听众引用了上下文怎么办?据我了解,共享 ViewModel 成员不应直接或间接引用上下文。
-
@Neoh:如果您使用的是 Jetpack
ViewModel,请使用AndroidViewModel访问Application单例。