Kotlin:来自另一个片段的微调器 onItemSelectedListener
Kotlin: spinner onItemSelectedListener from another fragment
我有一个带有 BottomNavigationView、一个 Spinner 和一个 FrameLayout 的片段,在 FrameLayout 中出现了一个带有 BottomNavigationView.setOnNavigationItemSelectedListener 的新片段,这是我的代码:
碎片ValcuotaEvolFragment
class ValcuotaEvolFragment: Fragment() {
lateinit var fragment : Fragment
override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?, savedInstanceState: Bundle?): View? {
val root = inflater.inflate(R.layout.fragment_valcuota_evol, container, false)
val menuBottom: BottomNavigationView = root.findViewById(R.id.nav_view_valcuota_evol)
val spn : Spinner = root.findViewById(R.id.spnAFP)
val db = DataBaseHandler(activity!!.applicationContext)
val afpListName : ArrayList<String> = db.getAFPNames()
fragment= ValcuotaChartFragment()
val bundle = Bundle()
spn.adapter= ArrayAdapter<String>(activity!!.applicationContext,android.R.layout.simple_spinner_dropdown_item,afpListName)
spn.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
bundle.putString("afp",spn.selectedItem.toString())
}
override fun onNothingSelected(parent: AdapterView<*>) { }
}
menuBottom.setOnNavigationItemSelectedListener {
menuItem ->
when(menuItem.itemId){
R.id.nav_evolcuota_chart -> {
fragment = ValcuotaChartFragment()
}
R.id.nav_evolcuota_data -> {
fragment = ValcuotaDataFragment()
}
}
fragment.setArguments(bundle);
val transaction = childFragmentManager.beginTransaction()
transaction.replace(R.id.frame_valcuota_evol, fragment)
transaction.addToBackStack(null)
transaction.commit()
true
}
fragment.setArguments(bundle);
val transaction = childFragmentManager.beginTransaction()
transaction.replace(R.id.frame_valcuota_evol, fragment)
transaction.addToBackStack(null)
transaction.commit()
return root
}
}
我通过 Bundle 将值 "afp" 传递给新片段,现在我需要新片段根据我在 ValcuotaEvolFragment[=13= 的微调器中 select 做一些不同的事情]
这就是我需要的:
class ValcuotaDataFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val root = inflater.inflate(R.layout.fragment_valcuota_data, container, false)
val afp = arguments!!.getString("afp")
if(afp == "something"){
doSomething()
else {
doSomethingElse
}
return root
}
}
这确实有效,但只有当我更改 BottomNavigationView 中的项目时我才需要它在更改 Spinner 中的项目时有效,thx
编辑
EventBus 解决方案工作正常,但现在我在 ValcuotaDataFragment 中遇到了一个新问题,我有一个 RecyclerView,所以现在我需要在 Spinner 中更改项目后填充 RecyclerView,这就是我现在的做法:
val rcViewValcuota = root. findViewById(R.id.rc_valcuota_data) as RecyclerView
var valcuota : MutableList<ValcuotaModel>
val db = DataBaseHandler(activity!!.applicationContext)
valcuota = db.getCompleteValCuota(spinnerData.selectedItem,"desc")
rcViewValcuota.adapter= ContentValcuotaMonthlyAdapter(valcuota)
我无法从函数 listenItemChange
访问 "root"
好的,所以当您从微调器中选择不同的项目时,除非您将数据传递给片段,否则您的片段不会意识到它。因此,为了通知片段,您可以根据需要实现接口。或者我最喜欢的你可以使用 EventBus 库来传递数据。
我将向您展示如何实现 EventBus。
首先,添加EventBus依赖是Gradle文件:
implementation 'org.greenrobot:eventbus:3.1.1'
好的,现在创建一个数据 class 用于传递数据 SpinnerData:
data class SpinnerData(val selectedItem:String)
然后在您的 itemSelected 侦听器中,使用 EventBus 传递数据:
spn.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
// bundle.putString("afp",spn.selectedItem.toString())
//insted add following line
EventBus.getDefault().post(SpinnerData(spn.selectedItem.toString()))
}
override fun onNothingSelected(parent: AdapterView<*>) { }
}
然后在您的 ValcuotaDataFragment 中添加以下内容:
@Subscribe
fun listenItemChange(spinnerData: SpinnerData){
if (spinnerData.selectedItem == "something") {
doSomething()
} else {
doSomethingElse()
}
}
override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}
override fun onStop() {
EventBus.getDefault().unregister(this)
super.onStop()
}
现在,每当您更改微调项时,Evenbus 都会被触发并将数据传递给片段内的订阅方法。
希望这对您有所帮助,如果您遇到问题请告诉我。
编辑:
如果您的片段尚未初始化,这将不起作用。
第一次使用时,请将您的行保留在您的 itemSelected 侦听器中:
bundle.putString("afp",spn.selectedItem.toString())
我有一个带有 BottomNavigationView、一个 Spinner 和一个 FrameLayout 的片段,在 FrameLayout 中出现了一个带有 BottomNavigationView.setOnNavigationItemSelectedListener 的新片段,这是我的代码:
碎片ValcuotaEvolFragment
class ValcuotaEvolFragment: Fragment() {
lateinit var fragment : Fragment
override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?, savedInstanceState: Bundle?): View? {
val root = inflater.inflate(R.layout.fragment_valcuota_evol, container, false)
val menuBottom: BottomNavigationView = root.findViewById(R.id.nav_view_valcuota_evol)
val spn : Spinner = root.findViewById(R.id.spnAFP)
val db = DataBaseHandler(activity!!.applicationContext)
val afpListName : ArrayList<String> = db.getAFPNames()
fragment= ValcuotaChartFragment()
val bundle = Bundle()
spn.adapter= ArrayAdapter<String>(activity!!.applicationContext,android.R.layout.simple_spinner_dropdown_item,afpListName)
spn.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
bundle.putString("afp",spn.selectedItem.toString())
}
override fun onNothingSelected(parent: AdapterView<*>) { }
}
menuBottom.setOnNavigationItemSelectedListener {
menuItem ->
when(menuItem.itemId){
R.id.nav_evolcuota_chart -> {
fragment = ValcuotaChartFragment()
}
R.id.nav_evolcuota_data -> {
fragment = ValcuotaDataFragment()
}
}
fragment.setArguments(bundle);
val transaction = childFragmentManager.beginTransaction()
transaction.replace(R.id.frame_valcuota_evol, fragment)
transaction.addToBackStack(null)
transaction.commit()
true
}
fragment.setArguments(bundle);
val transaction = childFragmentManager.beginTransaction()
transaction.replace(R.id.frame_valcuota_evol, fragment)
transaction.addToBackStack(null)
transaction.commit()
return root
}
}
我通过 Bundle 将值 "afp" 传递给新片段,现在我需要新片段根据我在 ValcuotaEvolFragment[=13= 的微调器中 select 做一些不同的事情]
这就是我需要的:
class ValcuotaDataFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val root = inflater.inflate(R.layout.fragment_valcuota_data, container, false)
val afp = arguments!!.getString("afp")
if(afp == "something"){
doSomething()
else {
doSomethingElse
}
return root
}
}
这确实有效,但只有当我更改 BottomNavigationView 中的项目时我才需要它在更改 Spinner 中的项目时有效,thx
编辑
EventBus 解决方案工作正常,但现在我在 ValcuotaDataFragment 中遇到了一个新问题,我有一个 RecyclerView,所以现在我需要在 Spinner 中更改项目后填充 RecyclerView,这就是我现在的做法:
val rcViewValcuota = root. findViewById(R.id.rc_valcuota_data) as RecyclerView
var valcuota : MutableList<ValcuotaModel>
val db = DataBaseHandler(activity!!.applicationContext)
valcuota = db.getCompleteValCuota(spinnerData.selectedItem,"desc")
rcViewValcuota.adapter= ContentValcuotaMonthlyAdapter(valcuota)
我无法从函数 listenItemChange
访问 "root"好的,所以当您从微调器中选择不同的项目时,除非您将数据传递给片段,否则您的片段不会意识到它。因此,为了通知片段,您可以根据需要实现接口。或者我最喜欢的你可以使用 EventBus 库来传递数据。
我将向您展示如何实现 EventBus。
首先,添加EventBus依赖是Gradle文件:
implementation 'org.greenrobot:eventbus:3.1.1'
好的,现在创建一个数据 class 用于传递数据 SpinnerData:
data class SpinnerData(val selectedItem:String)
然后在您的 itemSelected 侦听器中,使用 EventBus 传递数据:
spn.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
// bundle.putString("afp",spn.selectedItem.toString())
//insted add following line
EventBus.getDefault().post(SpinnerData(spn.selectedItem.toString()))
}
override fun onNothingSelected(parent: AdapterView<*>) { }
}
然后在您的 ValcuotaDataFragment 中添加以下内容:
@Subscribe
fun listenItemChange(spinnerData: SpinnerData){
if (spinnerData.selectedItem == "something") {
doSomething()
} else {
doSomethingElse()
}
}
override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}
override fun onStop() {
EventBus.getDefault().unregister(this)
super.onStop()
}
现在,每当您更改微调项时,Evenbus 都会被触发并将数据传递给片段内的订阅方法。
希望这对您有所帮助,如果您遇到问题请告诉我。
编辑:
如果您的片段尚未初始化,这将不起作用。
第一次使用时,请将您的行保留在您的 itemSelected 侦听器中:
bundle.putString("afp",spn.selectedItem.toString())