简体   繁体   中英

Xamarin Forms: How to change the background color of the Picker Controls popup in Android

I cannot figure out how to change the background or the buttons on the popup that appears on the Picker control. I have created a custom renderer that is able to change a lot of the fields I couldn't access for some reason via a style. But where the details for the background of the popup itself and the buttons at the bottom remain elusive. Anyone have a solution? Ideally how to do this in either a style or custom renderer since I've figured out how to plug those into my theming service?

Here's the core of my logic so far inside the custom renderer:

var xamarinSelectedColor = (Color)Application.Current.Resources["SelectedColor"];
var androidSelectedColor = xamarinSelectedColor.ToAndroid();

Control.SetHighlightColor(androidSelectedColor);
Control.BackgroundTintList = ColorStateList.ValueOf(androidSelectedColor);

var xamarinTextOnBackgroundColor = (Color)Application.Current.Resources["TextColorOverBackground"];
var androidTextOnBackgroundColor = xamarinTextOnBackgroundColor.ToAndroid();

Control.SetTextColor(androidTextOnBackgroundColor);

You could look at Renderer Base Classes and Native Controls ,in fact, your Control here is equivalent to EditText on Android, so it won't work if you change Control directly.

You need to define a custom Dialog in your custom renderer.

For example:

public class AndroidPickerRenderer : PickerRenderer
{
    private Context context;
    AlertDialog listDialog;
    string[] items;
    Color xamarinSelectedColor;
    Color xamarinTextOnBackgroundColor;
    public AndroidPickerRenderer(Context context) : base(context)
    {
        this.context = context;
    }
    protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
    {
        base.OnElementChanged(e);
        xamarinSelectedColor = (Color)Application.Current.Resources["SelectedColor"];
        xamarinTextOnBackgroundColor = (Color)Application.Current.Resources["TextColorOverBackground"];
         
        if (Control != null)
        {
            Control.Click += Control_Click;
        }
    }

    private void Control_Click(object sender, EventArgs e)
    {
        Picker model = Element;
        items = model.Items.ToArray();
        AlertDialog.Builder builder =
       new AlertDialog.Builder(context);
        builder.SetTitle(model.Title ?? "");
        builder.SetNegativeButton("Cancel", (s, a) =>
        {
            Control?.ClearFocus();
            builder = null;
        });
        Android.Views.View view = LayoutInflater.From(context).Inflate(Resource.Layout.listview, null);
        Android.Widget.ListView listView = view.FindViewById<Android.Widget.ListView>(Resource.Id.listView1);

        MyAdapter myAdapter = new MyAdapter(items, Element.SelectedIndex);
        listView.Adapter = myAdapter;
        listView.ItemClick += ListView_ItemClick;
        builder.SetView(view);
        listDialog = builder.Create();
        listDialog.Window.DecorView.SetBackgroundColor(xamarinSelectedColor.ToAndroid()); // set the dialog background color
        listDialog.Show();
        Android.Widget.Button button = listDialog.GetButton((int)DialogButtonType.Negative);
        button.SetTextColor(xamarinTextOnBackgroundColor.ToAndroid()); // set the button bottom color
    }

    private void ListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
    {
        Control.Text = items[e.Position];
        Element.SelectedIndex = e.Position;
        listDialog.Dismiss();
        listDialog = null;
    }

    class MyAdapter : BaseAdapter
    {
        private string[] items;
        private int selectedIndex;

        public MyAdapter(string[] items)
        {
            this.items = items;
        }

        public MyAdapter(string[] items, int selectedIndex) : this(items)
        {
            this.selectedIndex = selectedIndex;
        }

        public override int Count => items.Length;

        public override Java.Lang.Object GetItem(int position)
        {
            return items[position];
        }

        public override long GetItemId(int position)
        {
            return position;
        }

        public override Android.Views.View GetView(int position, Android.Views.View convertView, ViewGroup parent)
        {
            if (convertView == null)
            {
                convertView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.listview_item, null);
            }
            TextView textView = convertView.FindViewById<TextView>(Resource.Id.textView1);
            textView.Text = items[position];
            return convertView;
        }
    }
}

listview.xml (creat in your Resources/layout in android project):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
       android:id="@+id/listView1"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"/>


</LinearLayout>

listview_item.xml (creat in your Resources/layout in android project,you could define the style by yourself):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
   <TextView
      android:id="@+id/textView1"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"/>
</LinearLayout>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM