一个好老好老的老程序员了。
全部博文(915)
分类: Android平台
2018-06-18 21:15:44
使用ID区分视图
在TwoButtons程序中,您看到了一种共享事件处理程序的技术,通过比较对象来区分视图。 这在没有很多视图可以区分的情况下工作正常,但对于计算器程序来说这是一个糟糕的做法。
Element类定义了一个String类型的StyleId属性,专门用于识别视图。 它不用于Xamarin.Forms内部的任何东西,所以您可以将其设置为适用于应用程序的任何内容。 您可以使用if和else语句或在开关和大小写块中测试值,也可以使用Parse方法将字符串转换为数字或枚举成员。
以下程序不是计算器,而是一个数字键盘,它当然是计算器的一部分。 该程序被称为SimplestKeypad,并使用StackLayout来组织键的行和列。 (这个程序的目的之一就是要证明StackLayout对于这项工作来说不是很合适的工具!)
该程序总共创建五个StackLayout实例。 mainStack是垂直定向的,并且四个水平的StackLayout对象排列了10个数字按钮。 为了简单起见,键盘按电话顺序排列,而不是按计算器顺序排列:
public class SimplestKeypadPage : ContentPage { Label displayLabel; Button backspaceButton; public SimplestKeypadPage() { // Create a vertical stack for the entire keypad. StackLayout mainStack = new StackLayout { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }; // First row is the Label. displayLabel = new Label { FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)), VerticalOptions = LayoutOptions.Center, HorizontalTextAlignment = TextAlignment.End }; mainStack.Children.Add(displayLabel); // Second row is the backspace Button. backspaceButton = new Button { Text = "\u21E6", FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Button)), IsEnabled = false }; backspaceButton.Clicked += OnBackspaceButtonClicked; mainStack.Children.Add(backspaceButton); // Now do the 10 number keys. StackLayout rowStack = null; for (int num = 1; num <= 10; num++) { if ((num - 1) % 3 == 0) { rowStack = new StackLayout { Orientation = StackOrientation.Horizontal }; mainStack.Children.Add(rowStack); } Button digitButton = new Button { Text = (num % 10).ToString(), FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Button)), StyleId = (num % 10).ToString() }; digitButton.Clicked += OnDigitButtonClicked; // For the zero button, expand to fill horizontally. if (num == 10) { digitButton.HorizontalOptions = LayoutOptions.FillAndExpand; } rowStack.Children.Add(digitButton); } this.Content = mainStack; } void OnDigitButtonClicked(object sender, EventArgs args) { Button button = (Button)sender; displayLabel.Text += (string)button.StyleId; backspaceButton.IsEnabled = true; } void OnBackspaceButtonClicked(object sender, EventArgs args) { string text = displayLabel.Text; displayLabel.Text = text.Substring(0, text.Length - 1); backspaceButton.IsEnabled = displayLabel.Text.Length > 0; } }
这10个数字键共享一个Clicked处理程序。 StyleId属性表示与键关联的数字,因此程序可以简单地将该数字附加到由标签显示的字符串。 StyleId恰好与Button的Text属性相同,并且可以使用Text属性来代替,但在一般情况下,事情并不总是那么方便。
Backspace Button在功能上有很大的不同,以保证它自己的Clicked处理程序,尽管将两种方法结合到一起可以充分利用它们可能具有的任何代码。
为了给键盘稍大一点的尺寸,所有文本都使用NamedSize.Large给出一个FontSize。 以下是SimplestKeypad程序的三个效果图:
当然,您需要重复按下按键,直到您看到程序如何响应一串非常大的数字,并且您会发现它没有充分预测到这种情况。 当标签变得太宽时,它开始控制垂直StackLayout的整体宽度,并且按钮也开始移动。
此外,如果按钮包含字母或符号而不是数字,则按钮将错位,因为每个按钮宽度均基于其内容。
你能用HorizontalOptions属性上的Expands标志来解决这个问题吗? 不可以。扩展标志会导致额外的空间在StackLayout中的视图之间平均分配。 每个视图将以相同的数量相加增加,但按钮的宽度始终不同,并且它们将始终具有不同的宽度。 例如,查看TwoButtons或ButtonLambdas程序中的两个按钮。 这些按钮的HorizontalOptions属性设置为Fill?andExpand,但它们宽度不同,因为按钮内容的宽度不同。
这些程序的一个更好的解决方案是第17章中提到的称为网格的布局。