视图基础
设置视图的宽高
通过Layout文件设置视图宽高
- 视图宽度通过
android:layout_width设置
- 视图高度通过属性
android:layout_height设置
- 宽高的取值
match_parent和上级视图保持一致
wrap_content根据内容自适应
- 以dp为单位的具体数值
AndroidStudio操作小技巧:ctrl+shift+f 可以格式化代码(或者ctrl+alt+l),调整代码缩进并把每行代码按字母排序
通过Activity文件设置视图宽高
- 确保XML中的宽高属性为
wrap_content
- 调用控件对象的
getLayoutParams方法获取该控件的布局参数
- 布局参数的width属性表示宽度,height表示高度,修改这两个属性值即可改变控件的宽高
- 调用控件对象的
setLayoutParams方法,填入修改后的属性值使之生效(这里需要将dp转换为px)
新建util包,包中新建一个插件类用于将dp单位转换为px单位src\main\java\com\example\chapter03\util\DpConverter.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package com.example.chapter03.util;
import android.content.Context;
public class DpConverter {
public static int dip2px(Context context, float dpvalue){ float scale = context.getResources().getDisplayMetrics().density; return (int)(dpvalue * scale + 0.5f); } }
|
在Activity文件内调用方法,并修改控件的布局属性\src\main\java\com\example\chapter03\ViewBorderActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class ViewBorderActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_view_border); TextView tv_code_layout = findViewById(R.id.tv_code_layout); ViewGroup.LayoutParams params = tv_code_layout.getLayoutParams(); params.width = DpConverter.dip2px(this, 250); tv_code_layout.setLayoutParams(params); } }
|
设置视图的间距
layout_margin属性指定当前视图与平级视图和父级视图之间的距离。包括layout_marginLeft、layout_marginTop、layout_marginRight、layout_marginBottom
padding属性指定当前视图与内部下级视图之间的距离。包括paddingLeft、paddingTop、paddingRight、paddingBottom
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="300dp" android:orientation="vertical" android:background="@color/teal_200">
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="20dp" android:background="@color/purple_200" android:padding="50dp">
<View android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/teal_700"/>
</LinearLayout>
</LinearLayout>
|
设置视图的对齐方式
Layout文件设置视图对齐的两种方式
layout_gravity属性,设置当前视图相对于上级视图的对齐方式。
gravity属性,设置下级视图相对于当前视图的对齐方式。
layout_gravity属性的取值包括:top、bottom、center。
gravity属性的取值包括:top、bottom、start(从左到右)、end(从右到左)
如果需要左下、右上诸如此类的布局,可以将当前元素设置layout_gravity的值为top或bottom,父元素的gravity设置为start或end
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="400dp" android:background="@color/teal_200" android:orientation="horizontal">
<LinearLayout android:layout_width="0dp" android:layout_height="200dp" android:layout_weight="1" android:layout_gravity="top" android:gravity="end" android:background="@color/purple_200">
<View android:layout_width="50dp" android:layout_height="50dp" android:layout_gravity="bottom" android:background="@color/purple_500"/>
</LinearLayout>
<LinearLayout android:layout_width="0dp" android:layout_height="200dp" android:layout_weight="1" android:layout_gravity="bottom" android:background="@color/purple_200"> <View android:layout_width="50dp" android:layout_height="50dp" android:layout_gravity="top" android:background="@color/purple_500"/> </LinearLayout>
</LinearLayout>
|
常用布局
线性布局LinearLayout
线性布局内部视图有两种排列方式
android:orientation="vertical"内部视图按垂直方向从上到下排列
android:orientation="horizontal"内部视图按水平方向从左到右排列(可以使用gravity属性更改内部视图排列)
线性布局的权重
线性布局的权重指的是线性布局的下级视图各自拥有多大比例的宽高
使用layout_weight设置权重,但该属性不在LinearLayout节点设置,而在线性布局的子视图设置,表示该子视图占据父视图宽高的比例。
- 当前视图
layout_width设置为0,当前视图layout_weight表示水平方向的宽度比例
- 当前视图
layout_height设置为0,当前视图layout_weight表示垂直方向的高度比例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="第一个权重1"/> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="第二个权重1"/> </LinearLayout>
|
相对布局RelativeLayout
相对布局的下级视图位置由其他视图决定。用于确定下级视图位置的参照视图分为两种:
- 与该视图平级的视图
- 该视图的父级视图(包含它的RelativeLayout)
如果不设置下级视图的参照视图,那么下级视图默认显示在RelativeLayout内部的左上角
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="150dp"> <TextView android:id="@+id/tv_center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="@color/teal_200" android:text="垂直水平居中" android:textSize="11sp" android:textColor="@color/black"/>
<TextView android:id="@+id/tv_enter_horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:background="@color/teal_200" android:text="水平居中" android:textSize="11sp" android:textColor="@color/black"/>
<TextView android:id="@+id/tv_enter_vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:background="@color/teal_200" android:text="垂直居中" android:textSize="11sp" android:textColor="@color/black"/>
<TextView android:id="@+id/tv_align_right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:background="@color/teal_200" android:text="相对父元素右对齐" android:textColor="@color/black" android:textSize="11sp" />
<TextView android:id="@+id/tv_align_view_right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/tv_center" android:layout_alignBottom="@id/tv_center" android:layout_marginLeft="10dp" android:background="@color/teal_200" android:text="相对中间元素右、底部对齐" android:textColor="@color/black" android:textSize="11sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_center" android:layout_alignLeft="@id/tv_center" android:layout_marginTop="10dp" android:text="在中间元素下面,左对齐" android:textColor="@color/black" android:textSize="11sp" />
</RelativeLayout>
|
网格布局GridLayout
网格布局支持多行多列的表格排列。
网格布局默认从左往右、从上到下排列,它新增了两个属性:
columnCount属性,它指定了网格的列数,即每行能放多少个视图
rowCount属性,它指定了网格的行数,即每列能放多少个视图。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:columnCount="2" android:rowCount="2"> <TextView android:layout_width="0dp" android:layout_height="60dp" android:layout_columnWeight="1" android:background="@color/teal_200" android:text="文字1" android:gravity="center" android:textColor="@color/black" android:textSize="17sp"/> <TextView android:layout_width="0dp" android:layout_height="60dp" android:layout_columnWeight="1" android:background="@color/purple_200" android:textColor="@color/black" android:gravity="center" android:text="文字2" android:textSize="17sp"/> <TextView android:layout_width="80dp" android:layout_height="60dp" android:layout_columnWeight="1" android:background="@color/teal_700" android:gravity="center" android:text="文字3" android:textColor="@color/black" android:textSize="17sp"/> <TextView android:layout_width="80dp" android:layout_height="60dp" android:layout_columnWeight="1" android:background="@color/purple_500" android:gravity="center" android:textColor="@color/black" android:text="文字4" android:textSize="17sp"/> </GridLayout>
|
滚动视图ScrolView
滚动视图有两种
- ScrollView:它是垂直方向的滚动视图;垂直方向滚动,
layout_width属性值设置为match_parent、layout_height属性值设置wrap_content
- HorizontalScrollView:它是水平方向的滚动视图;水平方向滚动时,
layout_width属性值设置为wrap_content,layout_height属性值设置为match_parent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <HorizontalScrollView android:layout_width="wrap_content" android:layout_height="200dp"> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal"> <View android:layout_width="300dp" android:layout_height="match_parent" android:background="@color/purple_200"/>
<View android:layout_width="300dp" android:layout_height="match_parent" android:background="@color/teal_700"/> </LinearLayout> </HorizontalScrollView> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <View android:layout_width="match_parent" android:layout_height="500dp" android:background="@color/purple_200"/>
<View android:layout_width="match_parent" android:layout_height="500dp" android:background="@color/teal_700"/> </LinearLayout> </ScrollView> </LinearLayout>
|
按钮
按钮控件Button由TextView派生而来,它们之间的区别有:
- Button拥有默认的按钮背景,而TextView默认无背景
- Button的内部文本默认居中对齐,而TextView的内部文本
- Button会默认将英文字母转为大写,而TextView保持原始的英文大小写
与TextView相比,Button增加了两个新属性
textAllCaps属性,是否将所有英文字母转为大写,默认为true
onClik属性,指定点击事件产生时调用哪个方法
\src\main\res\layout\activity_button_style.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="点击事件处理" android:textColor="@color/black" android:textAllCaps="false" android:textSize="17sp" android:onClick="doClick"/> <TextView android:id="@+id/tv_event_target" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="点击按钮改变" android:textColor="@color/black" android:textSize="17sp"/> </LinearLayout>
|
\src\main\java\com\example\chapter03\ButtonStyleActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class ButtonStyleActivity extends AppCompatActivity {
private TextView tv_event_target;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_button_style); tv_event_target = findViewById(R.id.tv_event_target); } public void doClick(View view){ String desc = String.format("%s 您点击了按钮: %s",DateUtil.getNowTime(),((Button)view).getText()); tv_event_target.setText(desc); } }
|
\src\main\res\layout\activity_button_style.xml
1 2 3 4 5 6
| public class DateUtil { public static String getNowTime(){ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); return sdf.format(new Date()); } }
|
点击事件
监听器专门用于监听控件的动作行为,只有控件发生了指定的动作,监听器才会触发并执行对应的代码逻辑。
按钮控件有两种常用的监听器:
- 点击监听器,通过
setOnClickListener方法设置。按键被按住少于500毫秒
- 长按监听器,通过
setOnLongClickListener方法设置。按键按住超过500毫秒时,会触发长按事件。
\src\main\java\com\example\chapter03\ButtonClickActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| public class ButtonClickActivity extends AppCompatActivity implements View.OnClickListener{
private TextView tv_btn_click;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_button_click);
Button btn_click = findViewById(R.id.btn_click); Button btn_click_public = findViewById(R.id.btn_click_public); tv_btn_click = findViewById(R.id.tv_btn_click); btn_click.setOnClickListener(new MyOnClickListener(tv_btn_click)); btn_click_public.setOnClickListener(this); }
@Override public void onClick(View view) { if (view.getId() == R.id.btn_click_public){ tv_btn_click.setText("公共点击事件处理"); } } static class MyOnClickListener implements View.OnClickListener { private final TextView tv_btn_click; public MyOnClickListener(TextView tv_btn_click) { this.tv_btn_click = tv_btn_click; } @Override public void onClick(View view) { String desc = String.format("%s", DateUtil.getNowTime()); tv_btn_click.setText(desc); } } }
|
长按点击事件
- 长按监听器,通过
setOnLongClickListener方法设置。按键按住超过500毫秒时,会触发长按事件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class ButtonLongActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_button_long);
TextView tv_long_click = findViewById(R.id.tv_long_click); Button long_click = findViewById(R.id.long_click); long_click.setOnLongClickListener(view -> { String str = DateUtil.getNowTime(); tv_long_click.setText(str); return true; }); } }
|
禁用和恢复按钮
按钮有可用状态和不可用状态,它们在外观和功能上区别如下:
- 不可用按钮:按钮不允许点击,不会产生点击事件,按钮文字为灰色。
- 可用按钮:按钮允许点击,产生点击事件,按钮文字为黑色。
\src\main\java\com\example\chapter03\ButtonEnableActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public class ButtonEnableActivity extends AppCompatActivity implements View.OnClickListener {
private TextView tv_test_click; private Button btn_test;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_button_enable); btn_test = findViewById(R.id.btn_test); Button enable_click = findViewById(R.id.enable_click); Button disable_click = findViewById(R.id.disable_click); tv_test_click = findViewById(R.id.tv_test_click);
enable_click.setOnClickListener(this); disable_click.setOnClickListener(this); btn_test.setOnClickListener(this); }
@Override public void onClick(View view) { if (view.getId() == R.id.enable_click){ btn_test.setEnabled(true); }else if (view.getId() == R.id.disable_click){ btn_test.setEnabled(false); }else{ tv_test_click.setText(DateUtil.getNowTime()); } } }
|