打造一款计算器(1)界面设计
打造一款计算器(1)界面设计
学习android有一段时间了,计划打造一款简单易用的计算器,界面及功能从最基础的样式开始,后续实现的过程中再慢慢进行完善。
欢迎感兴趣的朋友一起讨论、学习,大家共同进步。
写这篇文章时,还没有对计算器界面上按钮对应的功能进行实现,只是给出界面设计及布局生成(xml代码的编写)过程中需要注意的地方。
1、界面设计布局代码
1 <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:id="@+id/tablelayout_calculator" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:stretchColumns="*" > 6 7 <TextView android:id="@+id/text_input" 8 android:layout_weight="3" 9 android:layout_height="0dp" 10 android:layout_width="match_parent" 11 android:hint="input something" 12 android:gravity="bottom|right" 13 android:textSize="@dimen/text_size" 14 android:textColor="#0000ff" /> 15 16 <TableRow android:layout_weight="1" > 17 <Button android:id="@+id/btn_sin" 18 android:layout_height="match_parent" 19 android:layout_width="wrap_content" 20 android:text="sin" 21 android:textSize="@dimen/text_size" 22 android:textAllCaps="false" /> 23 <Button android:id="@+id/btn_cos" 24 android:layout_height="match_parent" 25 android:layout_width="wrap_content" 26 android:text="cos" 27 android:textSize="@dimen/text_size" 28 android:textAllCaps="false" /> 29 <Button android:id="@+id/btn_tan" 30 android:layout_height="match_parent" 31 android:layout_width="wrap_content" 32 android:text="tan" 33 android:textSize="@dimen/text_size" 34 android:textAllCaps="false" /> 35 <Button android:id="@+id/btn_cls" 36 android:layout_height="match_parent" 37 android:layout_width="wrap_content" 38 android:text="C" 39 android:textSize="@dimen/text_size" 40 android:textAllCaps="false" /> 41 <Button android:id="@+id/btn_del" 42 android:layout_height="match_parent" 43 android:layout_width="wrap_content" 44 android:text="Del" 45 android:textSize="@dimen/text_size" 46 android:textAllCaps="false" /> 47 </TableRow> 48 49 <TableRow android:layout_weight="1" > 50 <Button android:id="@+id/btn_pia" 51 android:layout_height="match_parent" 52 android:layout_width="wrap_content" 53 android:text="@string/calculator_pia" 54 android:textSize="@dimen/text_size" /> 55 <Button android:id="@+id/btn_lna" 56 android:layout_height="match_parent" 57 android:layout_width="wrap_content" 58 android:text="ln" 59 android:textSize="@dimen/text_size" 60 android:textAllCaps="false" /> 61 <Button android:id="@+id/btn_log" 62 android:layout_height="match_parent" 63 android:layout_width="wrap_content" 64 android:text="log" 65 android:textSize="@dimen/text_size" 66 android:textAllCaps="false" /> 67 <Button android:id="@+id/btn_fac" 68 android:layout_height="match_parent" 69 android:layout_width="wrap_content" 70 android:text="!" 71 android:textSize="@dimen/text_size" 72 android:textColor="#ff9933" /> 73 <Button android:id="@+id/btn_add" 74 android:layout_height="match_parent" 75 android:layout_width="wrap_content" 76 android:text="+" 77 android:textSize="@dimen/text_size" 78 android:textColor="#ff9933" /> 79 </TableRow> 80 81 <TableRow android:layout_weight="1"> 82 <Button android:id="@+id/btn_7" 83 android:layout_height="match_parent" 84 android:layout_width="wrap_content" 85 android:text="7" 86 android:textSize="@dimen/text_size" /> 87 <Button android:id="@+id/btn_8" 88 android:layout_height="match_parent" 89 android:layout_width="wrap_content" 90 android:text="8" 91 android:textSize="@dimen/text_size" /> 92 <Button android:id="@+id/btn_9" 93 android:layout_height="match_parent" 94 android:layout_width="wrap_content" 95 android:text="9" 96 android:textSize="@dimen/text_size" /> 97 <Button android:id="@+id/btn_pow" 98 android:layout_height="match_parent" 99 android:layout_width="wrap_content" 100 android:text="^" 101 android:textSize="@dimen/text_size" 102 android:textColor="#ff9933"/> 103 <Button android:id="@+id/btn_sub" 104 android:layout_height="match_parent" 105 android:layout_width="wrap_content" 106 android:text="-" 107 android:textSize="@dimen/text_size" 108 android:textColor="#ff9933" /> 109 </TableRow> 110 111 <TableRow android:layout_weight="1"> 112 <Button android:id="@+id/btn_4" 113 android:layout_height="match_parent" 114 android:layout_width="wrap_content" 115 android:text="4" 116 android:textSize="@dimen/text_size" /> 117 <Button android:id="@+id/btn_5" 118 android:layout_height="match_parent" 119 android:layout_width="wrap_content" 120 android:text="5" 121 android:textSize="@dimen/text_size" /> 122 <Button android:id="@+id/btn_6" 123 android:layout_height="match_parent" 124 android:layout_width="wrap_content" 125 android:text="6" 126 android:textSize="@dimen/text_size" /> 127 <Button android:id="@+id/btn_sqr" 128 android:layout_height="match_parent" 129 android:layout_width="wrap_content" 130 android:text="@string/calculator_sqr" 131 android:textSize="@dimen/text_size" 132 android:textColor="#ff9933" /> 133 <Button android:id="@+id/btn_mul" 134 android:layout_height="match_parent" 135 android:layout_width="wrap_content" 136 android:text="*" 137 android:textSize="@dimen/text_size" 138 android:textColor="#ff9933" /> 139 </TableRow> 140 141 <TableRow android:layout_weight="1"> 142 <Button android:id="@+id/btn_1" 143 android:layout_height="match_parent" 144 android:layout_width="wrap_content" 145 android:text="1" 146 android:textSize="@dimen/text_size" /> 147 <Button android:id="@+id/btn_2" 148 android:layout_height="match_parent" 149 android:layout_width="wrap_content" 150 android:text="2" 151 android:textSize="@dimen/text_size" /> 152 <Button android:id="@+id/btn_3" 153 android:layout_height="match_parent" 154 android:layout_width="wrap_content" 155 android:text="3" 156 android:textSize="@dimen/text_size" /> 157 <Button android:id="@+id/btn_lef" 158 android:layout_height="match_parent" 159 android:layout_width="wrap_content" 160 android:text="(" 161 android:textSize="@dimen/text_size" 162 android:textColor="#ff9933" /> 163 <Button android:id="@+id/btn_div" 164 android:layout_height="match_parent" 165 android:layout_width="wrap_content" 166 android:text="/" 167 android:textSize="@dimen/text_size" 168 android:textColor="#ff9933" /> 169 </TableRow> 170 171 <TableRow android:layout_weight="1"> 172 <Button android:id="@+id/btn_0" 173 android:layout_height="match_parent" 174 android:layout_width="wrap_content" 175 android:text="0" 176 android:textSize="@dimen/text_size" /> 177 <Button android:id="@+id/btn_00" 178 android:layout_height="match_parent" 179 android:layout_width="wrap_content" 180 android:text="00" 181 android:textSize="@dimen/text_size" /> 182 <Button android:id="@+id/btn_poi" 183 android:layout_height="match_parent" 184 android:layout_width="wrap_content" 185 android:text="." 186 android:textSize="@dimen/text_size" /> 187 <Button android:id="@+id/btn_rig" 188 android:layout_height="match_parent" 189 android:layout_width="wrap_content" 190 android:text=")" 191 android:textSize="@dimen/text_size" 192 android:textColor="#ff9933" /> 193 <Button android:id="@+id/btn_equ" 194 android:layout_height="match_parent" 195 android:layout_width="wrap_content" 196 android:text="=" 197 android:textSize="@dimen/text_size" 198 android:textColor="#ff9933" /> 199 </TableRow> 200 201 </TableLayout>
2、xml代码简单分析
针对计算器这种功能性按钮呈类似表格状分布的应用程序界面,笔者首先想到的布局组件就是TableLayout和TableRow。
从xml布局代码或开头的界面示意图可以看出,整体界面的布局采用的组件如下:
a、根元素是1个TableLayout,并且设置了属性android:stretchColumns="*",保证其子组件TableRow中的元素所占列宽相同;
b、第二级子组件为1个TextView和6个TableView,前者TextView用来显示用户输入内容和最终计算结果;后者每个TableRow各有五个按钮,即总共30个按钮;
下面主要介绍一下布局代码中需要注意的地方。
a、第8、9行对于TextView组件的高度属性设置为android:layout_weight="3" , android:layout_height="0dp",结合后面的5个TableRow组件的高度属性设置android:layout_weight="1",那么整个TableLayout的所占的界面高度被分为了8份,最终效果为1个TextView占总高度的3/8,5个TableRow各占总高度1/8;
b、第22行对于按钮文本内容显示的大小写属性设置为android:textAllCaps="false",false表示最终显示在按钮的文本内容的大小写和定义时一致,如果不设置的话默认为true,那么程序会自动将本文全部转为大写;
c、第20、26等行是在xml布局文件中直接对按钮文本进行设置,规范的做法应该是在资源文件values/strings.xml(名称自取,不固定)文件中进行定义,然后在xml文件中利用@string/xxx(Java代码中是R.string.xxx)的形式进行获取。当然,有些字串是无法直接在xml布局文件中进行输入的,如π(pi,53行)、√(sqrt,130行)等,这时就必须在资源文件中对其进行定义,利用机器能够识别的十进制编码。定义代码如下:
1 <string name="calculator_pia">π</string> 2 <string name="calculator_sqr">√</string>
d、当然,可以将每个按钮或者每个TableRow结合styles等属性分别定义成可复用的xml文件,那样的话在最终的界面布局文件activity_calculator.xml中只需要利用include关键字导入定义好的TableRow组件对应的文件名即可。这部分设计本文没有给出,后面实现过程中如有必要的话会进行实现并写入文章中;
e、虽然按钮对应的功能实现本文没有涉及,但其对应的id命名这里先解释一下。像btn_0、btn_1这种很好理解,对应的按键是数字0、1,而像π、√、.这类按钮的id名称为btn_pia、btn_sqr、btn_poi。即除了数字一目了然外,其余的命名均采用btn_xxx的形式,这样做的目的是在后续的Java文件中获取组件id时有个统一的标准,毕竟组件很多的情况下有个可以参考的线索是比较省脑细胞的。
3、字串赋值规范化
既然说到字串等资源定义的规范化,接下来就将上面介绍的按钮文本直接赋值转为资源文件+Java代码的设置方式。
首先将所有按钮用到的字串统一定义到资源文件values/strings_calculator.xml中,具体如下。
1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 4 <string-array name="strings_calculator" > 5 6 <item>sin</item> 7 <item>cos</item> 8 <item>tan</item> 9 <item>C</item> 10 <item>Del</item> 11 12 <item>π</item> 13 <item>ln</item> 14 <item>log</item> 15 <item>!</item> 16 <item>+</item> 17 18 <item>7</item> 19 <item>8</item> 20 <item>9</item> 21 <item>^</item> 22 <item>-</item> 23 24 <item>4</item> 25 <item>5</item> 26 <item>6</item> 27 <item>√</item> 28 <item>*</item> 29 30 <item>1</item> 31 <item>2</item> 32 <item>3</item> 33 <item>(</item> 34 <item>/</item> 35 36 <item>0</item> 37 <item>00</item> 38 <item>.</item> 39 <item>)</item> 40 <item>=</item> 41 42 </string-array> 43 44 </resources>
接下来得注意,定义了字串资源文件后,对组件的文本进行设置可以在xml布局文件中,也可以在Java代码中。虽然常见的也较符合常理的做法是在xml文件中利用android:text="@string/xxx"进行设置,但是针对本文介绍的计算器而言,在Java代码中进行设置更为方便。结合TableLayout和TableRow的特性,来看看怎样快速地对左右按钮进行本文的设置。
1 package com.dylan_wang.calculator; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.Menu; 6 import android.view.MenuItem; 7 import android.widget.Button; 8 import android.widget.TableLayout; 9 import android.widget.TableRow; 10 11 public class ActivityCalculator extends Activity { 12 13 @Override 14 protected void onCreate(Bundle savedInstanceState) { 15 super.onCreate(savedInstanceState); 16 setContentView(R.layout.activity_calculator); 17 18 String[] stringsCalculator = getResources().getStringArray(R.array.strings_calculator); 19 TableLayout tableLayout = (TableLayout)findViewById(R.id.tablelayout_calculator); 20 for(int i=1;i<tableLayout.getChildCount();++i){ 21 TableRow tableRow = (TableRow)tableLayout.getChildAt(i); 22 for(int j=0;j<tableRow.getChildCount();++j){ 23 Button button = (Button)tableRow.getChildAt(j); 24 button.setText(stringsCalculator[(i-1)*5+j]); 25 } 26 } 27 } 28 29 @Override 30 public boolean onCreateOptionsMenu(Menu menu) { 31 // Inflate the menu; this adds items to the action bar if it is present. 32 getMenuInflater().inflate(R.menu.menu_main, menu); 33 return true; 34 } 35 36 @Override 37 public boolean onOptionsItemSelected(MenuItem item) { 38 // Handle action bar item clicks here. The action bar will 39 // automatically handle clicks on the Home/Up button, so long 40 // as you specify a parent activity in AndroidManifest.xml. 41 int id = item.getItemId(); 42 43 //noinspection SimplifiableIfStatement 44 if (id == R.id.action_settings) { 45 return true; 46 } 47 48 return super.onOptionsItemSelected(item); 49 } 50 }
可以看到,真正只用了9行代码(18-26)就完成了30个按钮的本文获取与设置。当然,如果在各行按钮之间穿插其他组件的话,得分情况处理。
从界面示意图可以看出,乘除号分别是*与/,并不是理想中的×与÷。那么对于π(pi,53行)、√(sqrt,130行)这种特殊字符对应编码去哪找,乘除号(×与÷)又该怎么输入呢?
对于前者,有一个总结得比较齐全的网站http://www.cnblogs.com/zhouyinhui/p/4025637.html,是咱们博客园中的同志贡献的,供大家参考。
而对于乘除号这类符号靠输入法+细心就能搞定了,相信平时大家在中文p拼音模式下(有时英文也会出现)输入一些中文字的部分或全部字符时一定看到过,输入法提示框中会出现额外的数学符号。如在百度输入chu,会出现以下提示框:
输入ch,竟然乘除号都出来了:
若是输入cheng,则没有想象中的×出现:
当然,不同电脑及输入法会有差异,但不出意外的话该方法是能够帮助我们获取到想要的符号的。
将乘除号设置为×、÷,并将清零与回删按钮标记为红色后的界面如下:
4、总结
至此只是完成了一款计算器粗略的界面设计部分,后续会慢慢对各按钮对应的功能进行实现,有必要也会对界面进行完善。
最后分享一个感觉不错的png等图标获取网站http://www.easyicon.net/iconsearch//,如果直接打开有问题,也可以直接度娘easyicon。
欢迎讨论,觉得有用且对后续实现感兴趣的朋友帮忙点个赞哦^_^