页面设计的零碎知识
- 通用属性
- 设置文本大小
- 设置视图宽高
- 设置视图的对齐方式
- 页面布局
- LinearLayout
- RelativeLayout
- GridLayout
- ScollView
- 按钮触控
- Button
- ImageView
- ImageButton
- 案例:简易计算机
通用属性
设置文本大小
纯数字的setTextSize方法,内部默认字体单位为sp,sp是Android推荐的字号单位
sp专门用来设置字体大小,在系统设置中可以调整字体大小
设置视图宽高
宽高的取值主要有下列三种:
- match_parent:表示与上级视图保持一致
- wrap_content:表示与内容自适应
- 以dp为单位的具体尺寸,dp是指与设备无关的显示单位。
在代码中设置视图宽高:
//.java文件
TextView tv_code=findViewById(R.id.tv_code);
//获取tv_code的布局参数(含高度和宽度)
ViewGroup.LayoutParams params=tv_code.getLayoutParams();
//修改布局参数中的宽度数值,注意默认为px单位
params.width=30
//调用控件对象的setLayoutParams方法,填入修改后的布局参数使之生效
tv_code.setLayoutParams(params)
设置视图的对齐方式
设置视图的对齐方式有两种途径:
- 采用layout_gravity属性,它指定了当前视图相对于上级视图的对齐方式
- 采用gravity属性,它指定了下级视图相对于当前视图的对齐方式
注:两个属性的取值包括:left、top、right、bottom,还可以用竖线连接各取值,例如“left|top”表示即靠左又靠上,也就是朝左上角对齐
例如:
<!--水平和竖直方向都居中-->
<TextViewandroid:gravity="center"/>
页面布局
LinearLayout
RelativeLayout
相对布局的下级视图位置由其他视图决定。用于确定下级视图位置的参照物分两种:
- 与该视图自身平级的视图
- 该视图的上级视图
如果不设定下级视图的参照物,那么下级视图默认显示在RelativeLayout内部的左上角
相对位置的取值
相对位置的属性取值 | 相对位置说明 |
---|---|
layout_toLeftOf | 当前视图在指定视图的左边 |
layout_toRightOf | 当前视图在指定视图的右边 |
layout_above | 当前视图在指定视图的上方 |
layout_below | 当前视图在指定视图的下方 |
layout_alignLeft | 当前视图与指定视图的左侧对齐 |
layout_alignRight | 当前视图与指定视图的右侧对齐 |
layout_alignTop | 当前视图与指定视图的顶部对齐 |
layout_alignBottom | 当前视图与指定视图的底部对齐 |
layout_centerInParent | 当前视图在上级视图中间 |
layout_centerHorizontal | 当前视图在上级视图的水平方向居中 |
layout_centerVertical | 当前视图在上级视图的垂直方向居中 |
layout_centerParentLeft | 当前视图与上级视图的左侧对齐 |
layout_centerParentRight | 当前视图与上级视图的右侧对齐 |
layout_centerParentTop | 当前视图与上级视图的顶部对齐 |
layout_centerParentBottom | 当前视图与上级视图的底部对齐 |
GridLayout
网格布局默认从左到右、从上到下排列,它新增了两个属性(是定义在布局组件上的):
columnCount
属性,它指定了网格的列数,即每行能放多少个视图rowCount
属性,它指定了网格的行数,即每列能放多少个视图
搭配layout_columnWeight
属性使用,可确定每行中的所有组件在列中的宽度占比,该属性定义在子组件上。
ScollView
滚动视图有两种:
- ScrollView,它是垂直方向的滚动视图;垂直方向滚动时,
layout_width
属性值设置为match_parent
,layout_height
属性值设置为wrap_parent
- HorizontalScrollView,它是水平方向的滚动视图;水平方向滚动时,
layout_width
属性值设置为wrap_content
,layout_height
属性值设置为match_parent
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><HorizontalScrollViewandroid:layout_width="wrap_content"android:layout_height="300dp"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="match_parent"android:orientation="horizontal"><Viewandroid:layout_width="300dp"android:layout_height="wrap_content"android:background="@color/white"/><Viewandroid:layout_width="300dp"android:layout_height="match_parent"android:background="@color/black"/></LinearLayout></HorizontalScrollView><ScrollViewandroid:layout_width="match_parent"android:layout_height="wrap_content"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="match_parent"android:orientation="vertical"><Viewandroid:layout_width="match_parent"android:layout_height="400dp"android:background="#0eeeef"/><Viewandroid:layout_width="match_parent"android:layout_height="500dp"android:background="#0000ff"/></LinearLayout></ScrollView>
</LinearLayout>
效果图
按钮触控
Button
按钮控件Button由TextView派生而来,它们之间的区别有:
- Button拥有默认的按钮背景,而TextView默认无背景
- Button的内部文本默认居中对齐,而TextView的内部文本默认靠左对齐
- Button会默认将英文字母转为大写,而TextView保持原始的英文大小写
注:Button取消字母全部大写:
android:textAllCaps="false"
按钮控件有两种常用的监听器:
- 点击监听器,通过
setOnClickListener
方法设置。按钮被按住少于500毫秒时,会触发点击事件。 - 长按监听器,通过
setOnLongClickListener
方法设置。按钮被按住超过500毫秒时,会触发长按事件。
几种常用的为Button控件设置点击事件的方式
//1.使用匿名内部类的方式设置点击事件 不占用内存
btn_click_single.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View view){//......}
})//2.静态内部类写法 易造成内存泄露
Button btn_click_single=findViewById(R.id.btn_click_single);
btn_click_single.setOnClickListener(new MyOnClickListener());
static class MyOnClickListener implements View.OnclickListener{@Overridepublic void onClick(View v){//.......}
}//3.Activity实现OnClickListener接口的方式设置点击事件
btn_click_single.setOnClickListener(this);
@Override
public void onClick(View v){if(v.getId()==R.id.btn_click_single){//...}//或者switch (v.getId()){case R.id.btn_click_single://......break;}
}//4.lambda表达式
btn_click_single.setOnClickListener(v->{//......return ture;//返回true表示允许冒泡 false表示禁止冒泡
})
//长按事件:只需要把setOnClickListener换为setOnLongClickListener
禁用与恢复按钮
是否允许点击由enabled属性控制,属性值为true时表示允许点击,为false时表示不允许点击
ImageView
ImageView继承自View类,它的功能用于显示图片,或者显示Drawable对象。
图像视图展示的图片通常位于res/drawable***目录,设置图像视图的显示图片有两种方式:
- 在XML文件中,通过属性
android:src
设置图片资源,属性值格式形如“@drawable/不含扩展名的图片名称” - 在Java代码中,调用
setImageResource
方法设置图片资源,方法参数格式形如“R.drawable.不含扩展名的图片名称”
ImageView本身默认图片居中(fitCenter),若要改变图片的显示方式,可通过scaleType属性设定(在Java代码中是setScaleType
)该属性的取值说明如下:
XML中的缩放类型 | ScaleType类中的缩放类型 | 说明 |
---|---|---|
fitXY | FIT_XY | 拉伸图片使其正好填满视图(图片会被拉伸变形) |
fitStart | FIT_START | 保持宽高比例,拉伸图片使其位于视图上方或左侧 |
fitCenter | FIT_CENTER | 保持宽高比例,拉伸图片使其位于视图中间 |
fitEnd | FIT_END | 保持宽高比例,拉伸图片使其位于视图下方或右侧 |
center | CENTER | 保持图片原尺寸,并使其位于视图中间 |
centerCrop | CENTER_CROP | 拉伸图片使其充满视图,并位于视图中间(图片不会被拉伸变形,多余部分会被裁减掉) |
centerInside | CENTER_INSIDE | 保持宽高比例,缩小图片使之位于视图中间(只缩小不放大) |
ImageButton
ImageButton是显示图片的图像按钮,但它继承自ImageView,而非继承Button。
ImageButton和Button之间的区别有:
- Button即可显示文本也可显示图片,ImageButton只能显示图片不能显示文本。
- ImageButton上的图像可按比例缩放,而Button通过背景设置的图像会拉伸变形。
- Button只能靠背景显示一张图片,而ImageButton可分别在前景和背景显示图片,从而实现两张图片叠加的效果。
在某些场合,有的字符无法由输入法打出来,或者某些文字以特殊字体展示,就适合先切图再放到ImageButton。
ImageButton和ImageView的区别有:
- ImageButton有默认的按钮背景,ImageView默认无背景。
- ImageButton默认的缩放类型为center,而ImageView默认的缩放类型为fitCenter。
同时展现文本和图像
(1)利用LinearLayout对ImageView和TextView组合布局。
(2)通过按钮控件Button的drawable***属性设置文本周围的图标。
- drawableTop:指定文字上方的图片
- drawableBottom:指定文字下方的图片
- drawableLeft:指定文字左边的图片
- drawableRight:指定文字右边的图片
- drawablePadding:指定图片与文字的间距
案例:简易计算机
要求
计算机界面分为两大部分,第一部分是上方的计算表达式,既包括用户的按键输入,也包括计算结果数字;第二部分是下方的各个按键,例如:从0到9的数字按钮、加减乘除与等号、正负号按钮、小数点按钮、求倒数按钮、平方按钮、开方按钮,以及退格、清空、取消等控制按钮。
代码
①页面设计
<!--calculator_layout.xml-->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#EEEEEE"android:padding="5dp"><ScrollViewandroid:layout_width="match_parent"android:layout_height="wrap_content"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="@string/simple_calculator"android:gravity="center"android:textColor="@color/black"android:textSize="20sp"/><TextViewandroid:id="@+id/tv_result"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/white"android:text="0"android:textColor="@color/black"android:textSize="25sp"android:lines="3"android:gravity="right|bottom"/><GridLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:columnCount="4"android:rowCount="5"><Buttonandroid:id="@+id/btn_cancel"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/cancel"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_divide"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/divide"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_multiply"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/multiply"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_clear"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/clear"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_seven"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/seven"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_eight"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/eight"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_nine"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/nine"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_plus"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/plus"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_four"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/four"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_five"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/five"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_six"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/six"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_minus"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/minus"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_one"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/one"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_two"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/two"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_three"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/three"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><ImageButtonandroid:id="@+id/btn_sqrt"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:src="@drawable/sqrt"android:scaleType="fitXY"/><Buttonandroid:id="@+id/btn_reciprocal"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/reciprocal"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_zero"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/zero"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_dot"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/dot"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_equal"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/equal"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/></GridLayout></LinearLayout></ScrollView>
</LinearLayout>
②交互逻辑
//CalculatorActivity.java
package com.example.myapplicationone;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;public class CalculatorActivity extends AppCompatActivity implements View.OnClickListener {private TextView tv_result;//第一个操作数private String firstNum="";//运算符private String operator="";//第二个操作数private String secondNum="";//当前的计算结果private String result="";//显示的文本内容private String showText="";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.calculator_layout);//从布局文件中获取名为tv_result的文本视图tv_result=findViewById(R.id.tv_result);//给下面每个按钮控件注册点击监听器findViewById(R.id.btn_cancel).setOnClickListener(this);findViewById(R.id.btn_divide).setOnClickListener(this);findViewById(R.id.btn_multiply).setOnClickListener(this);findViewById(R.id.btn_clear).setOnClickListener(this);findViewById(R.id.btn_seven).setOnClickListener(this);findViewById(R.id.btn_eight).setOnClickListener(this);findViewById(R.id.btn_nine).setOnClickListener(this);findViewById(R.id.btn_plus).setOnClickListener(this);findViewById(R.id.btn_four).setOnClickListener(this);findViewById(R.id.btn_five).setOnClickListener(this);findViewById(R.id.btn_six).setOnClickListener(this);findViewById(R.id.btn_minus).setOnClickListener(this);findViewById(R.id.btn_one).setOnClickListener(this);findViewById(R.id.btn_two).setOnClickListener(this);findViewById(R.id.btn_three).setOnClickListener(this);findViewById(R.id.btn_sqrt).setOnClickListener(this);findViewById(R.id.btn_reciprocal).setOnClickListener(this);findViewById(R.id.btn_zero).setOnClickListener(this);findViewById(R.id.btn_dot).setOnClickListener(this);findViewById(R.id.btn_equal).setOnClickListener(this);}@Overridepublic void onClick(View v) {String inputText;
// 注:
// ①switch支持的类型:switch表达式后面的数据类型只能是byte、short、chart、int四种整型类型,枚举类型和java.lang.String类型,不能是boolean类型。
// ②case中使用的必须是常量,也就是要进行判断的值必须是常量,必须使用final修饰。
// 在这里如果使用switch会遇到报错,switch无法使用String或者R.id.XXX报错的问题,
// 会提示Constant expression required,所以也顾不上麻烦直接写为if...else if....else。if(v.getId()==R.id.btn_sqrt){//如果是根号按钮inputText="√";}else {//根号外的其他按钮//Button虽然继承自TextView 但是并没有getText方法inputText=((TextView)v).getText().toString();}if (v.getId()==R.id.btn_clear){//点击了清除按钮clear();}else if(v.getId()==R.id.btn_cancel) {//撤销按钮}else if(v.getId()==R.id.btn_plus || v.getId()==R.id.btn_minus || v.getId()==R.id.btn_multiply ||v.getId()==R.id.btn_divide) {//加减乘除operator = inputText;refreshText(showText + operator);}else if(v.getId()==R.id.btn_equal) {//等号按钮//加减乘除四则运算double calculate_result=calculateFour();//把上一次的计算结果存起来refreshOperator(String.valueOf(calculate_result));refreshText(showText+"="+result);}else if(v.getId()==R.id.btn_sqrt) {//开根号按钮double sqrt_result=Math.sqrt(Double.parseDouble(firstNum));refreshOperator(String.valueOf(sqrt_result));refreshText(showText+"√="+result);}else if(v.getId()==R.id.btn_reciprocal) {//求导数按钮double reciprocal_result=1.0/Double.parseDouble(firstNum);refreshOperator(String.valueOf(reciprocal_result));refreshText(showText+"/="+result);}else{//其他按钮 包括数字和小数点//上次运算结果已经出来 再输入数字要清空if(result.length()>0&&operator.equals("")){clear();}if (operator.equals("")){//无运算符,则继续拼接第一个操作数firstNum=firstNum+inputText;}else {//有运算符,则继续拼接第二个操作数secondNum=secondNum+inputText;}//整数不需要前边的0if(showText.equals("0")&& !inputText.equals(".")){refreshText(inputText);}else {refreshText(showText + inputText);}}}//加减乘除四则运算 返回计算结果private double calculateFour() {switch(operator){//这里因为运算符都是常量 所以可以使用switchcase "+":return Double.parseDouble(firstNum)+Double.parseDouble(secondNum);case "-":return Double.parseDouble(firstNum)-Double.parseDouble(secondNum);case "×":return Double.parseDouble(firstNum)*Double.parseDouble(secondNum);default:return Double.parseDouble(firstNum)/Double.parseDouble(secondNum);}}private void clear() {refreshOperator("");refreshText("");}//刷新运算结果private void refreshOperator(String new_result){result=new_result;firstNum=result;secondNum="";operator="";}//刷新文本显示private void refreshText(String text){showText=text;tv_result.setText(showText);}
}
效果