Android学习笔记(三)UI
16lz
2021-01-26
3. UI界面
3.1 常见控件
3.1.1 TextView
显示一段文本信息。默认左上角对齐。属性 | 释义 | 值 |
android:layout_width | 宽度(所有控件都有) | match_parent:当前控件大小与父布局一致 fill_parent:同match_parent一样,官方推荐match_parent wrap_content:当前控件大小正好能包含内容(由内容来决定) |
android:layout_height | 高度 (所有控件都有) | 同上 |
android:gravity | 文字对齐方式 | top、bottom、left、right、center等 , 可 以 用 “ | ” 来 同 时 指 定 多 个 值 |
android:textSize | 文字大小 | - |
android:textColor | 文字颜色 | - |
3.1.2 Button
按钮3.1.3 EditText
输入框控件属性 | 释义 | 值 |
android:hint | 输入框的提示信息(相当于H5的placeholder) | - |
android:maxLines | 指定最大行数 | 数字 |
3.1.4 ImageView
展示图片控件属性 | 释义 | 值 |
android:src | 指定图片 | - |
imageView.setImageResource(R.drawable.test);
3.1.5 ProgressBar
进度条属性 | 释义 | 值 |
android:visibility | 控件是否可见(所有控件都有) | visible:可见,默认值 invisible:不可见,但仍然占据原来的位置和大小(可理解为透明) gone:不仅不可见,而且不占用原有任何空间 |
android:max | 在给进度条添加如下属性的时候: style="?android:attr/progressBarStyleHorizontal", 该进度条就成了一个水平进度条。 此时设置此max属性表示最大值为多少,比如100 | - |
//设置可见性,还有View.GONE、View.INVISIBLEprogressBar.setVisibility(View.VISIBLE);//设置进度progressBar.setProgress(60);
3.1.6 AlertDialog
对话框,置顶于所有控件之上,屏蔽他们的交互能力。/** * 1.首先通过AlertDialog.Builder来创建一个AlertDialog实例 * 2.然后设置标题、内容、可否取消等属性 * 3. setPositiveButton()方法为对话框确定按钮设置文本以及事件 * 4. setNegativeButton()方法则为取消按钮设置文本及事件 */AlertDialog.Builder dialog=new AlertDialog.Builder(MainActivity.this);dialog.setTitle("This is a dialog");dialog.setMessage("Some thing want to show");dialog.setCancelable(false);dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { }});dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { }});dialog.show();
3.1.7 ProgressDialog
对话框进度条/** * 1.先创建一个ProgressDialog对象 * 2.同样设置标题、内容、是否可取消 * 3.设置setCancelable(false)后则不能按Back键关闭对话框 */ProgressDialog dialog=new ProgressDialog(MainActivity.this);dialog.setTitle("This is a progress dialog");dialog.setMessage("Please Loading ....");dialog.setCancelable(false);dialog.show();//可以调用此方法来关闭对话框//dialog.dismiss();
3.2 基本布局
3.2.1 线性布局(LinearLayout)
将所有其包含的控件在线性方向上依次排列,是一种非常常用的布局。属性 | 释义 | 值 |
android:orientation | 线性排列方向 | horizontal(水平方向)、vertical(垂直方向) |
android:layout_gravity | 控件在布局中的对齐方式 | 注意:当布局方向为horizontal时,只有垂直方向的对齐方式起作用 同理,当为vertical时,只有水平方向的起作用。 |
android:layout_weight | 使用比例来指定控件大小 | 比如一共有2个控件,一个设为3,另一个设为2,则第一个占3/5,第二个占2/5; 同理如果两个都想占一半,则每个设为1即可,即1/2 |
3.2.2 相对布局(RelativeLayout)
相对布局更加随意,通过相对定位的方式让控件出现在布局的任何位置。因此相对布局属性非常多,但有规律可循。属性 | 释义 | 值 |
android:layout_alignParentLeft | 相对父布局向左 | true、false |
android:layout_alignParentTop | 相对父布局向上 | true、false |
android:layout_alignParentRight | 相对父布局向右 | true、false |
android:layout_alignParentBottom | 相对父布局向下 | true、false |
android:layout_centerInParent | 相对父布局居中 | true、false |
android:layout_above | 让控件位于另一个控件上方,注意!该控件需要定义在另一个控件 后面,下同 | 需要指定参考的控件id引用,如:@id/button1 |
android:layout_below | 让控件位于另一个控件下方 | 同上 |
android:layout_toLeftOf | 让控件位于另一个控件左侧 | 同上 |
android:layout_toRightOf | 让控件位于另一个控件右侧 | 同上 |
android:layout_alignLeft | 让控件左边缘和另一个控件左边缘对齐 | 控件id的引用 |
android:layout_alignRight | 让控件右边缘和另一个控件右边缘对齐 | 同上 |
android:layout_alignTop | 让控件上边缘和另一个控件上边缘对齐 | 同上 |
android:layout_alignBottom | 让控件下边缘和另一个控件下边缘对齐 | 同上 |
3.2.3 FrameLayout
这种布局没有任何的定位方式,所有的控件都会摆放在布局的左上角。3.2.4 TableLayout
使用表格的方式来排列控件。 TableRow:一个3.3 自定义控件
3.3.1 引入布局
(1)新建一个布局title.xml (2)在主布局文件中添加引用,如下:@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 窗口无标题(别忘了继承自Activity才起作用) requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main);}
3.3.2 创建自定义控件
当一些布局中的控件要求能够响应事件时,比如标题栏的返回按钮,不管在哪个活动中,返回按钮的作用都是销毁当前活动,如果在每一个活动中都注册相同的事件,则又增加了冗余代码,此时自定义控件可以解决此问题。 (1)创建一个自定义控件布局类(这里还是使用标题栏TitleLayout),继承自LinearLayout类package com.jastar.uicustomviews.layout;import android.content.Context;import android.util.AttributeSet;import android.view.LayoutInflater;import android.widget.LinearLayout;import com.jastar.uicustomviews.R;public class TitleLayout extends LinearLayout { /** * 重写带有两个参数的构造函数,在布局中引入TitleLayout就会调用这个函数 * * @param context * @param attrs */ public TitleLayout(Context context, AttributeSet attrs) { super(context, attrs); /** * 1.通过LayoutInflater.from()方法构造一个LayoutInflater对象 * 2.通过该对象的inflate()来动态加载title.xml布局 * 3.inflater(要加载的布局文件id,给加载好的布局再指定一个父布局这里使用TitleLayout) */ LayoutInflater.from(context).inflate(R.layout.title, this); }}
(2)在布局文件中添加这个自定义控件
添加自定义控件和添加普通控件方式一样,只不过需要指定完整类名 (3)给按钮添加点击事件 public TitleLayout(Context context, AttributeSet attrs) { super(context, attrs); /** * 1.通过LayoutInflater.from()方法构造一个LayoutInflater对象 * 2.通过该对象的inflate()来动态加载title.xml布局 * 3.inflater(要加载的布局文件id,给加载好的布局再指定一个父布局这里使用TitleLayout) */ LayoutInflater.from(context).inflate(R.layout.title, this); //同样获取到按钮对象 Button btnBack = (Button) this.findViewById(R.id.title_back); Button btnEdit = (Button) this.findViewById(R.id.title_edit); btnBack.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //返回按钮销毁当前活动 ((Activity) getContext()).finish(); } }); btnEdit.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getContext(), "您点击了编辑按钮", Toast.LENGTH_SHORT).show(); } });}
这样的话,每当引入该布局文件,返回按钮和编辑按钮的事件已经写好,将被共用。 3.4 ListView控件(很常用)
3.4.1 简单使用
(1)在布局中添加ListView控件并指定id为list_view,宽高设为match_parent (2)在代码中使用:package com.jastar.listviewtest;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.ArrayAdapter;import android.widget.ListView;public class MainActivity extends AppCompatActivity { /** * ListView的数据是需要提前准备好的,无论是从数据库读的还是从哪里来的;这里模拟一些数据 */ private String[] data = {"Apple", "Banana", "Orange", "Watermelon", "Pear", "Grap", "Pineapple", "Strawberry", "Cherry", "Mango"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /** * 1.Android中的数组是无法直接传递给ListView的,需要借助适配器Adapter来实现 * 2.ArrayAdapter还算是比较好用的,可以指定泛型 * 3.构造函数需要参数,不同场景应该使用不同的构造函数,此处的参数依次为: * param1:当前上下文 * param2:ListView子项布局id,这是一个安卓内置的子项布局文件,里面只有一个TextView,简单显示文本即可 * param3:要适配的数据 */ ArrayAdapter adapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, data); ListView listView = (ListView) findViewById(R.id.list_view); //调用setAdapter方法,将适配器传入 listView.setAdapter(adapter); }}
3.4.2 定制ListView界面
定制ListView界面就是需要我们自定义ListView子项的布局(下面的例子实现列表名称前显示对应图片的功能) (1)新建Fruit实体类,有两个字段:name(水果名称),imageId(水果对应的图片id) (2)创建自定义子项布局fruit_item.xml<?xml version="1.0" encoding="utf-8"?>
(3)创建自定义适配器FruitAdapter类继承自ArrayAdapter类,指定Fruit实体类泛型 package com.jastar.listviewtest.Adapter;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.ImageView;import android.widget.TextView;import com.jastar.listviewtest.Entity.Fruit;import java.util.List;public class FruitAdapter extends ArrayAdapter { private int resourceId; /** * 重写父类构造方法,用于将上下文、ListView、子项布局的id和数据都传递进来 * * @param context 上下文 * @param textViewResourceId 子项布局Id * @param objects 数据 */ public FruitAdapter(Context context, int textViewResourceId, List objects) { super(context, textViewResourceId, objects); resourceId = textViewResourceId; } /** * 1.重写getView方法,该方法在每个子项被滚动到屏幕内的时候调用 * * @param position * @param convertView * @param parent * @return */ @Override public View getView(int position, View convertView, ViewGroup parent) { //通过getItem()获取当前项的实例 Fruit fruit = getItem(position); //使用LayoutInflater将该子项加载到我们传入的布局 View view = LayoutInflater.from(getContext()).inflate(resourceId, null); //获取子项布局中的控件 ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image); TextView fruitName = (TextView) view.findViewById(R.id.fruit_name); fruitImage.setImageResource(fruit.getImageId()); fruitName.setText(fruit.getName()); return view; }}
(4)在活动中使用 @Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化水果数据,模拟假数据 initFruitList(); FruitAdapter adapter = new FruitAdapter(MainActivity.this, R.layout.fruit_item, fruitList); ListView view = (ListView) findViewById(R.id.list_view); view.setAdapter(adapter);}private void initFruitList() { Fruit apple = new Fruit("Apple", R.drawable.fruit_apple_pic); fruitList.add(apple); //....}
3.4.3 提升ListView的运行效率
(1)优化加载布局的次数 在 FruitAdapter的getView()方法中每次都将布局重新加载了一遍,当ListView快速滚动的时候,效率会很低。 其实getView()还有一个参数没用到就是convertView,这个参数用于将之前加载好的布局进行缓存,以便重用。 修改FruitAdapter中的代码:(2)优化获取控件实例次数 在getView()方法中每次都会去findViewById()控件实例,可以借助ViewHolder来对这个问题优化。
3.4.4 ListView点击事件
@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //... view.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Fruit fruit = fruitList.get(position); Toast.makeText(MainActivity.this, "name:" + fruit.getName() + ",imageid:" + fruit.getImageId(), Toast.LENGTH_SHORT).show(); } });}
3.5 单位和尺寸
在布局文件中常用的单位有:px、pt、dp、sp px:像素 pt:磅数,1磅等于1/72英寸,一般pt作为字体的单位来使用px和pt在不同的分辨率手机上显示的效果是完全不相同的,所以这两个单位在手机领域上不适用。 因此,谷歌为Android引入了一套新的单位:dp、sp
dp:密度无关像素的意思,也被称作dip,和px相比,它在不同密度的屏幕中的显示比例保持一致。 sp:可伸缩像素的意思,采用了和dp同样的设计理念,解决文字大小适配问题。
密度: Android 中的密度就是屏幕每英寸所包含的像素数,通常以 dpi为单位。比如一个手机屏幕的宽是 2 英寸长是 3 英寸,如果它的分辨率是 320*480 像素,那这个屏幕的密度就是 160dpi,如果它的分辨率是640*960,那这个屏幕的密度就是 320dpi,因此密度值越高的屏幕显示的效果就越精细。 根据 Android 的规定,在 160dpi 的屏幕上,1dp 等于 1px,而在 320dpi 的屏幕上,1dp就等于 2px。
3.6 编写界面最佳实践
3.6.1 制作Nine-Patch图片(可拉伸图片)
Nine-Patch图片:是一种被特殊处理过的图片,能够指定哪些区域可以延伸。 比如: 有一张图片:当图片宽度不足以填充整个屏幕时,图片就会被均匀拉伸,成这样:
所以Nine-Patch图片就是为了解决这个问题。 (1)在Android sdk目录tools文件夹下,找到 draw9patch.bat 文件双击打开 (2)点击File→Open 9-patch将图片加载进来,如:
(3)可以在四周绘制黑线 上边框和左边框的黑线:表示当图片需要拉伸时就拉伸黑线部分的区域 有边框和下边框的黑线:可画可不画,表示内容绘制区域,说白了就是当有内容放置的时候只放到此区域内。 (4)点击导航File→Save 9-patch,就会生成一个特殊的后缀为“.9.png”的图片。
更多相关文章
- Android(安卓)RelativeLayout布局
- AndroidStudio插件:布局文件转化Databinding
- Android(安卓)SlidingMenu 布局实现
- Android(安卓)关于嵌套listView时onItemClick事件不响应的解决办
- 【Android】毫无耦合性,一个Item根布局搞定 item侧滑删除菜单,像IO
- Android(安卓)Gradle 指定 Module 打包
- API DEMO APPWIGHT 学习
- Android基础控件——EditText隐藏软键盘、Enter键隐藏软键盘、点
- Android(安卓)自定义Toolbar的Menu菜单