常用控件
TextView
最简单的控件
-
例子
<TextView android:id="@+id/text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:textSize="24sp" android:textColor="#ff0000" android:text="Hello World!" />
- TextView中的文字默认是左上角对齐的
- android:gravity:指定文字的对齐方式,可选值包括top,bottom,left,right,center,可以使用|来同时指定多个值
- android:textSize:使用sp单位来指定字体大小
- android:textColor:指定文字颜色,值是16进制
Button
按钮控件
-
例子
<Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button" android:textAllCaps="false" />
- Button中,默认所有的英文自动转成大写,可以使用android:textAllCaps来取消转换
-
给按钮组件设置监听事件
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 在这里写按钮的逻辑 } }); }
EditText
程序和用户进行交互的控件,允许用户在控件里输入和编辑内容,程序可以对这些内容进行处理
-
例子
<EditText android:id="@+id/edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="在这里输入..." android:maxLines="2" />
- android:hint:提示一段提示性的文本
- android:maxLines:指定了EditText的最大行数,当输入的内容超过最大行数的时候文本自动上滚
-
例子:结合Button控件,实现点击按钮显示EditText中的内容
public class MainActivity extends AppCompatActivity { private EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText = findViewById(R.id.edit_text); Button button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String inputText = editText.getText().toString(); Toast.makeText(MainActivity.this,inputText,Toast.LENGTH_SHORT).show(); } }); } }
ImageView
在界面上展示图片的控件
-
例子
<ImageView android:id="@+id/image_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/img1" />
- android:src:指定图片
- 因为图片的宽高都是为止的,所以控件的宽高使用wrap_content来保证图片可以完整的展示
-
例子:配合Button控件,实现点击按钮切换图片
private EditText editText; private ImageView imageView; boolean flag = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText = findViewById(R.id.edit_text); imageView = findViewById(R.id.image_view); Button button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { flag = !flag; if (flag==true){ imageView.setImageResource(R.drawable.img2); } else{ imageView.setImageResource(R.drawable.img1); } } }); }
ProgressBar
在界面上显示进度条
-
例子
<ProgressBar android:id="@+id/progress_bar" android:layout_height="wrap_content" android:layout_width="match_parent" style="?android:attr/progressBarStyleHorizontal" android:max="100" />
- 默认是在屏幕中间出现一个圆在旋转
- android:visibility:用来控制控件是否可见,总共有三个值:visible,invisibel,gone
- visible:控件可见,默认值,在不指定这个属性的时候控件都是可见的
- invisible:控件不可见,但是仍然占据着原来的位置和大小
- gone:控件不可见,且不占用屏幕空间
- 可以使用style来指定进度条样式,这里指定为水平的
- android:max:指定进度条的大小,这里设置为100
-
例子:点击按钮让进度条消失,再点击出现
private ProgressBar progressBar; progressBar = findViewById(R.id.progress_bar); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (progressBar.getVisibility() == View.GONE){ progressBar.setVisibility(View.VISIBLE); } else{ progressBar.setVisibility(View.GONE); } } });
- 使用getVisibility()方法判断进度条是否可见,如果可见就隐藏起来,否则就显示出来
-
例子:动态地修改进度条的进度
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int progress = progressBar.getProgress(); progress = progress +10; progressBar.setProgress(progress); } });
- 每点击一次按钮,进度条加10
AlertDiallog
在当前的界面弹出一个对话框,这个对话框置顶于所有界面元素之上,而且能够屏蔽掉其他控件的交互功能
通常用来提示一些非常重要的内容或弹出警告信息
-
例子
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this); // 设置标题 dialog.setTitle("警告警告!"); // 设置内容 dialog.setMessage("这是一个警告!"); // 设置可不可以使用Back键关闭对话框,false表示不可以 dialog.setCancelable(false); // setPositiveButton()方法设置取消按钮的点击事件 dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { } }); dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { } }); // show()方法将对话框显示出来 dialog.show(); } });
ProgressDialog
类似于AlertDialog,区别就是ProgressDialog在对话框中显示一个进度条,一般用于表示当前操作比较耗时的时候
-
例子
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ProgressDialog progressDialog = new ProgressDialog(MainActivity.this); progressDialog.setTitle("Progress Dialog"); progressDialog.setMessage("加载中..."); progressDialog.setCancelable(true); // 设置为可以通过Back键取消掉 progressDialog.show(); } });
基本布局
线性布局
LinearLayout
这个布局会将包含的控件在线性方向上排列
-
例子
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button" android:layout_gravity="top" android:textAllCaps="false" /> </LinearLayout>
-
可以使用android:orientation属性来指定排列方向,默认是水平排列
- vertical
- 垂直排列
- 在这种排列的时候,内部空间不能将高度指定为match_parent
- horizontal
- 水平方向排列
- 在这种排列的时候,内部控件不能将宽度指定为match_parent
- vertical
-
android:layout_gravity
- 用来指定控件在布局中的对齐方式
- 当线性布局的排列方式是horizontal时,只有垂直方向上的对齐方式才会生效
- 当线性布局的排列方式是vertical时,只有水平方向上的对象方式才会生效
-
android:layout_weight
可以让用户使用比例的方式来指定控件的大小
-
例子
<Button android:id="@+id/button" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Button" android:layout_gravity="top" android:textAllCaps="false" android:layout_weight="1" /> <EditText android:id="@+id/edit_text" android:layout_width="0dp" android:layout_height="wrap_content" android:maxLines="2" android:layout_weight="1" android:hint="在这里输入..." />
- 上述代码表示Button和EditText控件在水平放心上平分宽度
- 具体计算方法:
- 系统会先将线性布局下所有控件指定的layout_weight的值相加,得到一个值n
- 然后使用每个控件的layout_weight的值除以n,得到的就是所占的比例
- 比如上述例子中,Button和EditText的layout_weight的值加起来是2,各自的是1,相除得到0.5,所以各占50%
-
相对布局
RelativeLayout
通过相对定位的方式让控件出现在布局的任何位置
-
例子
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:text="Button1" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:text="Button2" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Button3" /> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:text="Button4" /> <Button android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:text="Button5" /> <Button android:id="@+id/button6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/button3" android:layout_toRightOf="@+id/button3" android:text="Button6" /> <Button android:id="@+id/button7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/button3" android:layout_toLeftOf="@+id/button3" android:text="Button7" /> <Button android:id="@+id/button8" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/button3" android:layout_toRightOf="@+id/button3" android:text="Button8" /> </RelativeLayout>
- Button1和父布局的左上角对齐
- Button2和父布局的右上角对齐
- Button3居中显示
- Button4和父布局左下角对齐
- Button5和父布局右下角对齐
- android:layout_above
- 让一个控件位于另一个控件的上面
- 这个属性的值是相对控件的id
- android:layout_below:让一个控件位于另一个控件下方
- android:layout_toRightOf:让一个控件位于另一个控件右边
- android:layout_toLeftOf:让一个控件位于另一个控件左边
- android:layout_alignRight:让一个控件的右边缘和另一个控件的右边缘对齐
- android:layout_alignLeft:让一个控件的左边缘和另一个控件的左边缘对齐
帧布局
FrameLayout
在这种布局中,所有的控件都默认摆放在布局的左上角
-
例子
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" android:text="一个TextView" /> <ImageView android:id="@+id/image_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/ic_launcher" android:layout_gravity="right" /> </FrameLayout>
- android:layout_gravity
- 指定控件在布局中的对齐方式
- android:layout_gravity
百分比布局
在这种布局中,可以直接指定控件在布局中所占的百分比
百分比布局只weiFrameLayout和RelativeLayout提供了扩展,分别对应PercentFrameLayout和PercentRelativeLayout
-
使用
-
需要在app/build.gradle的dependencies中添加依赖
// 老版本 implementation 'com.android.support:percent:28.0.0' // 新版本 implementation 'androidx.percentlayout:percentlayout:1.0.0'
-
-
例子
<androidx.percentlayout.widget.PercentFrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="match_parent" android:layout_width="match_parent"> <!-- 这里报错不影响程序运行--> <Button android:id="@+id/button1" android:layout_heightPercent = "50%" android:layout_widthPercent = "50" android:layout_gravity="left|top" android:text="Button1" /> <Button android:id="@+id/button2" android:layout_heightPercent = "50%" android:layout_widthPercent = "50" android:layout_gravity="right|top" android:text="Button2" /> <Button android:id="@+id/button3" android:layout_heightPercent = "50%" android:layout_widthPercent = "50" android:layout_gravity="left|bottom" android:text="Button3" /> <Button android:id="@+id/button4" android:layout_heightPercent = "50%" android:layout_widthPercent = "50" android:layout_gravity="right|bottom" android:text="Button4" /> </androidx.percentlayout.widget.PercentFrameLayout>
- 使用android:layout_widthPercent属性来控制各个按钮的宽度
- 使用android:layout_heightPercent属性来控制各个按钮的高度
自定义控件
- 所有的控件都是直接或间接继承自View的
- 所有布局都是直接或间接继承自ViewGroup的
引入布局
-
自定义一个布局
<?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="match_parent"> <Button android:id="@+id/title_back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="5dp" android:background="@drawable/ic_launcher_background" android:text="Back" android:textColor="#fff" /> <TextView android:id="@+id/title_text" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="1" android:gravity="center" android:text="Title Text" android:textColor="#fff" android:textSize="24sp" /> <Button android:id="@+id/title_edit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="5dp" android:background="@drawable/ic_launcher_background" android:text="Edit" android:textColor="#fff" /> </LinearLayout>
- android:background
- 为布局或控件指定背景,可以使用图片或颜色进行填充
- android:background
-
在activity_main.xml中使用include标签使用自定义的布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context=".MainActivity"> <include layout="@layout/title"/> ... </LinearLayout>
ListView
使用ListView
-
先在activity_main.xml中创建一个控件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ListView android:id="@+id/list_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
-
然后修改mainActivity中的代码
public class MainActivity extends AppCompatActivity { // data是一个数组,包含水果的名字 private String[] data = { "Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple", "Strawberry","Cherry","Mango", "Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple", "Strawberry","Cherry","Mango"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 通过ArrayAdapter将数组中的数据传给ListView ArrayAdapter<String> adapter = new ArrayAdapter<String>( MainActivity.this, android.R.layout.simple_list_item_1,data); ListView listView = (ListView) findViewById(R.id.list_view); // setAdapter()方法可以将构建好的适配器对象传递进去 listView.setAdapter(adapter); } }
- android.R.layout.simple_list_item_1是Android内置的布局文件,里面只有一个TextView,可以用来简单的显示一段文本
定制ListView界面
-
先自定义一个布局
<?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"> <ImageView android:id="@+id/fruit_image" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/fruit_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" /> </LinearLayout>
-
然后自定义一个类
package com.example.listview; public class Fruits { private String name; private int imageId; public Fruits(String name,int imageId){ this.name = name; this.imageId = imageId; } public String getName() { return name; } public int getImageId() { return imageId; } }
-
然后自定义一个适配器
public class FruitsAdapter extends ArrayAdapter<Fruits> { private int resourceId; public FruitsAdapter(Context context, int textViewResourceId, List<Fruits> objects){ super(context,textViewResourceId,objects); resourceId = textViewResourceId; } @Override public View getView(int position, View convertView, ViewGroup parent){ Fruits fruits = getItem(position); // 获取当前项的实例 View view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false); ImageView fruitsImage = (ImageView) view.findViewById(R.id.fruit_image); TextView fruitsName = (TextView) view.findViewById(R.id.fruit_name); fruitsImage.setImageResource(fruits.getImageId()); fruitsName.setText(fruits.getName()); return view; } }
- 这个适配器重写了父类的一组构造函数
- 重写了getView()方法,这个方法在每个子项被滚动到屏幕内的时候会被调用
点击事件
-
例子
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { Fruits fruits = fruitsList.get(position); Toast.makeText(MainActivity.this,fruits.getName(),Toast.LENGTH_SHORT).show(); } });
- 通过setOnItemClickListener()方法给listView注册一个监听器,当用户点击了ListView中任何一个子项的时候,会回调onItemClick方法
- 通过position参数判断出用户点击的是哪一个子项
RecyclerView
- 增强版的ListView
基本用法
-
需要先添加依赖(app/build.gradle)
implementation 'androidx.recyclerview:recyclerview:1.2.1'
-
添加recycleview控件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>