Search code examples
androidlistviewandroid-arrayadapter

ListView - stretch single item across the whole ListView height


If I have a single item in an ArrayAdapter on a ListView, I would like to stretch that one item all over the ListView height (so I have the text of the one item in the center of the screen).

Like this:

enter image description here

This is really easily done with RecyclerView (the image above) but in my case I can't afford rebuilding ListView screens on RecyclerView now. I tried setting the height of the layout item to the screen height "match_parent" or in code, overriding the 80dp value. It didn't have any impact on my situation, the result looked like this:

enter image description here

this is how I am creating the ArrayAdapter:

string[] noResultsItem = { Resources.GetString(Resource.String.no_network) };
playlistListView.Adapter = new ArrayAdapter<string>(this, Resource.Layout.no_result_row, Resource.Id.textTop, noResultsItem);

This is the layout for the ArrayAdapter item:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    android:id="@+id/noResultsRow">
    <TextView
        android:id="@+id/textTop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textSize="18dip"
        android:textColor="#ffffff"
        android:text=""
        android:gravity="center_horizontal" />
</RelativeLayout>

I can imagine a solution with hiding and showing the ListView and replacing it with a TextView that would be centered but I don't like that solution that much.


Solution

  • Solved by creating my own simple adapter for one item:

    public class SingleItemAdapter : BaseAdapter
    {
        private readonly Context context;
        private readonly ListView listView;
        private readonly int textViewResourceId;
        private readonly int resource;
        private readonly int textResourceId;
    
        public SingleItemAdapter(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) { }
    
        public SingleItemAdapter(Context context, ListView listView, int resource, int textViewResourceId, int textResourceId)
        {
            this.context = context;
            this.textViewResourceId = textViewResourceId;
            this.resource = resource;
            this.textResourceId = textResourceId;
            this.listView = listView;
    
            listView.SetSelector(Android.Resource.Color.Transparent);
            listView.CacheColorHint = Android.Graphics.Color.Transparent;
        }
    
        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            if (convertView == null)
            {
                var inflater = LayoutInflater.From(context);
                var view = inflater.Inflate(resource, parent, false);
                return CustomizeView(view);
            }
            else
            {
                return CustomizeView(convertView);
            }
        }
    
        private View CustomizeView(View view)
        {
            view.LayoutParameters.Height = listView.Height;
            var textTop = view.FindViewById<TextView>(textViewResourceId);
            textTop.Text = context.GetString(textResourceId);
            return view;
        }
    
        public override Object GetItem(int position)
        {
            return context.GetString(textResourceId);
        }
    
        public override long GetItemId(int position)
        {
            return textResourceId;
        }
    
        public override int Count => 1;
    }
    

    This is the updated layout of the item that's being contained in the adapter:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:gravity="center_horizontal|center_vertical"
        android:id="@+id/noResultsRow"
        android:orientation="vertical">
        <TextView
            android:id="@+id/textTop"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:textSize="18dip"
            android:textColor="#ffffff"
            android:text=""
            android:gravity="center" />
    </LinearLayout>