3

I have an Activity with two child fragments Timeline and Milestones. Both these fragments contain listviews populated by a custom Cursor adapter

Here is a graphical Representation: enter image description here

Now when I am on TIMELINE and I open up the searchview, I type something all is good I get the desired result. But when I navigate from Timeline to Milestones with some text in the searchview the searchview does not get cleared, so I get filtered results on the Milestones page too and acccording to the paramaters I provided in Timeline.

I am using AppCompact lib to develop my ActionBar. The tabs in there are not ActionBar Tabs but simple SlidingTabLayout.

So far I have tried using

getActivity().supportInvalidateOptionsMenu(); in onResume() of both the fragments, does not work.

I have tried searchView.setQuery("",false) - does not work and randomly gives me a NPE.

SO what do I miss here?

Skynet
  • 7,820
  • 5
  • 44
  • 80

1 Answers1

0

You can take a look on my example, where I showed how to control searchView between fragments.

Firstly. You need to create BaseFragment, which works with context of activity with appBarLayout.

open class BaseFragment: Fragment() {
    lateinit var rootActivity: MainActivity
    lateinit var appBarLayout: AppBarLayout
    lateinit var searchView: androidx.appcompat.widget.SearchView

    override fun onAttach(context: Context) {
        super.onAttach(context)

        this.rootActivity = context as MainActivity
        appBarLayout = rootActivity.findViewById(R.id.app_bar_layout)
        searchView = rootActivity.findViewById(R.id.search_input)
    }

    override fun onResume() {
        super.onResume()

        resetAppBarLayout()
    }

    private fun resetAppBarLayout() {
        appBarLayout.elevation = 14f
    }

    fun setupSearch(query: String) {
        searchView.visibility = View.VISIBLE
        searchView.clearFocus()
        when(query.isNotEmpty()) {
            true -> {
                searchView.setQuery(query, true)
                searchView.isIconified = false
            }
            false -> {
                searchView.isIconified = true
                searchView.isIconified = true
            }
        }
    }

    fun hideSearchKeyboard() {
        context?.let {
            KeyboardHelper.hideSearchKeyboard(it, searchView.findViewById(R.id.search_src_text))
        }
    }

    fun hideSearch() {
        searchView.visibility = View.GONE
        searchView.clearFocus()
    }
}

Secondly. Inherit your fragments from BaseFragment, override onResume() method and control searchView in your fragments by calling methods from BaseFragment. Something like this.

class FragmentA : BaseFragment() {
    private var searchQuery = ""

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val root = inflater.inflate(R.layout.fragment, container, false)
        val textView: TextView = root.findViewById(R.id.textView)
        textView.text = "Fragment A"
        return root
    }

    override fun onResume() {
        super.onResume()

        setupSearch()
    }

    private fun setupSearch() {
        searchView.setOnQueryTextListener(object : androidx.appcompat.widget.SearchView.OnQueryTextListener {
            override fun onQueryTextChange(newText: String?): Boolean {
                when(newText.isNullOrEmpty()) {
                    true -> searchQuery = ""
                    false -> searchQuery = newText
                }
                return true
            }

            override fun onQueryTextSubmit(query: String?): Boolean {
                hideSearchKeyboard()
                return true
            }
        })

        super.setupSearch(searchQuery)
    }
}

Full example you can find here https://github.com/yellow-cap/android-manage-searchview