Kotlin: spinner onItemSelectedListener из другого фрагмента - PullRequest
0 голосов
/ 10 ноября 2019

у меня есть фрагмент с 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
}
}
1005 * Я передаю новому фрагменту значение «afp» через Bundle, теперь мне нужно, чтобы новый фрагмент сделал что-то другое, в зависимости от того, что я выбрал в счетчике ValcuotaEvolFragment

это то, что мне нужно:

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

EDIT

Решение EventBus работает нормально, но теперь у меня есть новая проблема в ValcuotaDataFragment, у меня есть RecyclerView, поэтому теперь мне нужно заполнить RecyclerView после изменения элемента в Spinner, вот как я это делаю сейчас:

    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

1 Ответ

0 голосов
/ 10 ноября 2019

Хорошо, поэтому, когда вы выбираете другой элемент из счетчика, ваш фрагмент не узнает об этом, пока вы не передадите данные во фрагмент. Так что для информирования фрагмента вы можете реализовать интерфейс, если хотите. Или мой любимый, вы можете использовать библиотеку EventBus для передачи данных.

Я покажу вам, как вы можете реализовать EventBus.

Во-первых, добавьте EventBus Dependency в файл Gradle:

implementation 'org.greenrobot:eventbus:3.1.1'

Хорошо, теперь создайте класс данных для передачи данных, скажем 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 будет запускаться и передавать данные методу Subscribeed внутри вашего фрагмента.

Надеюсь, это поможет, позвольте мнезнать, если вы застряли где-то.

Редактировать:

Это не будет работать, если ваш фрагмент еще не инициализирован.

Так что держите свою линию внутри вашего элемента. Выбранный слушатель для первого использования:

bundle.putString("afp",spn.selectedItem.toString())
...