Android官方文档—User Interface(Layouts)(概述)

Layouts


布局定义用户界面的可视结构,例如活动或应用程序窗口小部件的UI。您可以通过两种方式声明布局:

  • 以XML格式声明UI元素。 Android提供了一个简单的XML词汇表,它对应于View类和子类,例如小部件和布局的类。
  • 在运行时实例化布局元素。您的应用程序可以以编程方式创建View和ViewGroup对象(并操纵其属性)。

Android框架使您可以灵活地使用这些方法中的一种或两种来声明和管理应用程序的UI。例如,您可以用XML声明应用程序的默认布局,包括将出现在其中的屏幕元素及其属性。然后,您可以在应用程序中添加代码,这些代码将在运行时修改屏幕对象的状态,包括以XML格式声明的对象。您还应该尝试使用层次结构查看器工具来调试布局 - 它会显示布局属性值,在模拟器或设备上调试时绘制带有填充/边距指示符的线框和完整的渲染视图。layoutopt工具可让您快速分析布局和层次结构,以解决效率低下或其他问题。

在XML中声明UI的优点是,它使您能够更好地将应用程序的表示与控制其行为的代码分开。您的UI描述是应用程序代码的外部描述,这意味着您可以修改或修改它,而无需修改源代码并重新编译。例如,您可以为不同的屏幕方向,不同的设备屏幕大小和不同的语言创建XML布局。此外,使用XML声明布局可以更容易地可视化UI的结构,因此调试问题更容易。因此,本文档重点介绍如何使用XML声明布局。如果您对在运行时实例化View对象感兴趣,请参阅ViewGroup和View类引用。

通常,用于声明UI元素的XML词汇表紧密遵循类和方法的结构和命名,其中元素名称对应于类名称,属性名称对应于方法。实际上,对应关系通常是如此直接,以至于您可以猜测XML属性对应于类方法,或猜测哪个类对应于给定的XML元素。但请注意,并非所有词汇都相同。在某些情况下,存在轻微的命名差异。例如,EditText元素具有与EditText.setText()对应的text属性。

  • 您还应该尝试使用层次结构查看器工具来调试布局 - 它会显示布局属性值,在模拟器或设备上调试时绘制带有填充/边距指示符的线框和完整的渲染视图。
  •     layoutopt工具可让您快速分析布局和层次结构,以解决效率低下或其他问题。

提示:了解有关Common Layout Objects中不同布局类型的更多信息。

编写XML


使用Android的XML词汇表,您可以快速设计UI布局及其包含的屏幕元素,就像使用HTML创建网页一样 - 使用一系列嵌套元素。

每个布局文件必须只包含一个根元素,该元素必须是View或ViewGroup对象。定义根元素后,可以添加其他布局对象或窗口小部件作为子元素,以逐步构建定义布局的视图层次结构。例如,这是一个XML布局,它使用垂直LinearLayout来保存TextView和Button:

<?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"
              android:orientation="vertical" >
    <TextView android:id="@+id/text"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="Hello, I am a TextView" />
    <Button android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello, I am a Button" />
</LinearLayout>

在用XML声明布局后,在Android项目的res / layout /目录中保存扩展名为.xml的文件,以便正确编译。

有关布局XML文件语法的更多信息,请参阅“布局资源”文档。

加载XML资源


加载XML资源

编译应用程序时,每个XML布局文件都会编译为View资源。您应该在Activity.onCreate()回调实现中从应用程序代码加载布局资源。这样做是通过调用setContentView(),以以下形式将引用传递给您的布局资源:R.layout.layout_file_name。例如,如果您的XML布局保存为main_layout.xml,则可以为您的Activity加载它,如下所示:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_layout);
}

当您的Activity启动时,您的Activity中的onCreate()回调方法由Android框架调用(请参阅活动文档中有关生命周期的讨论)。

属性


每个View和ViewGroup对象都支持各种XML属性。某些属性特定于View对象(例如,TextView支持textSize属性),但这些属性也可由任何可扩展此类的View对象继承。有些对于所有View对象都是通用的,因为它们是从根View类继承的(就像id属性一样)。并且,其他属性被视为“布局参数”,它们是描述View对象的某些布局方向的属性,由该对象的父ViewGroup对象定义。

ID

任何View对象都可以具有与之关联的整数ID,以唯一标识树中的View。编译应用程序时,此ID被引用为整数,但ID通常在布局XML文件中作为字符串在id属性中指定。这是所有View对象(由View类定义)共有的XML属性,您将经常使用它。 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,而不是本地资源类。

为了创建视图并从应用程序引用它们,常见的模式是:

1.在布局文件中定义视图/窗口小部件并为其分配唯一的ID:

<Button android:id="@+id/my_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/my_button_text"/>

2.然后创建视图对象的实例并从布局中捕获它(通常在onCreate()方法中):

Button myButton = (Button) findViewById(R.id.my_button);

创建RelativeLayout时,定义视图对象的ID非常重要。在相对布局中,兄弟视图可以相对于另一个兄弟视图定义其布局,该视图由唯一ID引用。

ID在整个树中不一定是唯一的,但它在您正在搜索的树的部分内应该是唯一的(通常可能是整个树,因此在可能的情况下最好是完全唯一的)。

布局参数


名为layout_something的XML布局属性定义适合其所在ViewGroup的View的布局参数。

每个ViewGroup类都实现一个扩展ViewGroup.LayoutParams的嵌套类。此子类包含定义每个子视图的大小和位置的属性类型,适用于视图组。如图1所示,父视图组定义了每个子视图(包括子视图组)的布局参数。

图1.具有与每个视图关联的布局参数的视图层次结构的可视化。

请注意,每个LayoutParams子类都有自己的设置值的语法。每个子元素必须定义适合其父元素的LayoutParams,尽管它也可以为自己的子元素定义不同的LayoutParams。

所有视图组都包含宽度和高度(layout_width和layout_height),每个视图都需要定义它们。许多LayoutParams还包括可选的边距和边框。

您可以使用精确测量指定宽度和高度,但您可能不希望经常这样做。更常见的是,您将使用这些常量之一来设置宽度或高度:

  • wrap_content告诉您的视图将自身大小调整为其内容所需的维度。
  • match_parent告诉您的视图变得与其父视图组允许的一样大。

通常,不建议使用绝对单位(如像素)指定布局宽度和高度。相反,使用相对度量(如密度无关像素单位(dp),wrap_content或match_parent)是一种更好的方法,因为它有助于确保应用程序在各种设备屏幕大小上正确显示。可接受的测量类型在可用资源文档中定义。

布局位置


视图的几何形状是矩形的几何形状。视图具有一个位置,表示为一对左坐标和顶坐标,以及两个维度,表示为宽度和高度。位置和尺寸的单位是像素。

可以通过调用getLeft()和getTop()方法来检索视图的位置。前者返回表示视图的矩形的左坐标或X坐标。后者返回表示视图的矩形的顶部或Y坐标。这些方法都返回视图相对于其父级的位置。例如,当getLeft()返回20时,这意味着视图位于其直接父级左边缘右侧20像素处。

此外,还提供了几种方便的方法来避免不必要的计算,即getRight()和getBottom()。这些方法返回表示视图的矩形的右边和底边的坐标。例如,调用getRight()类似于以下计算:getLeft()+ getWidth()。

尺寸,填充和边距


视图的大小用宽度和高度表示。视图实际上具有两对宽度和高度值。

第一对称为测量宽度和测量高度。这些维度定义了视图在其父级中的大小。可以通过调用getMeasuredWidth()和getMeasuredHeight()来获取测量的维度。

第二对简称为宽度和高度,有时也称为绘图宽度和绘图高度。这些尺寸定义了屏幕上,绘图时和布局后视图的实际大小。这些值可以但不必与测量的宽度和高度不同。可以通过调用getWidth()和getHeight()来获得宽度和高度。

要测量其尺寸,视图会考虑其填充。填充以视图的左,上,右和底部分的像素表示。填充可用于将视图的内容偏移特定数量的像素。例如,左边的填充为2会将视图的内容推到左边缘右侧2个像素。可以使用setPadding(int,int,int,int)方法设置填充,并通过调用getPaddingLeft(),getPaddingTop(),getPaddingRight()和getPaddingBottom()来查询。

即使视图可以定义填充,它也不会为边距提供任何支持。但是,视图组提供了这样的支持。有关详细信息,请参阅ViewGroup和ViewGroup.MarginLayoutParams。

有关尺寸的更多信息,请参阅尺寸值。

常见布局


ViewGroup类的每个子类都提供了一种独特的方式来显示嵌套在其中的视图。以下是Android平台内置的一些更常见的布局类型。

注意:虽然您可以在另一个布局中嵌套一个或多个布局来实现UI设计,但您应该尽量使布局层次结构尽可能浅。如果嵌套布局较少,则布局绘制速度更快(宽视图层次结构优于深层视图层次结构)。

Linear Layout

将子项组织为单个水平或垂直行的布局。如果窗口的长度超过屏幕的长度,它会创建一个滚动条。

Relative Layout

使您可以指定子对象相对于彼此的位置(子B的左侧的子A)或父对象的位置(与父对象的顶部对齐)。

Web View

显示网页。

使用适配器构建布局


当布局的内容是动态的或未预先确定的时,您可以使用子类AdapterView在运行时使用视图填充布局的布局。 AdapterView类的子类使用适配器将数据绑定到其布局。适配器充当数据源和AdapterView布局之间的中间人 - 适配器检索数据(来自诸如数组或数据库查询之类的源)并将每个条目转换为可添加到AdapterView布局中的视图。

适配器支持的常见布局包括:

List View

显示滚动的单列列表。

Grid View

显示列和行的滚动网格。

使用数据填充适配器视图

您可以通过将AdapterView实例绑定到适配器来填充AdapterView(如ListView或GridView),该适配器从外部源检索数据并创建表示每个数据条目的View。

Android提供了几个Adapter的子类,可用于检索不同类型的数据和构建AdapterView的视图。两种最常见的适配器是:

ArrayAdapter

当数据源是数组时,请使用此适配器。默认情况下,ArrayAdapter通过在每个项目上调用toString()并将内容放在TextView中来为每个数组项创建一个视图。

例如,如果要在ListView中显示要显示的字符串数组,请使用构造函数初始化新的ArrayAdapter,以指定每个字符串和字符串数组的布局:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1, myStringArray);

这个构造函数的参数是:

  • 你的应用上下文
  • 包含数组中每个字符串的TextView的布局
  • 字符串数组

然后只需在ListView上调用setAdapter():

ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);

要自定义每个项目的外观,可以覆盖数组中对象的toString()方法。或者,要为除TextView之外的其他项创建视图(例如,如果您希望每个数组项都有ImageView),请扩展ArrayAdapter类并覆盖getView()以返回每个项所需的视图类型。

SimpleCursorAdapter

当数据来自Cursor时,请使用此适配器。使用SimpleCursorAdapter时,必须指定要用于Cursor中每一行的布局,以及Cursor中的哪些列应插入到布局的哪些视图中。例如,如果要创建人员姓名和电话号码列表,则可以执行一个查询,该查询返回包含每个人的行的Cursor以及名称和数字的列。然后创建一个字符串数组,指定布局中每个结果所需的Cursor列和一个整数数组,指定每列应放置的相应视图:

String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME,
                        ContactsContract.CommonDataKinds.Phone.NUMBER};
int[] toViews = {R.id.display_name, R.id.phone_number};

实例化SimpleCursorAdapter时,传递用于每个结果的布局,包含结果的Cursor,以及这两个数组:

SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
        R.layout.person_name_and_number, cursor, fromColumns, toViews, 0);
ListView listView = getListView();
listView.setAdapter(adapter);

然后,SimpleCursorAdapter通过将每个fromColumns项插入相应的toViews视图,使用提供的布局为Cursor中的每一行创建一个视图。

如果在应用程序生命周期中,您更改了适配器读取的基础数据,则应调用notifyDataSetChanged()。这将通知附加的视图,数据已更改,并且应自行刷新。

处理点击事件

您可以通过实现AdapterView.OnItemClickListener接口来响应AdapterView中每个项目的单击事件。例如:

// Create a message handling object as an anonymous class.
private OnItemClickListener mMessageClickedHandler = new OnItemClickListener() {
    public void onItemClick(AdapterView parent, View v, int position, long id) {
        // Do something in response to the click
    }
};

listView.setOnItemClickListener(mMessageClickedHandler);

猜你喜欢

转载自blog.csdn.net/weixin_42703445/article/details/83752726