A ListView is not displaying any data on OnCreate/OnStart after AndroidX migration

Federico Navarrete 621 Reputation points
2021-04-23T16:53:09.133+00:00

I have an app that is only displaying data until I filter something on a SearchView. Now, in the following example, I'm switching between the Home Activity and the More Sites Activity (where the bug happens).

90853-ezgifcom-gif-maker-3.gif

As you could see when I switched to the More Sites activity and its only ListView stayed empty until I "filtered" something. It's important to highlight that the More Sites Activity used to work properly before I migrated the app to AndroidX.

This is part of my current code:

other_ruins.xml

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:app="http://schemas.android.com/apk/res-auto"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical">  
 <androidx.coordinatorlayout.widget.CoordinatorLayout  
        android:layout_weight="1"  
        android:layout_width="match_parent"  
        android:layout_height="match_parent">  
        <LinearLayout  
            android:layout_width="match_parent"  
            android:layout_height="match_parent"  
            android:orientation="vertical">  
           <include layout="@layout/search_container" />  
            <ListView  
                android:id="@+id/lstOtherRuins"  
                android:layout_margin="8dp"  
                android:layout_height="match_parent"  
                android:layout_width="match_parent"  
                android:choiceMode="singleChoice"  
                android:layout_gravity="left|start" />  
        </LinearLayout>  
    </androidx.coordinatorlayout.widget.CoordinatorLayout>  
    <com.google.android.gms.ads.AdView  
        android:id="@+id/adView"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        app:adSize="SMART_BANNER"  
        app:adUnitId="@string/banner_ad_unit_id" />  
</LinearLayout>  

search_container.xml

<?xml version="1.0" encoding="UTF-8" ?>  
<FrameLayout  
    xmlns:app="http://schemas.android.com/apk/res-auto"  
    xmlns:android="http://schemas.android.com/apk/res/android"  
    android:id="@+id/toolbar_container"  
    android:layout_width="match_parent"  
    android:layout_height="wrap_content">  
  
    <androidx.appcompat.widget.Toolbar  
        android:id="@+id/toolbar"  
        app:theme="@style/ToolBarStyle"  
        android:layout_width="match_parent"  
        android:layout_height="?attr/actionBarSize"  
        android:background="@color/colorPrimary" />  
  
    <com.miguelcatalan.materialsearchview.MaterialSearchView  
        android:id="@+id/search_view"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content" />  
</FrameLayout>  

This is my C# code, and in both cases, I use the UpdateListView method:

protected override void OnStart()  
{  
    base.OnStart();  
  
    UpdateListView(AllRuins);  
}  

private void UpdateListView(List<Row> result)  
{  
    List<IMenuItemsType> item = new();  
  
    string prevCountry = "";  
  
    foreach (var datum in result)  
    {  
        if (datum.Col3 != prevCountry)  
        {  
            prevCountry = datum.Col3;  
            item.Add(new MenuHeaderItem(prevCountry));  
        }  
  
        item.Add(new MenuContentSimpleItem(datum.Col1, datum.Col2, datum.Col3, datum.Col4, datum.Col5));  
    }  
  
    LstOtherRuins.Adapter = new OtherRuinsAdapter(this, item);  
}  

This is the SearchView filter:

public partial class OtherRuinsActivity  
{  
    public class MaterialSearchViewListener : Java.Lang.Object, MaterialSearchView.IOnQueryTextListener  
    {  
        private readonly OtherRuinsActivity OActivity;  
  
        public MaterialSearchViewListener(OtherRuinsActivity oActivity)  
        {  
            OActivity = oActivity;  
        }  
  
        public bool OnQueryTextChange(string p0)  
        {  
            OActivity.CurrentWord = p0;  
            OActivity.UpdateListView(OActivity.AllRuins.Where(x => x.Col1.ToLower().Contains(p0)).ToList());  
  
            return true;  
        }  
  
        public bool OnQueryTextSubmit(string p0)  
        {  
            OActivity.CurrentWord = p0;  
            OActivity.UpdateListView(OActivity.AllRuins.Where(x => x.Col1.ToLower().Contains(p0)).ToList());  
  
            return true;  
        }  
    }  
}  

I already verified and have data:

90797-screen-shot-2021-04-23-at-183449.png

This is my adapter also:

public partial class OtherRuinsAdapter  
{  
    private class OtherRuinsViewHolder : Java.Lang.Object  
    {  
        public TextView LblName { get; set; }  
        public TextView LblLocation { get; set; }  
    }  
}  

public partial class OtherRuinsAdapter : ArrayAdapter<IMenuItemsType>  
{  
    public OtherRuinsAdapter(Context context, List<IMenuItemsType> items) : base(context, 0, items)  
    {  
        Context1 = context;  
        Items = items;  
        Inflater = (LayoutInflater)Context1.GetSystemService(Context.LayoutInflaterService);  
    }  
  
    public override int Count  
    {  
        get  
        {  
            return Items.Count;  
        }  
    }  
  
    public Context Context1 { get; set; }  
    public List<IMenuItemsType> Items { get; set; }  
    public LayoutInflater Inflater { get; set; }  
    public LayoutInflater Inflater1 { get => Inflater; set => Inflater = value; }  
  
    public override long GetItemId(int position)  
    {  
        return position;  
    }  
  
    public override View GetView(int position, View convertView, ViewGroup parent)  
    {  
        var inflater = LayoutInflater.From(parent.Context);  
        OtherRuinsViewHolder holder = null;  
        var view = convertView;  
  
        if (view != null)  
        {  
            holder = view.Tag as OtherRuinsViewHolder;  
        }  
  
        if (holder == null)  
        {  
            holder = new OtherRuinsViewHolder();  
            view = inflater.Inflate(Resource.Layout.other_ruins_list, parent, false);  
            holder.LblName = view.FindViewById<TextView>(Resource.Id.lblName);  
            holder.LblLocation = view.FindViewById<TextView>(Resource.Id.lblLocation);  
            view.Tag = holder;  
        }  
  
        IMenuItemsType item = Items[position];  
        if (item.GetMenuItemsType() == 0)  
        {  
            MenuHeaderItem _headerItem = (MenuHeaderItem)item;  
            view = inflater.Inflate(Resource.Layout.listview_header_item, null);  
            // user dont click header item  
            view.Clickable = false;  
  
            var headerName = view.FindViewById<TextView>(Resource.Id.txtHeader);  
            headerName.Text = _headerItem.HeaderText;  
  
        }  
        else if (item.GetMenuItemsType() == 1)  
        {  
            MenuContentSimpleItem _contentItem = (MenuContentSimpleItem)item;  
  
            if (!string.IsNullOrEmpty(_contentItem.Wiki))  
            {  
                holder.LblName.PaintFlags = PaintFlags.UnderlineText;  
                holder.LblName.SetTextColor(Color.Argb(255, 10, 150, 124));  
                holder.LblName.Click += LblName_Click;  
            }  
            else  
            {  
                holder.LblName.PaintFlags = PaintFlags.AntiAlias;  
                holder.LblName.SetTextColor(Color.Argb(255, 33, 33, 33));  
                holder.LblName.Click -= LblName_Click;  
            }  
  
            if (!string.IsNullOrEmpty(_contentItem.SubScript))  
            {  
                if (Build.VERSION.SdkInt >= BuildVersionCodes.N)  
                    holder.LblName.SetText(Html.FromHtml($"{_contentItem.Title}<sub><small>{_contentItem.SubScript}</small></sub>", FromHtmlOptions.ModeLegacy), BufferType.Spannable);  
                else  
#pragma warning disable CS0618 // Type or member is obsolete  
                    holder.LblName.SetText(Html.FromHtml($"{_contentItem.Title}<sub><small>{_contentItem.SubScript}</small></sub>"), BufferType.Spannable);  
#pragma warning restore CS0618 // Type or member is obsolete  
            }  
            else  
            {  
                holder.LblName.Text = _contentItem.Title;  
            }  
  
            holder.LblLocation.Text = _contentItem.Description;  
            holder.LblLocation.PaintFlags = PaintFlags.UnderlineText;  
            holder.LblLocation.Click += LblLocation_Click;  
        }  
  
        return view;  
    }  
  
    private void LblName_Click(object sender, System.EventArgs e)  
    {  
        Context1.StartActivity(new Intent(Intent.ActionView, Android.Net.Uri.Parse(new XML2CSharp("OtherRuins.xml").FromXml<Book>().Row.Where(x => x.Col1 == ((TextView)sender).Text).FirstOrDefault().Col4)));  
    }  
  
    private void LblLocation_Click(object sender, System.EventArgs e)  
    {  
        Intent mapIntent = new Intent(Intent.ActionView, Android.Net.Uri.Parse($"google.navigation:q={((TextView)sender).Text}, {new XML2CSharp("OtherRuins.xml").FromXml<Book>().Row.Where(x => x.Col2 == ((TextView)sender).Text).FirstOrDefault().Col3}"));  
        mapIntent.SetPackage("com.google.android.apps.maps");  
        Context1.StartActivity(mapIntent);  
    }  
}  
Developer technologies .NET Xamarin
0 comments No comments
{count} votes

Accepted answer
  1. Federico Navarrete 621 Reputation points
    2021-04-25T20:59:14.54+00:00

    Somehow the GetView method was not called because of a LinerLayout that contains the ListView. I re-wrote the Layout and now it works properly.

    other_ruins.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
     <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <include layout="@layout/search_container" />
            <ListView
                android:id="@+id/lstOtherRuins"
                app:layout_behavior="@string/appbar_scrolling_view_behavior"
                android:nestedScrollingEnabled="true"
                android:layout_margin="8dp"
                android:layout_height="match_parent"
                android:layout_width="match_parent"
                android:choiceMode="singleChoice"
                android:layout_below="@id/toolbar_container"
                android:layout_gravity="left|start" />
        </androidx.coordinatorlayout.widget.CoordinatorLayout>
        <com.google.android.gms.ads.AdView
            android:id="@+id/adView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:adSize="SMART_BANNER"
            app:adUnitId="@string/banner_ad_unit_id" />
    </LinearLayout>
    

    Also, I needed to change the container by adding the AppBarLayout because it was being overlapped.

    search_container.xml:

    <?xml version="1.0" encoding="UTF-8" ?>
    <com.google.android.material.appbar.AppBarLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/toolbar_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                app:theme="@style/ToolBarStyle"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@color/colorPrimary" />
    
            <com.miguelcatalan.materialsearchview.MaterialSearchView
                android:id="@+id/search_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </FrameLayout>
    
    </com.google.android.material.appbar.AppBarLayout>
    
    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.