官方文档地址:http://developer.android.com/guide/topics/ui/declaring-layout.html

PS:API Guides里面的内容不免都简单些,翻译还是很渣,明明知道意思,但按着它的原话翻感觉就是很怪……

一个布局为用户接口定义了视觉上的结构,像activityapp widget的UI界面。你可以使用两种方式来声明布局:

  • 在XML中定义UI元素。Android提供了一个直截了当的XML词汇表,与那些小控件,布局的视图类以及它们的子类关联。
  • 在运行时实例化布局元素。你的应用可以通过编程的方式创建View和ViewGroup对象(并且操纵它们的属性)。
Android框架给你提供了极大的灵活性,你可以使用两种方式让你来声明,管理你的UI。比如说,你可以在XML中声明你应用的默认布局,包括要显示在屏幕上的元素和它们的属性。随后你可以在运行时的代码中修改它们的状态,包括那些已经在XML中声明的对象。
 
在XML中声明你的UI的好处是你可以更好的将应用的声明与应用的功能分开。你的UI的描述对于程序代码来说是额外的,这意味着,你可以不通过修改源代码或者重编译来修改或者适配它们。比如说,你可以为不同屏幕方向来创建XML布局,不同的设备屏幕尺寸,不同的语言。另外在XML中声明这些布局更容易让你看清UI的结构,这样就很容易发现bug。所以这篇文档着眼于教你如何在XML文件中声明布局。如果你对运行时实例化View对象比较有兴趣的话,请参考ViewGroupView的参考。
 
通常情况下,用来声明UI元素的XML词汇都遵循着类的命名规则与方法,这也包括那些类中的属性名。事实上,因为这样的关联,你可以直接猜到XML属性对应着类里面的哪一个方法,或者哪个类对应着哪一个XML元素。然而,你需要记住,不是所有的词汇都是对应的。在一些情况下,有一些少量的不同的命名。比如,EditText元素有text属性,这个属性关联着EditText.setText()。(译者注:text关联setText()很正常啊,这根本就不是反例啊……)
 
Tip:Common Layout Objects里学习更多有关于不同的布局类型。在Hello Views教程指南里,也有构建各种各样布局的教程。
 
编写XML文件(Write the XML)
通过使用Android的XML词汇,你可以快速的设计UI布局和屏幕中所包含的元素,如同通过HTML创建网页一——通过一系列内置的元素。
 
每个布局文件必须包含一个正确的根元素,它必须是一个View或者ViewGroup对象。当你定义好根元素之后,你可以添加额外的布局对象或者小控件作为他们的子元素,以此来构建View的层级结构。比如,下面的XML布局使用了一个垂直的LinearLayout包含了一个TextView和一个Button控件。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextViewandroid:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a TextView"/>
<Buttonandroid:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a Button"/>
</LinearLayout>
当你在XML中声明完你的布局,并以.xml后缀保存在Android项目的res/layout/目录下之后,它就会被正确的编译。
 
更多关于布局XML文件的语法可以参考Layout Resources文档。
 
载入XML资源(Load the XML Resource)
当你编译你的应用程序的时候,每一个XML文件会被编译成一个View资源。你应该通过你的程序代码载入布局文件资源,在你的Activity.onCreate()回调里实现。只要调用setContentView()就可以了,传递一个如下格式的布局资源的参数:R.layout.layout_file_name。如果你的XML布局文件保存为main_layout.xml,你应该在Activity中载入它,像这样:
publicvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
}
onCreate()回调方法是在Activity启动的时候由Android框架负责调用的(关于生命周期的讨论,请查看Activities文档)。
 
属性(Attributes)
每个View和ViewGroup对象支持众多的XML属性。一些属性是特定于一个View对象的(比如,TextView有textSize属性),但很多属性都是继承于它们的父类View。所以所有的View对象都是相似的,因为它们都继承于View类(比如所有的view都有id属性)。其它的一些属性像“layout parameters”,这些属性是用于描述View对象里面的具体的布局细节,方向灯,这些都是在父类ViewGroup中定义的。
 
ID
任何一个View对象都有一个整型的ID与之关联,使之在树中有唯一的标示符。当应用程序被编译的时候,ID将作为一个整型,但在XML布局文件中,ID属性通常都是一个字符串。这对大部分View对象都是通用的,你会经常使用到它,在XML标签里面,ID的语法如下:
android:id="@+id/my_button"
在字符串开头的at符号(@)指明XML解析器应该解析ID字符串剩下的部分并标示它为一个ID资源。加号(+)表示这是一个新的资源名,应该被创建并且添加到资源中去(在R.java文件中)。Android框架提供了一些ID资源。当你要引用Android资源ID,你不需要加上加号,但你必须要加上android包的命名空间,像这样:
android:id="@android:id/empty"
当我们使用android包命名空间的时候,我们正在使用一个来自android.R资源类的ID,而不是本地的资源类。
 
为了创建Views,并且能在程序里引用它们,通常是这样的模式:
1.在布局文件中定义一个view/widget,并注册一个唯一的ID:
<Buttonandroid:id="@+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/my_button_text"/>
2.然后创建一个view对象的实例,并从布局中捕获它(通常是在onCreate()方法中):
Button myButton =(Button) findViewById(R.id.my_button);
 
当使用RelativeLayout的时候,为view对象定义ID是非常重要的。在相对布局中,view对象定义它们的布局关系通过其它的view对象,这都必须引用唯一的ID。
 
在整个树中,ID不需要是唯一的,但是,你应该要确保在你搜寻的局部的树中,ID必须是唯一的。(通常都是搜寻整个树,所以最好的办法就是ID绝对唯一。)
 
布局参数(Layout Parameters)
XML布局属性都是叫layout_something的,这些属性定义了View在ViewGroup中的正确位置。
 
每个ViewGroup类都实现了内置的一个类ViewGroup.LayoutParams。这个子类包含了各种属性来定义子元素的大小和位置,使它们可以在正确的位置。如figure 1所示,父类view group为每一个子view都定义了布局参数(包括子view group)
 
记住没个LayoutParams子类都有自己的语法去设置值。每一个子元素必须定义LayoutParams用来适应它的父类,虽然这可能会为它自己的子元素定义不同的LayoutParams。
 
所有的view group都包含了宽度和高度(layout_width和layout_height),并且每一个view都必须定义这两个属性。大部分LayoutParams也有可选的外边距和边界。
 
你可以使用精确的值来指定宽度和高度,虽然你不会经常这么做的。通常你会使用下面的常量来设置宽度和高度:
  • wrap_content 告诉你的view,它的尺寸必须要包住里面的内容。
  • fill_parent(在API LEVEL 8 改名为match_parent) 告诉view必须要和父ViewGroup有一样的大小。
通常,使用绝对精确的单位,比如像素,来指定宽度和高度是不推荐的。取而代之的,我们使用与尺寸相关的单位,像像素无关单位 dp,wrap_content或者fill_parent是更好的选择,因为它能确保你的应用可以适应更多的设备的屏幕尺寸。允许的尺寸类型在Available Resources文档中定义。
 
布局位置(Layout Position)
View在几何学上都是矩形的。一个View有它的位置,通过左和上的坐标来确定,有两个尺寸,通过宽度和高度来指定。位置和尺寸的单位都是像素。
 
是可以通过调用View的getLeft()和getTop()方法来获取到View的位置的。前一个方法返回左,或者称为表示view的矩形的X坐标。后一个方法返回顶,或者view的矩形的Y坐标。这两个方法返回值都是与view的父级视图相关的,比如说:当getLeft()返回20,者意味着view位于它直接父级控件的左边缘偏右20像素的地方。
 
另外,一些方便的方法也提供给你了,避免无谓的计算,它们是getRight()和getBottom()。这两个方法返回view矩形的右边的坐标和底部的坐标。比如:调用getRight()就相当于如下的计算:getLeft() + getWidth()。
 
大小,内边距与外边距(Size, Padding and Margins)
一个view的大小是通过宽度和高度来指定的。一个view其实拥有两对宽度高度值。
 
第一对称为measured width和measured height。这两个尺寸定义了一个view它期望在它的父级控件中有多大。这两个尺寸可以通过getMeasuredWidth()getMeasuredHeight()来获取。
 
第二对就是所谓的width和height,有时候称之为drawing width和drawing height。这两个尺寸都是view在绘制和布局完成之后,在屏幕中的确切尺寸大小。这些值可能会与measured width 和 measured height 不同,但这不是绝对的。这两个值可以通过getWidth()getHeight()来获取。
 
为了去测量它的尺寸,一个View要把它的内边距算进去。内边距是一个view的上下左右,四个部分的值来表示的。内边距是用来偏移view里面内容的。比如说,左边距是2将会导致view里面的内容相对于view的左边缘向右偏移2像素,内边距可以通过setPadding(int, int, int, int)来设定,可以通过getPaddingLeft()getPaddingTop()getPaddingRight()getPaddingBottom()来获取。
 
虽然view可以定义内边距,但它不提供任何对外边距的支持。然而,ViewGroup提供这样的支持。查看ViewGroupViewGroup.MarginLayoutParams来获取更多信息。
 
更多关于尺寸的信息,请参考Dimension Values
 
常用的布局(Common Layouts)
每一个ViewGroup的子类都提供了一个唯一的方法去显示你内嵌于它里面的view。下面是一些比较常用的布局类型。
 
Note:虽然你可以嵌入一个或多个布局在另一个布局里面,以此来构建你的UI,但你应该让你的布局嵌套的少一点。如果你不用嵌套的布局,你的界面会被绘制的更快。(一个宽的视图结构比一个深的视图结构更好。)
 
Linear Layout
线性布局将它的子元素都单一的组织在水平方向或者垂直方向上。如果窗口的长度超过了屏幕了长度就创建一个滚动条。
 
Relative Layout
相对布局能让你通过指定彼此之间的相对位置来给子元素定位(A在B的左边)或者与父控件相关(与父控件的顶部对齐)。
 
Web View
显示web页面。
 
构建带适配器的布局(Building Layouts with an Adapter)
当你的布局里面的内容是动态的或者不是预先设定的,你可能会需要使用AdapterView的子类的布局对象,它可以在运行时填充新的视图进去。AdapterView类的子类使用一个Adapter来给它的布局绑定数据。Adapter是作用是作为数据源和AdapterView布局的中间人,Adapter获取数据(从数组或者数据库中)然后转换成一个view添加进AdapterView布局中。
 
常用的布局是:
List View
显示一个可以滚动的单行列表。
 
Grid View
显示一个可以滚动的网格列表。
 
给适配器视图填充数据(Filling an adapter view with data)
你可以通过给AdapterView视图,像ListView或者GridView,绑定一个适配器的实例来填充数据,它会从额外的数据源获取数据,并创建一个view用来填充。
 
Android提供一些Adapter的子类,它们非常的有用,可以获取不同类型的数据并为AdapterView构建视图。最常用的是:
 
     当你的数据源是一个数组的时候使用这个适配器。默认情况下,ArrayAdapter为每一个item创建一个视图,通过调用toString()来将内容放到一个TextView里面。
 
     比如,如果你有一组字符串想要显示在ListView,初始化一个ArrayAdapter,通过构造方法指定每一个String的布局和String数组:
ArrayAdapter adapter =newArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, myStringArray);
构造方法里的参数:
  • 你的应用的Context
  • 为字符串数组的每一项提供的包含一个TextView的布局。
  • 字符串数组
然后,简单的在你的ListView上调用setAdapter()方法即可:
ListView listView =(ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);
想要自定义每一项的输出,你可以为你的数组中的每一个对象覆写toString()。或者为每一项创建一个view,里面可能需要显示更多的东西,(比如,如果你希望在每一项里显示一个ImageView),继承ArrayAdapter然后覆写getView()方法,去返回一个自己想要的view对象。
 
     当你的数据来自一个Cursor对象的时候,你需要使用这个适配器。当使用SimpleCursorAdapter的时候,你必须指定一个布局供每一行使用。比如,如果你想要创建一个人名和电话的列表,你可以执行一个查询,返回的Cursor包含着每一个人的信息以及电话号码。然后,你需要创建一个字符串数组用来指定Cursor中的每一列都对应着布局中的那个view:
String[] fromColumns ={ContactsContract.Data.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER};
int[] toViews ={R.id.display_name, R.id.phone_number};
当你实例化SimpleCursorAdapter对象,传递为每一个结果准备布局,Cursor对象包含着结果,所有有两个数组:
SimpleCursorAdapter adapter =newSimpleCursorAdapter(this,
R.layout.person_name_and_number, cursor, fromColumns, toViews,0);
ListView listView = getListView();
listView.setAdapter(adapter);
SimpleCursorAdapter随后会为每一行都创建一个视图,把fromColums的数据都关联到toViews上面。
 
如果在你应用的生命内,你改变了适配器所绑定的数据源,你需要调用notifyDataSetChanged()方法。这个会通知它附着的视图数据已经改变了,它应该刷新自己。
 
处理点击事件(Handling click events)
你可以实现AdapterView.OnItemClickListener接口为每一项设置点击事件。比如:
// Create a message handling object as an anonymous class.
privateOnItemClickListener mMessageClickedHandler =newOnItemClickListener(){
publicvoid onItemClick(AdapterView parent,View v,int position,long id){
// Do something in response to the click
}
}; listView.setOnItemClickListener(mMessageClickedHandler);

[翻译]API Guides - Layouts的更多相关文章

  1. [翻译]API Guides - Bound Services

    官方文档原文地址:http://developer.android.com/guide/components/bound-services.html 一个Bound Service是一个客户端-服务器 ...

  2. [翻译]API Guides - Service

    官方文档原文地址:http://developer.android.com/guide/components/services.html Service是应用程序组件之一,它并不提供一个用户界面,可以 ...

  3. C# 调用百度翻译Api

    这是简单的界面.用的是wpf,winform也可以 具体的操作类 public partial class MainWindow : Window { string url = "" ...

  4. 基于百度翻译API开发属于自己的翻译工具

    你是否每天使用着网页翻译工具?你是否遇到过这种情况,上网过程中遇到一个很长的单词但是又不能复制,要开两个浏览器,一个打开百度翻译,照着另一个网页输入单词?你安装了各种翻译软件后,又删除,只因忍受不了那 ...

  5. Python 调用百度翻译API

    由于实习公司这边做的是日文app,有时要看看用户反馈,对于我这种五十音图都没记住的人,表示百度翻译确实还可以.但不想每次都复制粘贴啊,google被墙也是挺蛋疼的事,所以用python结合baidu ...

  6. Android API Guides 学习笔记---Application Fundamentals(一)

    今天开始学习google官网上的API guides ,主要读了Application Fundamentals这一章节,此章节介绍了一个App的基本组成,共包括四大部分内容. 1.      App ...

  7. [Python] 使用有道翻译API

    Python 使用youdao (有道翻译)API 想写一个给自己记录背单词状况的软件,需要获取英文单词的中文释义(基本功能).考虑使用有道翻译的API实现获取英文单词的中文释义的方法. 获取API_ ...

  8. 记微信开发(有道翻译api)

    记微信开发(有道翻译api) 记微信开发(有道翻译api) 效果: 有道翻译api申请: 地址:http://fanyi.youdao.com/openapi code: <?php/** * ...

  9. 有道翻译API

    轻奢侈品_百度百科 轻奢侈品 有道翻译API 有道翻译API申请成功 API key:72763558 keyfrom:lexus-studio

随机推荐

  1. 2014年第五届蓝桥杯B组(C/C++)预赛题目及个人答案(欢迎指正)

    参考:https://blog.csdn.net/qq_30076791/article/details/50573512 第3题: #include<bits/stdc++.h> usi ...

  2. 20155215 《Java程序设计》实验二( Java面向对象程序设计)实验报告

    20155215 <Java程序设计>实验二( Java面向对象程序设计)实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉 ...

  3. Android开发——支付宝和微信支付快速接入流程

    一.Android快速实现支付宝支付 1.首先,我们需要前往支付宝开放平台,申请我们的支付功能:https://open.alipay.com/platform/home.htm 支付宝首页 这里 有 ...

  4. spring_cloud多个微服务访问时偶发forward_error问题

    1.问题: 最近在做SpringBoot项目的时候,有多个分开的微服务,偶发forward error 问题 2.猜想: 个人理解为服务跳转错误,可能本身没找到目标服务,或者目标服务损坏 3.解决: ...

  5. 1722: [Usaco2006 Mar] Milk Team Select 产奶比赛

    1722: [Usaco2006 Mar] Milk Team Select 产奶比赛 https://www.lydsy.com/JudgeOnline/problem.php?id=1722 分析 ...

  6. XDS100V3连接Pandaboard ES OMAP4460开发板

    1. 硬件连接如下 2. 使用CCS创建工程,不过好像没有ARM9的内核吧?为啥会出现? 3. 创建目标配置文件 4. 不过确实有ARM9的内核,两个A9内核,一个DSP C64X内核,两个M3的内核 ...

  7. python基础数据类型补充

    python_day_7 一. 今日主要内容: 1. 补充基础数据类型的相关知识点 str. join() 把列表变成字符串 列表不能再循环的时候删除. 因为索引会跟着改变 字典也不能直接循环删除.把 ...

  8. jenkins升级为2.134

    由于前面装的jenkins版本为2.130版本,昨天(2018.7.26)发现了两个jenkins的漏洞,影响范围为:Jenkins weekly 2.132 以及更早的版本.Jenkins LTS ...

  9. MySQL事务、并发问题、锁机制

    MySQL事务,并发问题,锁机制 1.什么是事务 事务是一条或多条数据库操作语句的组合,具备ACID,4个特点. 原子性:要不全部成功,要不全部撤销 隔离性:事务之间相互独立,互不干扰 一致性:数据库 ...

  10. leetcode26_C++删除排序数组中的重复项

    给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 1 ...