> For the complete documentation index, see [llms.txt](https://xxgqin.gitbook.io/android/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://xxgqin.gitbook.io/android/ch02/ch02-3.md).

# 第六个项目——登陆界面

## 实验目的

* 掌握布局的组合使用方式；
* 掌握**Vector Asset**资源的使用方式；
* 掌握**Image View**、**View**等控件的使用方式；

## 实验要求

* 创建布局文件并对根据要求对布局进行设置；

## 实验内容

### 步骤一，创建**Android**工程

打开**Android Studio**创建名为**Code05**的工程，选择**Empty Activity**模板。

本次项目需要实现应用的登录界面布局，登录界面效果图如[图1. Code05登录界面效果](/android/ch02/ch02-3.md#code05_screenshot)所示。

![图1. Code05登录界面效果](http://www.funnycode.net/guet/img/ch02/Code05_running_screenshot.png)

### 步骤二，构建页面布局

**1. 页面所需控件，根据效果图可知，需要如下控件进行布局：**

* **ImageView**，显示**Logo**、账号、密码、密码样式等四个图标；
* **EditText**，输入用户名、密码等；
* **Button**，登录按钮。

**2. 根据效果图可将页面分为三个部分：**

* 页面顶部，包含应用的**Logo**。可采用**RelativeLayout**；
* 页面中部，包含账号、密码输入框等。可采用**RelativeLayout**；
* 页面底部，包含登录按钮。可采用**RelativeLayout**；

页面整体可采用**LinearLayout**进行布局，代码如下所示，对于页面三个部分的高度可通过指定页面顶部元素、底部元素的**android:layout\_weight**，使得顶部和底部占满页面，而中部则根据控件实际大小进行设置。

```markup
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".LoginActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1">
        ...
    </RelativeLayout>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="40dp">
        ...
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="40dp">
        ...
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_weight="1"
        android:layout_height="wrap_content">
        ...
    </RelativeLayout>
</LinearLayout>
```

**3. 加入应用的Logo图标资源。**

将名为**ic\_logo.png**按照像素密度分别放入**res/mipmap-XXXXX**等文件夹中。

**4. 在activity\_main.xml加入ImageView控件显示Logo。**

**ImageView**作为整个页面的顶部显示的元素，把其放入顶部的**RelativeLayout**中。通过设置**ImageView**的**android:layout\_centerInParent**属性可以**ImageView**在其父容器中居中。设置**android:src**属性则 可设置为**ImageView**控件设置图片源。

通过设置顶部的**RelatvieLayout**的**android:layout\_marginTop**属性， 可调整**ImageView**距离顶部的位置，使得整个页面空间更加协调，代码下所所示。

```markup
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".LoginActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_marginTop="48dp">
        <ImageView
            android:layout_width="108dp"
            android:layout_height="108dp"
            android:src="@mipmap/ic_logo"
            android:layout_centerInParent="true"
            />
    </RelativeLayout>
    ...
```

**5. 加入用户账号、密码图标Vector Asset资源。**

用户账号、密码的图标采用**Android Studio**提供的内置**Vector Asset**资源。在工程窗口右击**app**模块，选择【New】-> 【Vector Asset】菜单，弹出的**Asset Studio**窗口中按照以下步骤进行设置：

* 在**Asset Type**中选择**Clip Art**；
* 点击**Clip Art** 图标选项，弹出如[图2. Select Icon窗口](/android/ch02/ch02-3.md#code05_select_icon)所示的**Select Icon**窗口；
* 选择**person outline**图标，点击确定；
* 在**res/drawable**目录下看到**ic\_person\_outline\_black\_24dp.xml** drawable图标资源；

使用同样的方式添加**lock outline**、**visibility**、**visibility off**三个图标。

![图2. Select Icon窗口](http://www.funnycode.net/guet/img/ch02/Code05_select_icon.png)

**6. 设置用户账户、密码布局。**

对于布局中用户账号一栏，使用了2个控件，分别是**ImageView**、**EditText**，这两个控件均在**RelativeLayout**中。 设置两个控件的**android:layout\_alignParentBottom**属性可以使得2个控件底部与父容器**RelativeLayout**对齐。

设置**ImageView**控件的**android:layout\_width**和**android:layout\_height**属性为*32dp*。

设置**EditText**控件的**android:layout\_marginStart**和**android:layout\_marginEnd**属性为*48dp*。

%由于**EditText**控件的样式（例如：底部横线颜色，文本光标颜色等）与App的主题色不符，在此可通过一些属性设置来改变。

%首先设置**EditText**控件的**android:background**属性为\`\`@null''用于取消该控件的底部横线以及背景，文本光标的颜色则通过设置**android:textCursorDrawable**

以同样的方式设置用户密码一栏的布局。不同的是密码栏的右侧还增加了一个**ImageView**用于设置密码可见操作。因此这一栏实际上有三个控件，分别是**ImageView**、**EditText**、**ImageView**。页面中部的布局代码下所示。

```markup
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".LoginActivity">

    ...
      <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_marginTop="48dp">

        <ImageView
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginBottom="4dp"
            android:layout_alignParentBottom="true"
            android:src="@drawable/ic_person_outline_black_24dp"/>

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="4dp"
            android:layout_alignParentBottom="true"
            android:layout_gravity="center"
            android:inputType="text"
            android:hint="Email/Account"
            android:layout_marginStart="48dp"
            android:layout_marginEnd="48dp"
            android:maxLines="1"/>
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_marginTop="16dp">

        <ImageView
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginBottom="4dp"
            android:layout_alignParentBottom="true"
            android:src="@drawable/ic_lock_outline_black_24dp"/>

        <EditText
            android:id="@+id/et_pwd"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="4dp"
            android:layout_alignParentBottom="true"
            android:inputType="textPassword"
            android:hint="Password"
            android:layout_marginStart="48dp"
            android:layout_marginEnd="48dp"
            android:maxLines="1"/>

        <ImageView
            android:id="@+id/iv_pwd_switch"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_marginBottom="6dp"
            android:layout_alignParentBottom="true"
            android:layout_alignParentEnd="true"
            android:src="@drawable/ic_visibility_off_black_24dp"/>
    </RelativeLayout>
    ...
```

**7. 设置登录按钮布局。**

登录按钮的布局相对较简单，将**Button**控件置于底部的**RelativeLayout**中，并设置其 **android:textColor**、**android:layout\_alignParentTop**等属性，具体代码如下所示。

```markup
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".LoginActivity">

    ...

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_marginBottom="32dp"
        android:layout_weight="1"
        android:layout_height="wrap_content">
        <Button
            android:text="Login"
            android:textColor="@android:color/white"
            android:background="@color/colorPrimary"
            android:layout_marginTop="32dp"
            android:layout_alignParentTop="true"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </RelativeLayout>
</LinearLayout>
```

### 步骤三，设置App启动图标

工程窗口中右击工程的**app**模块，在弹出的菜单中选择【New】-> 【Image Asset】，弹出如[图3. Asset Studio窗口](/android/ch02/ch02-3.md#asset_studio)所示的**Asset Studio**窗口。 按照以下步骤进行设置：

* 在**Icon Type**中选择**Launcher Icons (Adaptive and Legacy)**。
* 设置**Name**为**ic\_launcher**。
* 在**Foreground Layer**标签中的**Source Asset**中选择**Asset Type**为**Image**，并在**Path**中选择所需要使用的图标文件（在本例中为ic\_logo.png）。
* 在**Background Layer**标签中的**Source Asset**中选择**Color**，并设置**Color**为白色。
* 点击确定完成**Logo**图标的导入。

![图3. Asset Studio窗口](http://www.funnycode.net/guet/img/ch02/Code05_asset_studio.png)

### 步骤四，实现密码明文切换图标动作

当用户点击密码栏中的密码明文切换图标时，可将密码**EditText**控件中的输入类型进行切换，这需要在**LoginActivity**活动中增加**ImageView**控件的**OnClickListener**事件侦听器并对**EditText**控件的**inputType**属性进行设置即可，具体代码如下所示。

```java
public class LoginActivity extends AppCompatActivity {

    private Boolean bPwdSwitch = false;
    private EditText etPwd;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...

        final ImageView ivPwdSwitch = findViewById(R.id.iv_pwd_switch);
        etPwd = findViewById(R.id.et_pwd);

        ivPwdSwitch.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                bPwdSwitch = !bPwdSwitch;
                if (bPwdSwitch) {
                    ivPwdSwitch.setImageResource(
                            R.drawable.ic_visibility_black_24dp);
                    etPwd.setInputType(
                            InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
                } else {
                    ivPwdSwitch.setImageResource(
                            R.drawable.ic_visibility_off_black_24dp);
                    etPwd.setInputType(
                        InputType.TYPE_TEXT_VARIATION_PASSWORD | 
                        InputType.TYPE_CLASS_TEXT);
                    etPwd.setTypeface(Typeface.DEFAULT);
                }
            }
        });
```

## 实验小结

通过本次实验，你应该掌握了如下知识内容：

* 使用**LinearLayout**，**Relative Layout**进行页面布局；
* 使用**Vector Asset**添加图标资源；
* 使用**Image Asset**导入应用启动图标；


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://xxgqin.gitbook.io/android/ch02/ch02-3.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
