yachek
yachek

Reputation: 21

ListView show item only after refresh

I started to learn android and one time I faced with problem like it: In my fragment I have editText and ListView. I set standard adapter with ArraList<String> data and saw that ListView show items only after I call the keyboard tapping on editText. I tried to find any information about it on many programming websites but I faced failure.

What kind of problem I have?

My .xml file:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".ui.forMainActivity.searchDish.SearchShopFragment"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/linearLayoutCompat"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginVertical="10dp"
        android:weightSum="5">

        <EditText
            android:id="@+id/for_search_shop"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="4" />

        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:src="@drawable/ic_baseline_search_24" />

    </LinearLayout>

    <LinearLayout

        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <ListView
            android:id="@+id/for_list_of_categories"
            android:layout_width="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:layout_height="match_parent" />
    </LinearLayout>

</LinearLayout>

My fragment file:

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    arrayOfNames = ArrayList()
    db.collection("restaurants")
        .get()
        .addOnSuccessListener { documents ->
            for (document in documents) {
                arrayOfNames.add(document.data["name"].toString())
            }
        }
    val root = inflater.inflate(R.layout.fragment_search_shop, container, false)
    val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, arrayOfNames)
    root.findViewById<ListView>(R.id.for_list_of_categories).adapter = adapter
    return root
}

Upvotes: 1

Views: 104

Answers (1)

Zain
Zain

Reputation: 40888

You need to update the adapter synchronously with data, as the addOnSuccessListener callback get called after you set the adapter, so in below line of code the arrayOfNames list is still empty.

val adapter = ArrayAdapter(requireContext(), 
                           android.R.layout.simple_list_item_1, arrayOfNames)

To fix this you need to either:

Set the adapter within the addOnSuccessListener callback

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    val root = inflater.inflate(R.layout.fragment_search_shop, container, false)
    arrayOfNames = ArrayList()
    db.collection("restaurants")
        .get()
        .addOnSuccessListener { documents ->
            for (document in documents) {
                arrayOfNames.add(document.data["name"].toString())
            }
            val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, arrayOfNames)
            root.findViewById<ListView>(R.id.for_list_of_categories).adapter = adapter
        }
    return root
}

Or adapter.notifyDatasetChanged() within the callback.

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    val root = inflater.inflate(R.layout.fragment_search_shop, container, false)
    val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, arrayOfNames)
    root.findViewById<ListView>(R.id.for_list_of_categories).adapter = adapter
    arrayOfNames = ArrayList()
    db.collection("restaurants")
        .get()
        .addOnSuccessListener { documents ->
            for (document in documents) {
                arrayOfNames.add(document.data["name"].toString())
            }
            adapter.notifyDataSetChanged()
        }
    return root
}

Upvotes: 2

Related Questions