简体   繁体   中英

TextColor of Xamarin.Forms SearchBar

I have a Xamarin.Forms SearchBar on a StackLayout with a dark background color.

By default the input field is dark as well, probably due to a transparent background. To modify the search bar background color there is a BackgroundColor property. (In the example below I set it to dark gray.)

But how to adjust the text color? There is no such property. And even with a custom search bar renderer I don't find a solution.

This is how it looks with just the placeholder:

...and with some input (black "Hello world!" on a pretty dark background):

Here is the code for an Android Custom renderer that will do the trick. I would upload a screenshot, but I don't have enough points yet :(

using System;

using Android.Widget;
using Android.Text;
using G = Android.Graphics;

using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly:ExportRenderer( typeof(MySearchBar), typeof(Some.Namespance.MySearchBar_Droid) )]

namespace Some.Namespace
{
    public class MySearchBar_Droid : SearchBarRenderer
    {
        protected override void OnElementChanged( ElementChangedEventArgs<SearchBar> args )
        {
            base.OnElementChanged( args );

            // Get native control (background set in shared code, but can use SetBackgroundColor here)
            SearchView searchView = (base.Control as SearchView);
            searchView.SetInputType( InputTypes.ClassText | InputTypes.TextVariationNormal );

            // Access search textview within control
            int textViewId = searchView.Context.Resources.GetIdentifier( "android:id/search_src_text", null, null );
            EditText textView = (searchView.FindViewById( textViewId ) as EditText);

            // Set custom colors
            textView.SetBackgroundColor( G.Color.Rgb( 225, 225, 225 ) );
            textView.SetTextColor( G.Color.Rgb( 32, 32, 32 ) );
            textView.SetHintTextColor( G.Color.Rgb( 128, 128, 128 ) );

            // Customize frame color
            int frameId = searchView.Context.Resources.GetIdentifier( "android:id/search_plate", null, null );
            Android.Views.View frameView = (searchView.FindViewById( frameId ) as Android.Views.View);
            frameView.SetBackgroundColor( G.Color.Rgb( 96, 96, 96 ) );
        }
    }
}

You can achieve this by creating a custom View that has a bindable-property like ForegroundTextColor and then create a custom renderer.

In the custom renderer you can inherit from the platform specific renderer, ie on WindowsPhone it is:-

Xamarin.Forms.Platform.WinPhone.SearchBarRenderer

You can then monitor for property changes to the bindable-property you created and set the platform native control Text-color that is used to change the appearance of the non-editing view of the SearchBar .

You also have to monitor for IsFocused and apply the colouring on WindowsPhone , at least, also. This may also apply for other platforms possibly as well.

Update 1:-

========

In reply to your comment you don't have to render the whole SearchBar yourself.

If you inherit from the renderer you are able to customize things finer.

With specific reference to Android to achieve this you have to get reference to AutoCompleteTextView and then you can call SetTextColor to change the color.

Update 2:-

==========

SearchBar is a composite control in Android .

The AutoCompleteTextView is buried rather deep in the hierarchy.

On 4.4 this can be found using the following code. Other versions may well differ. This is by no means a good approach necessarily for production using ordinal indexes however:-

AutoCompleteTextView objAutoTextView = (AutoCompleteTextView)(((this.Control.GetChildAt(0) as ViewGroup).GetChildAt(2) as ViewGroup).GetChildAt(1) as ViewGroup).GetChildAt(0);

Where this is the renderer class.

You can then call objAutoTextView.SetTextColor with the color to achieve the change in color to the SearchBar foreground text.

You can make the following changes in the xaml if you are using xaml to obtain the different text color of search bar on different platforms:

<SearchBar x:Name="Search"
           Placeholder="Search"    
           TextChanged="SearchBar_OnTextChanged"  
           SearchButtonPressed="OnSearch" BackgroundColor="#19588F">
         <SearchBar.TextColor>
             <OnPlatform x:TypeArguments="Color">
                    <OnPlatform.iOS>
                      Black
                    </OnPlatform.iOS>
                    <OnPlatform.Android>
                      White
                    </OnPlatform.Android>
                    <OnPlatform.WinPhone>
                      White
                    </OnPlatform.WinPhone>
             </OnPlatform>
         </SearchBar.TextColor>
 </SearchBar> 

I finally found a very simple solution:

I accidentally used the Android Theme @android:style/Theme.Holo.Light and modified all colors explicitly. But to get a bright text color on a search bar you better use @android:style/Theme.Holo .

It does not allow you to set the color very precisely, but changing it from black to white was all I needed in this case.

Here's how I did it, another way:

[assembly: ExportRenderer(typeof (CustomSearchBar), typeof (CustomSearchBarRenderer))]

namespace Bahai.Android.Renderers 
{
public class CustomSearchBarRenderer : SearchBarRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
    {
        base.OnElementChanged(e);
        if (e.OldElement == null)
        {
            SearchBar element = (SearchBar) this.Element;
            var native = (global::Android.Widget.SearchView) Control;

            // do whatever you want to the controls here!
            //--------------------------------------------
            // element.BackgroundColor = Color.Transparent;
            // native.SetBackgroundColor(element.BackgroundColor.ToAndroid());
            // native.SetBackgroundColor(Color.White.ToAndroid());

            //The text color of the SearchBar / SearchView 
            AutoCompleteTextView textField = (AutoCompleteTextView)
                (((Control.GetChildAt(0) as ViewGroup)
                    .GetChildAt(2) as ViewGroup)
                    .GetChildAt(1) as ViewGroup)
                    .GetChildAt(0);

            if (textField != null)
                textField.SetTextColor(Color.White.ToAndroid());
        }
    }
   }
}

SearchBar has a TextColor property. At least in Xamarin 5.

<SearchBar
        TextColor="Black"
        Text="{Binding SearchString}">

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