Котлин: связь между разными фрагментами - PullRequest
0 голосов
/ 07 декабря 2018

Я в настоящее время разрабатываю приложение для Android благодаря Kotlin.

Я использую блок навигации и фрагмент по умолчанию.Я хочу сделать что-то вроде этого:

  1. В текущем фрагменте положить некоторые данные в счетчик (готово)
  2. При щелчке текстового представления сохранить данные (извыбранный прядильщик) выбран (почти готов), затем (3)
  3. Перейти к другому фрагменту (готово)
  4. На этом фрагменте создайте прядильщик с некоторыми данными и отправьте их в первый фрагмент (почти готово)
  5. Вставьте новое значение И старый первый фрагмент

Итак, у меня есть два счетчика, а второй (на втором фрагменте) имеет адаптер.

Мой вопрос таков: есть ли способ сделать это проще?Я борюсь со всеми этими связками между фрагментами и адаптером, но я искренне верю, что есть способ более простой, чем то, что я делаю ...

Первый фрагмент:

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val v = inflater.inflate(R.layout.mes_informations, container, false)
        val thisBundle = this.arguments
        if(thisBundle != null){
            val builder = StringBuilder("Extras:\n")
            for (key in thisBundle.keySet()) {
                val value = thisBundle.get(key)
                builder.append(key).append(": ").append(value).append("\n")
            }
            selectedArret.text = thisBundle.get("Arret").toString()
        }

        return v
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val thisBundle = this.arguments

        if(thisBundle != null){
            val builder = StringBuilder("Extras:\n")
            for (key in thisBundle.keySet()) {
                val value = thisBundle.get(key)
                builder.append(key).append(": ").append(value).append("\n")
            }
            Log.i(TAG, builder.toString())
        }

        bundle = Bundle()


        spinnerDepartement.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
                when (position) {
                    position -> departement = bundle.putString("departement", spinnerDepartement.selectedItem.toString())
                    else -> bundle.putString("departement", "Cher")
                }
                Log.i(TAG, spinnerDepartement.selectedItem.toString())
            }

            override fun onNothingSelected(parent: AdapterView<*>) {
            }
        }


        val fragmentTransaction = fragmentManager?.beginTransaction()
        val rechercheFragm = RechercherArret()
        rechercheFragm.arguments = bundle
        ligneReguliereLayout.setOnClickListener {
                fragmentTransaction
                    ?.replace(R.id.content_frame, rechercheFragm)
                    ?.addToBackStack(null)
                    ?.commit()
        }
    }

второй:

   override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)    
        lignes = ArrayList()

        val resultArgument = arguments

        val queryFill = resources.getStringArray(R.array.fillSearchQuery2)
        for(ligne in queryFill){
            lignes.add(ligne)
        }

        adapter = ListAdapterCustom(view.context, R.layout.list_adapter, lignes, resultArgument)

        listSearchView.adapter = adapter

        search.queryHint = "Entrez un arrêt"

        search.setOnQueryTextListener(object : SearchView.OnQueryTextListener {

            override fun onQueryTextChange(newText: String): Boolean {
                adapter.filter.filter(newText.trim())
                if(newText.trim() != ""){
                    listSearchView.visibility = View.VISIBLE
                }else{
                    listSearchView.visibility = View.GONE
                }
                return false
            }

            override fun onQueryTextSubmit(query: String): Boolean {
                Toast.makeText(view.context, "Submit $query", Toast.LENGTH_SHORT).show()
                return false
            }

        })
    }

и адаптер:

class ListAdapterCustom(context: Context, resource: Int, list: ArrayList<String>, private val arguments: Bundle?) : ArrayAdapter<String>(context, resource, list) {


override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
    val view = super.getView(position, convertView, parent)

    val thisBundle = arguments
    if(thisBundle != null){
        val builder = StringBuilder("Extras:\n")
        for (key in thisBundle.keySet()) {
            val value = thisBundle.get(key)
            builder.append(key).append(": ").append(value).append("\n")
        }
        Log.i("Extras", builder.toString())
    }

    val arret = view.findViewById<TextView>(R.id.arret)

    arret.setOnClickListener {
        val fragment = MesInformations()
        val bundle = Bundle()
        bundle.putString("Arret", arret.text.toString())
        fragment.arguments = bundle

        Snackbar.make(view, arret.text, Snackbar.LENGTH_SHORT).show()

        val fragmentManager = (context as AppCompatActivity).supportFragmentManager
        val fragmentTransaction = fragmentManager.beginTransaction()

        fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack(null)
        fragmentTransaction.commit()
        fragmentTransaction.addToBackStack(null)
    }

    if (position % 2 == 1) {
        view.setBackgroundResource(R.color.colorWhite)
    } else {
        view.setBackgroundResource(R.color.grayBackground)
    }
    return view
}

}

1 Ответ

0 голосов
/ 07 декабря 2018

Вы можете создать общий ViewModel для связи между фрагментами.Создайте ViewModel и получите к ним доступ, используя контекст хостинга Activity внутри каждого из фрагментов.

Вот пример , скопированный из документации ViewModel здесь: https://developer.android.com/topic/libraries/architecture/viewmodel

class SharedViewModel : ViewModel() {
    val selected = MutableLiveData<Item>()

    fun select(item: Item) {
        selected.value = item
    }
}

class MasterFragment : Fragment() {

    private lateinit var itemSelector: Selector

    private lateinit var model: SharedViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        model = activity?.run {
            ViewModelProviders.of(this).get(SharedViewModel::class.java)
        } ?: throw Exception("Invalid Activity")

        itemSelector.setOnClickListener { item ->
            model.select(item)  // <-- This will notify the `DetailFragment`
        }
    }
}

class DetailFragment : Fragment() {

    private lateinit var model: SharedViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        model = activity?.run {
            ViewModelProviders.of(this).get(SharedViewModel::class.java)
        } ?: throw Exception("Invalid Activity")

        model.selected.observe(this, Observer<Item> { item ->
            // Update the UI
        })
    }
}

Здесь к SharedViewModel обращаются как в MasterFragment, так и вDetailFragment.Оба получают доступ к одному и тому же экземпляру SharedViewModel, потому что оба они обращаются к ViewModel из контекста Activity:

ViewModelProviders.of(*ACTIVITY*).get(SharedViewModel::class.java)

Теперь вы можете включить LiveData в SharedViewModel иоба фрагмента могут прослушивать / обновлять их, что в конечном итоге отражается и на другом фрагменте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...