【转】代码控制UI,View
【转】Android 步步为营 第5营 代码控制UI,View
在前面的几讲中,我们都是使用xml layout 来去控制UI组件,其实我们也可以完全抛开XML,用纯代码来控制我们的界面UI。
回顾我们学过的,遇到过的UI组件,有容器类的Layout:LinearLayout,RelativeLayout等, 也有视图类UI:TextView, EditText, Button, ImageView等。对应到代码中,我们会发现,他们都是View子类,具体关系如下:
Tips:在Eclipse中,可以用Ctrl+T键来查看某个类的类层次关系:
ViewGroup 与View 的关系,是一个典型的“组合”设计模式。
我们来用代码,实现一个简单的UI布局:
只有一个EditText和一个Button, 看看代码是怎么写的:

public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); LinearLayout container = new LinearLayout(this);
container.setOrientation(LinearLayout.HORIZONTAL); this.setContentView(container); EditText content = new EditText(this);
content.setHint("写点什么吧...");
Button submit = new Button(this);
submit.setText("发送"); container.addView(content);
container.addView(submit); }
}

我们来分析一下代码,
不管LinearLayout, EditText 还是Button, 他们的构造函数都是this. 其实查看源码后我们发现,所有的View及其子类的构造都至少包含三个构造方法:
public View(Context context) public View(Context context, AttributeSet attrs) public View(Context context, AttributeSet attrs, int defStyle)
后两个是为XML layout 定义的,用代码创建View时,一般都是用第一个构造函数,这里用this, 是因为Activity其实就是Context的子类。
this.setContentView()这个方法,以前我们都是传一个R.layout进去,其实它有多个重载,也可以直接传入根视图View。
这里的线性布局container 就是根视图(容器视图),要往容器视图里面添加View,使用addView方式,addView 方法有几个重载版本:
public void addView(View child)
public void addView(View child, int index)
public void addView(View child, int index, LayoutParams params)
public void addView(View child, int width, int height)
public void addView(View child, LayoutParams params)
LayoutParams 我们之后会讲到。
总结一下,用代码添加UI组件的步骤是:
- New 组件对应的类;
- 把它添加到父容器中。
运行结果就如上图的一样。你也许会想到,不是说width, height是必须的吗?怎么没有设置也可以啊?是因为,addView默认使用wrap_content.
但是光是这样不够,我们还想添加边距,权重等。
为View指定LayoutParams
添加宽,高,边距,权重这些属性,对应的类是LayoutParams,它一般都是作为一个内部类出现在某个ViewGroup的子类中。对于线性布局,我们使用LinearLayout.LayoutParams,
weight, leftMargin, rightMargin…..这些属性都在它的公有变量里面。

LinearLayout.LayoutParams contentLayoutParams = new LinearLayout.LayoutParams(0,
LinearLayout.LayoutParams.WRAP_CONTENT);
contentLayoutParams.weight = 1;
contentLayoutParams.leftMargin = 10; container.addView(content, contentLayoutParams); LinearLayout.LayoutParams buttonLayoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
buttonLayoutParams.leftMargin = 10;
container.addView(submit, buttonLayoutParams);

在addView之前,我们设置好LayoutParams 的值,调用addView(View child, LayoutParams params)这个重载方法。
相对布局的RelativeLayout.LayoutParams
我们来看看, 在代码中,调用那些方法来定位布局
因为在相对布局中, 定位的方法有很多种类,所以API提供了一个统一的方法:
addRule(int verb, int anchor)
addRule(int verb)
verb是动词的意思,就是用来表达above, below, toRightOf, toLeftOf, alignParentLeft…..等等。
这些动词的int 值在RelativeLayout下有常量定义。例如:
RelativeLayout.ABOVE
RelativeLayout.BELOW
RelativeLayout.ALIGN_LEFT
RelativeLayout.LEFT_OF
RelativeLayout.RIGHT_OF
anchor的值,可以是RelativeLayout.TRUE,0表示false, 或者其它View 的Id, 根据具体的verb, 填入相应的值:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); this.setContentView(this.addRelativeLayout());
} private RelativeLayout addRelativeLayout() {
RelativeLayout container = new RelativeLayout(this);
Button btn1 = new Button(this);
btn1.setId(11);
btn1.setText("上");
Button btn2 = new Button(this);
btn2.setId(12);
btn2.setText("下");
Button btn3 = new Button(this);
btn3.setId(13);
btn3.setText("左");
Button btn4 = new Button(this);
btn4.setId(14);
btn4.setText("右");
Button btn5 = new Button(this);
btn5.setId(15);
btn5.setText("中");
RelativeLayout.LayoutParams lp1 = new RelativeLayout.LayoutParams(100,
RelativeLayout.LayoutParams.WRAP_CONTENT); RelativeLayout.LayoutParams lp2 = new RelativeLayout.LayoutParams(lp1);
RelativeLayout.LayoutParams lp3 = new RelativeLayout.LayoutParams(lp1);
RelativeLayout.LayoutParams lp4 = new RelativeLayout.LayoutParams(lp1);
RelativeLayout.LayoutParams lp5 = new RelativeLayout.LayoutParams(lp1);
lp5.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE); lp1.addRule(RelativeLayout.ABOVE, btn5.getId());
lp1.addRule(RelativeLayout.ALIGN_LEFT, btn5.getId());
lp2.addRule(RelativeLayout.BELOW, btn5.getId());
lp2.addRule(RelativeLayout.ALIGN_LEFT, btn5.getId());
lp3.addRule(RelativeLayout.LEFT_OF, btn5.getId());
lp3.addRule(RelativeLayout.ALIGN_BASELINE, btn5.getId());
lp4.addRule(RelativeLayout.RIGHT_OF, btn5.getId());
lp4.addRule(RelativeLayout.ALIGN_TOP, btn5.getId()); container.addView(btn5, lp5);
container.addView(btn1, lp1);
container.addView(btn2, lp2);
container.addView(btn3, lp3);
container.addView(btn4, lp4); return container;
}

注意:LayoutParams的构造函数也可以是另外一个已经存在的LayoutParams对象,他的width, height值被克隆到当前对象中去。
FrameLayout, TableLayout的LayoutParams, 读者可自行研究一下。
【转】代码控制UI,View的更多相关文章
- 使用XML文件和Java代码控制UI界面
Android推荐使用XML文件设置UI界面,然后用Java代码控制逻辑部分,这体现了MVC思想. MVC全名是Model View Controller,是模型(model)-视图(view)-控制 ...
- Android学习笔记(9):使用XML文件和Java代码控制UI界面
Android推荐使用XML文件设置UI界面.然后用Java代码控制逻辑部分,这体现了MVC思想. MVC全名是Model View Controller.是模型(model)-视图(view)-控制 ...
- 用代码控制UI界面
public class MainActivity extends Activity { //当第一次创建Activity时回调该方法 @Override protected void ...
- Android学习:代码控制UI界面示例
package allegro.test2; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; im ...
- Android——控制UI界面
一.使用XML布局文件控制UI界面 res\layout\activity_main.xml代码如下: <FrameLayout xmlns:android="http://schem ...
- 【iOS 开发】iOS 开发 简介 (IOS项目文件 | MVC 模式 | 事件响应机制 | Storyboard 控制界面 | 代码控制界面 | Retina 屏幕图片适配)
一. iOS 项目简介 1. iOS 文件简介 创建一个 HelloWorld 项目, 在这个 IOS 项目中有四个目录 : 如下图; -- HelloWorldTests 目录 : 单元测试相关的类 ...
- Android控制UI界面
⒈使用XML布局文件控制UI界面[推荐] Android推荐使用XML布局文件来控制视图,这样不仅简单.明了,而且可以将应用的视图控制逻辑从Java或Kotlin代码中分离出来,放入XML文件中控制, ...
- 使用XML布局文件和Java代码混合控制UI界面
完全使用Java代码来控制UI界面不仅烦琐.而且不利于解耦:而完全利用XML布局文件来控制UI界面虽然方便.便捷,但难免有失灵活.因此有些时候,可能需要混合使用XML布局文件和代码来控制UI界面. 当 ...
- 在代码中控制UI界面
虽然Android推荐使用XML布局文件来控制UI界面,但如果开发者愿意,Android允许开发者完全抛弃XML布局文件,完全在Java代码中控制UI界面. 实例:用编程的方式开发UI界面 packa ...
随机推荐
- IOS微信中看文章跳转页面后点击返回无效
经过查找原因发现,下面两种链接,链接1返回不了,链接2可以返回. 链接1:http://mp.weixin.qq.com/s?__biz=MzA5NDY5MzcyNA==&mid=265089 ...
- hihocoder 1038 01背包
#1038 : 01背包 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 且说上一周的故事里,小Hi和小Ho费劲心思终于拿到了茫茫多的奖券!而现在,终于到了小Ho领取奖励 ...
- 设置transparent是否多此一举
在css是设置中我们经常会用到background:transparent这一属性设置,表示背景透明.但是background默认的颜色就是透明的!那么设置是否属于多此一举呢?我们浏览网页时经常见到“ ...
- jQuery API 3.1.0 速查表-打印版
jQuery API 3.1.0 速查表-打印图,(API来自:http://jquery.cuishifeng.cn/index.html)
- Swift类型检查与转换
继承会发生在子类和父类中,如图所示,是一系列类的继承关系类图,Person是类层次结构中的根类,Student是Person的直接子类,Worker是Person的直接子类.这个继承关系类图的具体实现 ...
- Mingw64编译wxWidgets3.0.2常见错误
使用Mingw64编译wxWidgets3.0.2,首先得下载wxMSW-Setup-3.0.2.exe(https://sourceforge.net/projects/wxwindows/file ...
- 用JS实现回文数的精准辨别!!!
笔者最近在一边看<JS高级程序设计3>一边在FCC上找题目练习啊.那叫一个爽.这不,刚刚用生命在课堂,寝室,实验室,图书馆等各种场所将第五章"引用类型"搞定,FCC便知 ...
- gdb/valgrind/coredump to debug c/cpp program
gdb/valgrind/coredump 调试 1.gdb 调试 while/for 循环 ①如果在调试 while/for的时候,可以用until xxx(其中,xxx代表 行号)直接跳转到循环后 ...
- JDK中工具类的使用
JDK中内置了很多常用的工具类,且多以“s”结尾,如:集合工具类Collections,数组工具类Arrays,对象工具类Objects,文件工具类Files,路径工具类Paths,数学工具类Math ...
- Ueditor设置默认字体
其实很简单,只需要将ueditor.all.js 以及 ueditor.all.min.js 两个文件中的字体改掉即可 修改方法: 在ueditor.all.js中搜索:设置默认字体和字号: 在ued ...