Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Commit 91d30c9

Browse files
jfversluisandreinitescurmarinho
authored
RadioButton Implementation (#8910) fixes #2404 closes #5349
* RadioButton * Removed unused files * Rebase and make it run * First round of feedback * Revert AppCompatButton -> AButton * Cleaned minor usings * Fix unselecting radiobutton on iOS * Fixed Mac OS grouping * [Android] Fix API29 usages Co-authored-by: Andrei Nitescu <[email protected]> Co-authored-by: Rui Marinho <[email protected]>
1 parent 758bdd3 commit 91d30c9

File tree

26 files changed

+1835
-12
lines changed

26 files changed

+1835
-12
lines changed

Stubs/Xamarin.Forms.Platform.cs

+7
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ internal class _ButtonRenderer { }
5454
[RenderWith(typeof(ImageButtonRenderer))]
5555
internal class _ImageButtonRenderer { }
5656

57+
#if __ANDROID__
58+
[RenderWith(typeof(RadioButtonRenderer))]
59+
#elif !TIZEN4_0
60+
[RenderWith(typeof(RadioButtonRenderer))]
61+
#endif
62+
internal class _RadioButtonRenderer { }
63+
5764
[RenderWith (typeof (TableViewRenderer))]
5865
internal class _TableViewRenderer { }
5966

Loading
Loading

Xamarin.Forms.ControlGallery.Android/Xamarin.Forms.ControlGallery.Android.csproj

+7-1
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,12 @@
394394
<ItemGroup>
395395
<LinkDescription Include="LinkDescription.xml" />
396396
</ItemGroup>
397+
<ItemGroup>
398+
<AndroidResource Include="Resources\drawable\rb_unchecked.png" />
399+
</ItemGroup>
400+
<ItemGroup>
401+
<AndroidResource Include="Resources\drawable\rb_checked.png" />
402+
</ItemGroup>
397403
<ItemGroup>
398404
<AndroidAsset Include="Assets\googlemap.html" />
399405
</ItemGroup>
@@ -408,4 +414,4 @@
408414
</CreateItem>
409415
<Copy SourceFiles="@(MapsKey)" DestinationFiles="Properties\MapsKey.cs" Condition="!Exists('Properties\MapsKey.cs')" />
410416
</Target>
411-
</Project>
417+
</Project>

Xamarin.Forms.Controls/CoreGallery.cs

+2
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,8 @@ public override string ToString()
291291
new GalleryPageFactory(() => new EmbeddedFonts(), "Embedded Fonts"),
292292
new GalleryPageFactory(() => new MemoryLeakGallery(), "Memory Leak"),
293293
new GalleryPageFactory(() => new Issues.A11yTabIndex(), "Accessibility TabIndex"),
294+
new GalleryPageFactory(() => new RadioButtonGroupGalleryPage(), "RadioButton group Gallery - Legacy"),
295+
new GalleryPageFactory(() => new RadioButtonCoreGalleryPage(), "RadioButton Gallery"),
294296
new GalleryPageFactory(() => new FontImageSourceGallery(), "Font ImageSource"),
295297
new GalleryPageFactory(() => new IndicatorsSample(), "Indicator Gallery"),
296298
new GalleryPageFactory(() => new CarouselViewGallery(), "CarouselView Gallery"),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
using Xamarin.Forms.CustomAttributes;
2+
3+
namespace Xamarin.Forms.Controls
4+
{
5+
class RadioButtonCoreGalleryPage : CoreGalleryPage<RadioButton>
6+
{
7+
protected override bool SupportsFocus => false;
8+
protected override bool SupportsTapGestureRecognizer => true;
9+
protected override void InitializeElement(RadioButton element)
10+
{
11+
element.Text = "RadioButton";
12+
}
13+
14+
protected override void Build(StackLayout stackLayout)
15+
{
16+
base.Build(stackLayout);
17+
18+
IsEnabledStateViewContainer.View.Clicked += (sender, args) => IsEnabledStateViewContainer.TitleLabel.Text += " (Tapped)";
19+
20+
var borderButtonContainer = new ViewContainer<RadioButton>(Test.Button.BorderColor,
21+
new RadioButton
22+
{
23+
Text = "BorderColor",
24+
BackgroundColor = Color.Transparent,
25+
BorderColor = Color.Red,
26+
BorderWidth = 1,
27+
}
28+
);
29+
30+
var borderRadiusContainer = new ViewContainer<RadioButton>(Test.Button.BorderRadius,
31+
new RadioButton
32+
{
33+
Text = "BorderRadius",
34+
BackgroundColor = Color.Transparent,
35+
BorderColor = Color.Red,
36+
BorderWidth = 1,
37+
}
38+
);
39+
40+
var borderWidthContainer = new ViewContainer<RadioButton>(Test.Button.BorderWidth,
41+
new RadioButton
42+
{
43+
Text = "BorderWidth",
44+
BackgroundColor = Color.Transparent,
45+
BorderColor = Color.Red,
46+
BorderWidth = 15,
47+
}
48+
);
49+
50+
var clickedContainer = new EventViewContainer<RadioButton>(Test.Button.Clicked,
51+
new RadioButton
52+
{
53+
Text = "Clicked"
54+
}
55+
);
56+
clickedContainer.View.Clicked += (sender, args) => clickedContainer.EventFired();
57+
58+
var pressedContainer = new EventViewContainer<RadioButton>(Test.Button.Pressed,
59+
new RadioButton
60+
{
61+
Text = "Pressed"
62+
}
63+
);
64+
pressedContainer.View.Pressed += (sender, args) => pressedContainer.EventFired();
65+
66+
var commandContainer = new ViewContainer<RadioButton>(Test.Button.Command,
67+
new RadioButton
68+
{
69+
Text = "Command",
70+
Command = new Command(() => DisplayActionSheet("Hello Command", "Cancel", "Destroy"))
71+
}
72+
);
73+
74+
var fontContainer = new ViewContainer<RadioButton>(Test.Button.Font,
75+
new RadioButton
76+
{
77+
Text = "Font",
78+
Font = Font.SystemFontOfSize(NamedSize.Large, FontAttributes.Bold)
79+
}
80+
);
81+
82+
var textContainer = new ViewContainer<RadioButton>(Test.Button.Text,
83+
new RadioButton
84+
{
85+
Text = "Text"
86+
}
87+
);
88+
89+
var textColorContainer = new ViewContainer<RadioButton>(Test.Button.TextColor,
90+
new RadioButton
91+
{
92+
Text = "TextColor",
93+
TextColor = Color.Pink
94+
}
95+
);
96+
97+
var paddingContainer = new ViewContainer<RadioButton>(Test.Button.Padding,
98+
new RadioButton
99+
{
100+
Text = "Padding",
101+
BackgroundColor = Color.Red,
102+
Padding = new Thickness(20, 30, 60, 15)
103+
}
104+
);
105+
106+
var isCheckedContainer = new ValueViewContainer<RadioButton>(Test.RadioButton.IsChecked, new RadioButton() { IsChecked = true, HorizontalOptions = LayoutOptions.Start }, "IsChecked", value => value.ToString());
107+
108+
var checkedVisualState = new VisualState { Name = "IsChecked" };
109+
checkedVisualState.Setters.Add(new Setter { Property = RadioButton.ButtonSourceProperty, Value = "rb_checked" });
110+
111+
var group = new VisualStateGroup();
112+
group.States.Add(checkedVisualState);
113+
114+
var normalVisualState = new VisualState{ Name = "Normal" };
115+
normalVisualState.Setters.Add(new Setter { Property = RadioButton.ButtonSourceProperty, Value = "rb_unchecked" });
116+
group.States.Add(normalVisualState);
117+
118+
var groupList = new VisualStateGroupList();
119+
groupList.Add(group);
120+
121+
var rbStateManaged = new RadioButton() { HorizontalOptions = LayoutOptions.Start };
122+
VisualStateManager.SetVisualStateGroups(rbStateManaged, groupList);
123+
124+
var stateManagedContainer = new ValueViewContainer<RadioButton>(Test.RadioButton.ButtonSource, rbStateManaged, "IsChecked", value => value.ToString());
125+
126+
Add(borderButtonContainer);
127+
Add(borderRadiusContainer);
128+
Add(borderWidthContainer);
129+
Add(clickedContainer);
130+
Add(pressedContainer);
131+
Add(commandContainer);
132+
Add(fontContainer);
133+
Add(textContainer);
134+
Add(textColorContainer);
135+
Add(paddingContainer);
136+
Add(isCheckedContainer);
137+
Add(stateManagedContainer);
138+
}
139+
}
140+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
4+
x:Class="Xamarin.Forms.Controls.GalleryPages.RadioButtonGroupGalleryPage">
5+
<TabbedPage.Resources>
6+
<ResourceDictionary>
7+
<DataTemplate x:Key="NoGroupNameLVItemTemplate">
8+
<ViewCell>
9+
<RadioButton Text="RadioButton, Group=null"/>
10+
</ViewCell>
11+
</DataTemplate>
12+
<DataTemplate x:Key="GroupNameLVItemTemplate">
13+
<ViewCell>
14+
<RadioButton GroupName="A" Text="RadioButton, Group='A'"/>
15+
</ViewCell>
16+
</DataTemplate>
17+
<ControlTemplate x:Key="NoGroupNameControlTemplate">
18+
<ContentPresenter />
19+
</ControlTemplate>
20+
<ControlTemplate x:Key="GroupNameControlTemplate">
21+
<ContentPresenter />
22+
</ControlTemplate>
23+
</ResourceDictionary>
24+
</TabbedPage.Resources>
25+
<ContentPage Title="Parent level">
26+
<ScrollView>
27+
<StackLayout Padding="10">
28+
<Label Text="Radio buttons with no group name are mutually exclusive at parent level"
29+
Margin="0, 0, 0, 10"/>
30+
<Label Text="StackLayout" />
31+
<StackLayout>
32+
<RadioButton Text="RadioButton, Group=null" />
33+
<RadioButton Text="RadioButton, Group=null"/>
34+
<RadioButton Text="RadioButton, Group=null"/>
35+
</StackLayout>
36+
<Label Text="StackLayout" Margin="0, 10"/>
37+
<StackLayout>
38+
<RadioButton Text="RadioButton, Group=null" />
39+
<RadioButton Text="RadioButton, Group=null" />
40+
<RadioButton Text="RadioButton, Group=null" />
41+
</StackLayout>
42+
<Label Text="ScrollView" />
43+
<ScrollView>
44+
<RadioButton Text="RadioButton, Group=null" />
45+
</ScrollView>
46+
<Label Text="ContentView" />
47+
<ContentView>
48+
<RadioButton Text="RadioButton, Group=null" />
49+
</ContentView>
50+
<Label Text="Frame" />
51+
<Frame>
52+
<RadioButton Text="RadioButton, Group=null" />
53+
</Frame>
54+
<Label Text="ContentView with ControlTemplate" />
55+
<ContentView ControlTemplate="{StaticResource NoGroupNameControlTemplate}">
56+
<RadioButton Text="RadioButton, Group=null" />
57+
</ContentView>
58+
<Label Text="ListView with ItemTemplate" />
59+
<ListView ItemTemplate="{StaticResource NoGroupNameLVItemTemplate}"
60+
VerticalOptions="Start"
61+
HeightRequest="300">
62+
<ListView.ItemsSource>
63+
<x:Array Type="{x:Type x:String}">
64+
<x:String>mono</x:String>
65+
<x:String>monodroid</x:String>
66+
<x:String>monotouch</x:String>
67+
</x:Array>
68+
</ListView.ItemsSource>
69+
</ListView>
70+
</StackLayout>
71+
</ScrollView>
72+
</ContentPage>
73+
74+
<ContentPage Title="Page level">
75+
<ScrollView>
76+
<StackLayout Padding="10">
77+
<Label Text="Radio buttons with same group name are mutually exclusive at page level"
78+
Margin="0, 0, 0, 10"/>
79+
<Label Text="StackLayout" />
80+
<StackLayout>
81+
<RadioButton GroupName="A" Text="RadioButton, Group='A'" />
82+
<RadioButton GroupName="A" Text="RadioButton, Group='A'"/>
83+
<RadioButton GroupName="A" Text="RadioButton, Group='A'"/>
84+
</StackLayout>
85+
<Label Text="StackLayout" Margin="0, 10"/>
86+
<StackLayout>
87+
<RadioButton GroupName="A" Text="RadioButton, Group='A'" />
88+
<RadioButton GroupName="A" Text="RadioButton, Group='A'" />
89+
<RadioButton GroupName="A" Text="RadioButton, Group='A'" />
90+
</StackLayout>
91+
<Label Text="ScrollView" />
92+
<ScrollView>
93+
<RadioButton GroupName="A" Text="RadioButton, Group='A'" />
94+
</ScrollView>
95+
<Label Text="ContentView" />
96+
<ContentView>
97+
<RadioButton GroupName="A" Text="RadioButton, Group='A'" />
98+
</ContentView>
99+
<Label Text="Frame" />
100+
<Frame>
101+
<RadioButton GroupName="A" Text="RadioButton, Group='A'" />
102+
</Frame>
103+
<Label Text="ContentView with ControlTemplate" />
104+
<ContentView ControlTemplate="{StaticResource GroupNameControlTemplate}">
105+
<RadioButton GroupName="A" Text="RadioButton, Group='A'" />
106+
</ContentView>
107+
<Label Text="ListView with ItemTemplate" />
108+
<ListView ItemTemplate="{StaticResource GroupNameLVItemTemplate}"
109+
VerticalOptions="Start"
110+
HeightRequest="300">
111+
<ListView.ItemsSource>
112+
<x:Array Type="{x:Type x:String}">
113+
<x:String>mono</x:String>
114+
<x:String>monodroid</x:String>
115+
<x:String>monotouch</x:String>
116+
</x:Array>
117+
</ListView.ItemsSource>
118+
</ListView>
119+
</StackLayout>
120+
</ScrollView>
121+
</ContentPage>
122+
123+
<ContentPage Title="Test">
124+
<ScrollView>
125+
<StackLayout Padding="10">
126+
<Label Text="Test with radio buttons with no group name or same group name"
127+
Margin="0, 0, 0, 10"/>
128+
<Label Text="StackLayout" />
129+
<StackLayout>
130+
<RadioButton GroupName="A" Text="RadioButton, GroupName='A'" />
131+
<RadioButton GroupName="A" Text="RadioButton, GroupName='A'" />
132+
<RadioButton Text="RadioButton, GroupName=null" />
133+
</StackLayout>
134+
<StackLayout Margin="0, 10">
135+
<RadioButton GroupName="A" Text="RadioButton, GroupName='A'" />
136+
<RadioButton GroupName="B" Text="RadioButton, GroupName='B'" />
137+
<RadioButton GroupName="B" Text="RadioButton, GroupName='B'" />
138+
<RadioButton Text="RadioButton, GroupName=null" />
139+
</StackLayout>
140+
<StackLayout>
141+
<RadioButton GroupName="A" Text="RadioButton, GroupName='A'" />
142+
<RadioButton GroupName="B" Text="RadioButton, GroupName='B'" />
143+
<RadioButton GroupName="C" Text="RadioButton, GroupName='C'" />
144+
<RadioButton GroupName="C" Text="RadioButton, GroupName='C'" />
145+
<RadioButton Text="RadioButton, GroupName=null" />
146+
<RadioButton Text="RadioButton, GroupName=null" />
147+
</StackLayout>
148+
</StackLayout>
149+
</ScrollView>
150+
</ContentPage>
151+
</TabbedPage>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using Xamarin.Forms.Xaml;
2+
3+
namespace Xamarin.Forms.Controls.GalleryPages
4+
{
5+
[XamlCompilation(XamlCompilationOptions.Compile)]
6+
public partial class RadioButtonGroupGalleryPage : TabbedPage
7+
{
8+
public RadioButtonGroupGalleryPage()
9+
{
10+
InitializeComponent();
11+
}
12+
}
13+
}

Xamarin.Forms.Controls/Xamarin.Forms.Controls.csproj

+5
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@
6060
<Generator></Generator>
6161
</EmbeddedResource>
6262
</ItemGroup>
63+
<ItemGroup>
64+
<EmbeddedResource Update="GalleryPages\RadioButtonGroupGalleryPage.xaml">
65+
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
66+
</EmbeddedResource>
67+
</ItemGroup>
6368

6469
<ItemGroup>
6570
<Folder Include="Fonts\" />

0 commit comments

Comments
 (0)