《第一行代码》读书笔记(二)----UI开发(上)

来源:互联网 发布:mmd 动作数据 r 18 编辑:程序博客网 时间:2024/05/19 14:51

常用控件的使用方法

TextView

  • android:layout_width: 指定宽度
  • android:layout_height: 指定高度
    • 这两个属性是每个控件都必须有的, 通常可选值有match_parent(大小有父布局指定)和wrap_content(大小由内容指定), 也可以写固定值, 但是这样写屏幕适配会有问题.
  • android:gravity: 指定文字的大小
    • 可选的值一看便知. 可以用 | 来同时指定多个值.
  • android:text: 指定文字内容
  • android:textSize: 指定文字大小
  • android:textColor: 指定文字颜色

Button

按钮的注册监听有三种实现方式:

第一种是在布局文件中为Button设置一个android:onClick属性, 属性的值为方法名, 在所在的活动中public void 方法名(View view){}来实现.

第二种是在活动中使用匿名内部类的方式注册监听:

public class MainActivity extends Activity {    private Button button;    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        button = (Button) findviewById(R.id.button);        button.setonClickListener(new onClickListener() {            public void onClick(View v) {                //在此添加逻辑...            }        });    }   }

第三种是让活动实现onClickListener接口, 这么做的好处是, 可以把不同按钮的处理逻辑写在一个函数里, 看起来更为清晰一些:

public class MainActivity extends Activity implements View.OnClickListener {    private Button button1;    private Button button2;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        button1 = (Button) findViewById(R.id.btn1);        button2 = (Button) findViewById(R.id.btn2);        button1.setOnClickListener(this);        button2.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.btn1:                Toast.makeText(this, "btn1", Toast.LENGTH_SHORT).show();                break;            case R.id.btn2:                Toast.makeText(this, "btn2", Toast.LENGTH_SHORT).show();        }    }}

EditText

  • android:hint: 提示性的文字
  • android:maxLines: 指定EditText最大行数, 超过时, 文本会向上滚动.

ImageView

  • android:src: 为ImageView指定图片, Android Studio 的值为”@mipmap/..”

ProgressBar

在界面上显示一个进度条.
* android:visibility: 设置可见属性. 所有控件都具有这个属性.
* 可选的值有3个, visible(可见, 默认), invisible(不可见, 但还占据屏幕空间, 可理解为透明了), gone(不可见, 不占据屏幕).
* 通过代码设置可见性, 使用setVisibility()方法, 可以传入View.VISIBLE, View.INVISIBLE, View.GONE 三种值.
* android:max: 给进度条设置最大值.
* style: 可以给进度条设置样式. 比如style:"?android:attr/progressBarStyleHorizontal"
* 代码中可以使用getProgress()和setProgress()方法来获取和修改进度.比如

int progress = progressBar.getProgress();progress = progress + 10;progressBar.setProgress(progress);

AlertDialog

在当前界面弹出一个对话框, 置顶于其他元素之上, 屏蔽其他控件的交互能力. 一般用户提示非常重要的内容或者警告信息. 这个控件不是在布局文件里写的, 要在活动的代码中添加, 比如按一个按钮弹出对话框:

case R.id.btn4:    AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);    dialog.setTitle("This is Dialog");    dialog.setMessage("Sth important");    dialog.setCancelable(true);//可否被取消(按Back键或者触摸屏幕其他区域)    dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {        @Override        public void onClick(DialogInterface dialog, int which) {        }    });    dialog.setNegativeButton("Cancle", new DialogInterface.OnClickListener() {        @Override        public void onClick(DialogInterface dialog, int which) {        }    });    dialog.show();//注意别忘了show, 不然没效果.    break;

ProgressDialog

与AlertDialog类似, 不同的是它会在对话框中显示一个进度条, 用于表示当前操作比较耗时,需要用户等待. 写在活动的代码中:

case R.id.btn5:    ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);    progressDialog.setTitle("This is ProgressDialog");    progressDialog.setMessage("Loading");    progressDialog.setCancelable(true);    progressDialog.show();    break;

四种基本布局

布局是一种容器, 可以放置多种控件, 也可以放置布局, 通过多层布局的嵌套, 可以实现一些比较复杂的界面.

LinearLayout

将所包含的控件在线性方向上依次排列.

  • 通过android:orientation属性来指定方向. 如不指定, 默认是horizontal.
    • 如果是horizontal, 内部控件的宽度不能指定为match_parent.
    • 如果是vertical, 内部控件的高度不能指定为match_parent.
  • android:layout_gravity: 指定控件在布局中的对齐方式.
    • android:gravity是指定文字在控件中的对齐方式. 注意区别.
    • 方向是horizontal时, 只有垂直方向上的对齐方式才有效.
    • 方向是vertical时, 只有水平方向上的对齐方式才有效.
  • android:layout_weight: 使用比例的方式来指定控件的大小. 手机适配.
    • 如果是horizontal, 内部控件的宽度设置为0dp.
    • 如果是vertical, 内部控件的高度设置为0dp.
    • 表示按权重分配剩余空间, 比如有两个控件, 一个要占3/5, 一个要占2/5, 则将它们的layout_weight分别设置为3和2.

RelativeLayout

通过相对定位的方式让控件出现在布局的任何位置.

相对于父布局进行定位的属性(组合使用):
* android:alignParentLeft
* android:alignParentRight
* android:alignParentTop
* android:alignParentBottom
* android:centerInParent
以上属性可选值true或者false.

相对于控件进行定位的属性(组合使用):
* android:layout_above
* android:layout_below
* android:layout_toLeftOf
* android:layout_toRightOf
* android:layout_alignLeft: 让一个控件左边缘与另一个控件的左边缘对齐.
* android:layout_alignRight
* android:layout_alignTop
* android:layout_alignBottom
以上属性的值为某个控件的id. 注意, 在 Eclipse 环境下, 要先定义好要引用的控件, 不然会找不到这个控件的id, 但是在 Android Studio 下则不必这样.

FrameLayout

这种布局没有任何的定位方式, 所有空间都会摆放在布局的左上角. 应用场景并不多, 在碎片中会用到.

TableLayout

不常用, 使用表格的方式来排列控件.
* <TableRow>: 表示添加了一行, 在里面加入一个控件, 就表示添加了该行的一列. 注意, 在<TableRow>里面的控件是不能指定宽度的.
* android:layout_span: 表示让某个控件占据几列的空间. 值为整数.
* android:inputType: 在EditText中指定输入文本的类型, 如textPassword表示密码.
* android:stretchColumns: 表示拉伸某一列. 如果指定为0, 则拉伸第一列; 指定为1, 则拉伸第二列. 解决屏幕适配问题(因为TableLayout中的控件不能指定宽度), 这个属性要写在根节点中.

自定义控件

控件和布局的继承结构

所有控件都继承View, 所有布局都继承ViewGroup.

View: Android中最基本的UI组件. 在屏幕上绘制一块矩形区域, 并能响应这块区域的各种事件.

ViewGroup: 一种特殊的View, 可以包含很多子View和子ViewGroup, 用于放置控件和布局的容器.

引入布局

首先新建一个标题栏布局文件title.xml, 包含一个TextView展示文字, 和两个Button分别表示Back和Edit, 代码如下:

<?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="wrap_content"    android:background="@mipmap/title_bg">    <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="@mipmap/back_bg"        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_gravity="center"        android:layout_margin="5dp"        android:background="@mipmap/edit_bg"        android:text="Edit"        android:textColor="#fff"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /></LinearLayout>
  • android:background: 为布局或者控件指定背景, 可以用颜色或者图片填充.
  • android:layout_margin: 指定控件在上下左右四个方向上偏移的距离.

如果要在其他布局文件中使用这个标题栏, 只要一行代码引入这个布局就可以了:

<include layout="@layout/title" />

创建自定义控件

单单引入布局在某些需求下还是不够的, 比如有一些控件要响应事件, 这些事件的功能在哪一个活动中的功能都是相同的, 如果只引入布局, 那么还要在每个活动中都添加响应事件的代码, 造成大量重复. 而自定义控件可以解决这个问题.

新建一个类 TitleLayout 继承自 LinearLayout :

public class TitleLayout extends LinearLayout {    public TitleLayout(Context context, AttributeSet attrs) {        super(context, attrs);        LayoutInflater.from(context).inflate(R.layout.title, this);        Button titleBack = (Button) findViewById(R.id.title_back);        Button titleEdit = (Button) findViewById(R.id.title_edit);        titleBack.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                //getContext()返回Context对象, 强转成Activity                ((Activity) getContext()).finish();            }        });        titleEdit.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(getContext(), "You clicked Edit button", Toast.LENGTH_SHORT).show();            }        });    }}

重写一个构造函数, 在布局中引入TitleLayout控件就会调用这个构造函数. LayoutInflater 的 from() 方法构建出一个LayoutInflater 对象, 然后调用inflate() 方法动态加载布局文件, 这个方法两个参数, 第一个是布局文件的 id, 第二个是给加载好的布局再添加一个父布局, 传入 this .然后为这个控件添加响应事件.

自定义控件写好了, 如何在布局文件中添加呢? 与添加普通控件方式差不多, 但是需要指定完整的类名, 不可以省略包名. 在Android Studio 中, 我没找到复制一个类的完整类名的方法, 但是在布局文件中直接键入就会有提示, 确实比Eclipse效率高, 嘿嘿嘿嘿.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    >    <me.zipstream.uicustomviews.TitleLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        ></me.zipstream.uicustomviews.TitleLayout></LinearLayout>
0 0