如何在Android中更改分段控件的tintcolor?

时间:2018-03-31 03:21:46

标签: xamarin xamarin.forms xamarin.android

我发现这是为iOS和Android创建SegmentedControl

In the C# back end, how can I select an element in a Segmented Control?

我想以编程方式更改控件的颜色,如下图所示:

enter image description here

所以我添加了以下代码:

在共享代码中

public class SegmentedControl : View, IViewContainer<SegmentedControlOption>
    {
        // Other codes here

        public static readonly BindableProperty TintColorProperty = BindableProperty.Create(nameof(TintColor), typeof(Color), typeof(SegmentedControl), Color.Blue, BindingMode.OneWay);
        public Color TintColor
        {
            get { return (Color)GetValue(TintColorProperty); }
            set { SetValue(TintColorProperty, value); }
        }
        // Other codes here
}

在iOS渲染器中:

public class SegmentedControlRenderer : ViewRenderer<SegmentedControl, UISegmentedControl>
   {
      protected override void OnElementChanged(ElementChangedEventArgs<SegmentedControl> e)
      {
         base.OnElementChanged(e);
         // more codes here

        segmentedControl.TintColor = e.NewElement?.TintColor.ToUIColor();

         // more codes here
      }

      protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
      {
         base.OnElementPropertyChanged(sender, e);

         if (e.PropertyName == SegmentedControl.TintColorProperty.PropertyName)
                SetSegmentTintColor();
      }
      void SetSegmentTintColor()
      {
         if (Element is SegmentedControl formsElement)
                Control.TintColor = formsElement.TintColor.ToUIColor();
      }
   }

在XAML中

<local:SegmentedControl ValueChanged="OnModeChanged" x:Name="segControlMode" HorizontalOptions="End" TintColor="Red" > 
   <local:SegmentedControl.Children>
      <local:SegmentedControlOption Text="Learn" />
      <local:SegmentedControlOption Text="Quiz" />
   </local:SegmentedControl.Children>
</local:SegmentedControl>

正如您在上图中看到的,这适用于iOS,但我不知道如何将此更改应用于Android。任何人都知道如何做到这一点?

1 个答案:

答案 0 :(得分:1)

  

我想要做的是以编程方式更改android中的控件颜色,如上图所示。

您提供的示例通过静态样式设置背景。如果要以编程方式设置颜色,可以按照以下步骤更改示例项目:

  1. df3 = df[df['timestamp'].between(df2['timestamp'].min(), df2['timestamp'].max())] print (df3) Id timestamp 5 285 2017-05-22 11:52:48 中注释掉两行SegmentedControlOption样式,以便它不使用静态资源来设置背景和textcolor:

    Resource/values/styles.xml
  2. <style name="SegmentedControlOption" parent="@android:style/Widget.CompoundButton.RadioButton"> <item name="android:gravity">center</item> <!--<item name="android:background">@drawable/segmented_control_background</item>--> <item name="android:button">@null</item> <!--<item name="android:textColor">@color/segmented_control_text</item>--> <item name="android:layout_width">0dp</item> <item name="android:layout_height">wrap_content</item> <item name="android:layout_weight">1</item> <item name="android:minWidth">85dp</item> <item name="android:minHeight">@dimen/segmented_control_default_height</item> <item name="android:textSize">@dimen/segmented_control_text_size</item> ... 修改为以下代码:

    SegmentedControlRenderer
  3. public class SegmentedControlRenderer : ViewRenderer<SegmentedControl, RadioGroup> { public SegmentedControlRenderer(Context context) : base(context) { } protected override void OnElementChanged(ElementChangedEventArgs<SegmentedControl> e) { base.OnElementChanged(e); RadioGroup nativeControl = null; Android.Graphics.Color themeColor = Android.Graphics.Color.Red; if (e.NewElement != null) { themeColor = e.NewElement.TintColor.ToAndroid(); } if (Control == null) { // Instantiate the native control and assign it to the Control property with the SetNativeControl method var layoutInflater = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService); nativeControl = new RadioGroup(Context) { Orientation = Orientation.Horizontal }; for (var i = 0; i < e.NewElement.Children.Count; i++) { var o = e.NewElement.Children[i]; var v = (SegmentedControlButton)layoutInflater.Inflate(Resource.Layout.SegmentedControl, null); v.Text = o.Text; //Create a shape act as the background of the button v.ThemeColor=themeColor; if (i == 0) { //Specifies radii for each of the 4 corners. For each corner, the array contains 2 values, [X_radius, Y_radius]. //The corners are ordered top-left, top-right, bottom-right, bottom-left. This property is honored only when the shape is of type RECTANGLE. v.ChangeCornerRadius(8,0,0,8); } else if (i == e.NewElement.Children.Count - 1) { v.ChangeCornerRadius(0, 8, 8, 0); } v.CheckedChange += (s, args) => { if (args.IsChecked) { (v.Background as GradientDrawable).SetColor(themeColor); v.SetTextColor(Android.Graphics.Color.White); } else { (v.Background as GradientDrawable).SetColor(Android.Graphics.Color.White); v.SetTextColor(themeColor); } }; //if (i == 0) // v.SetBackgroundResource(Resource.Drawable.segmented_control_first_background); //else if (i == e.NewElement.Children.Count - 1) // v.SetBackgroundResource(Resource.Drawable.segmented_control_last_background); nativeControl.AddView(v); } SetNativeControl(nativeControl); SetSelectedSegment(); } if (e.OldElement != null) { // Unsubscribe from event handlers and cleanup any resources if (nativeControl != null) nativeControl.CheckedChange -= NativeCheckedChanged; } if (e.NewElement != null) { nativeControl.CheckedChange += NativeCheckedChanged; } } protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); if (e.PropertyName == nameof(SegmentedControl.SelectedSegment)) SetSelectedSegment(); } void NativeCheckedChanged(object sender, EventArgs e) { if (Element is SegmentedControl formsElement) { var rg = (RadioGroup)sender; if (rg.CheckedRadioButtonId != -1) { var id = rg.CheckedRadioButtonId; var radioButton = rg.FindViewById(id); var radioIndex = rg.IndexOfChild(radioButton); formsElement.SelectedSegment = radioIndex; } }; } void SetSelectedSegment() { if (Element is SegmentedControl formsElement) { if (formsElement.SelectedSegment >= 0 && formsElement.SelectedSegment < Control.ChildCount) { var radioBtn = (RadioButton)Control.GetChildAt(formsElement.SelectedSegment); radioBtn.Checked = true; } } } } 修改为以下代码:

    SegmentedControlButton