第一章 用户界面设计基础

1 UI设计相关概念

1.1 View

视图,类似于窗户的格子,然后每个格子显示用户定义的内容。一般我们不直接使用View类,而是使用它的子类。

需要注意的是:View类位于android.view包内,而View的子类一般都位于android.widget包中。 

 View的常用属性:

  • android:id属性,为view设定一个唯一的标识。
  • android:background属性,为view设置背景,具体值可以是图片资源,也可以是颜色值
    android:background="@mipmap/bg"
    
    android:background="#FF6600"
  •  android:padding属性,设置一个view的上下左右的4个内边距


//将四个方向的内边距设置成一样
android:padding="@dimen/activity_margin"

//分别对四个方向的内边距进行设置
android:paddingLeft
android:paddingTop
android:paddingRight
android:paddingBottom

android:paddingStart  //其实就是左内边距
android:paddingEnd    //其实就是右内边距

1.2 ViewGroup

如果将view比作窗户的格子的话,那么ViewGroup就是窗户框,负责控制格子的摆放。

ViewGroup类继承于View类,而且是一个抽象类。

ViewGroup控制其子组件分布时依赖于两个内部类:

  • ViewGroup.LayoutParams类
    • android:layout_height:FILL_PARENT、MATCH_PARENT、WRAP_PARENT
    • android:layout_width:FILL_PARENT、MATCH_PARENT、WRAP_PARENT
  • ViewGroup.MarginLayoutParams类

 1.3 Android UI组件的层次结构

2 控制UI界面

2.1 选择控制UI界面的方法

2.1.1 使用XML布局文件控制UI界面(推荐)

好处:将布局文件待遇与控制逻辑的Java代码分隔开来

① 在Android应用的res/layout目录下编写XML布局文件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

②在Activity中使用以下Java代码显示XML文件中布局的内容

setContentView(R.layout.activity_main);

2.1.2 在Java代码中控制UI界面

在android中,支持像JavaSwing一样完全通过Java代码来控制布局。

package com.example.xmllayout;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;

import org.w3c.dom.Text;

public class MainActivity extends AppCompatActivity {

    @SuppressLint("ResourceAsColor")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FrameLayout frameLayout = new FrameLayout(this);
        frameLayout.setBackgroundResource(R.mipmap.tableball);
        setContentView(frameLayout);
        TextView text = new TextView(this);
        text.setText(R.string.start);
        text.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
        text.setTextColor(Color.rgb(17, 85, 114));
        text.setBackgroundColor(R.color.purple_700);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
        );
        params.gravity = Gravity.CENTER;
        text.setLayoutParams(params);
        text.setOnClickListener((v)->{
            new AlertDialog.Builder(MainActivity.this).setTitle("系统提示")
                    .setMessage("游戏有风险,进入需谨慎,真的要进入吗?")
                    .setPositiveButton("确定",
                            (dialog, which)->{
                        Log.i("桌面台球","进入游戏");
                            })
                    .setNegativeButton("退出",
                    (dialog, which)->{
                                Log.i("桌面台球","退出游戏");
                                finish();
                    }).show();
        });
        frameLayout.addView(text);
    }
}

2.1.3 使用XML和Java代码混合控制UI界面

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layout"
    android:rowCount="3"
    android:columnCount="4"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context=".MainActivity">
    
</GridLayout>
package com.example.xmlandjava;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.GridLayout;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

    private ImageView[] imgs = new ImageView[12];
    private int[] imagePaths = new int[]{
            R.mipmap.image1,R.mipmap.image2,R.mipmap.image3,R.mipmap.image4,
            R.mipmap.image5,R.mipmap.image6,R.mipmap.image7,R.mipmap.image8,
            R.mipmap.image9,R.mipmap.image10,R.mipmap.image11,R.mipmap.image12
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        GridLayout layout = findViewById(R.id.layout);
        for(int i = 0; i < imagePaths.length; i++) {
            imgs[i] = new ImageView(MainActivity.this);
            imgs[i].setImageResource(imagePaths[i]);
            imgs[i].setPadding(2,2,2,2);
            ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
                    400,
                    100);
            imgs[i].setLayoutParams(params);
            layout.addView(imgs[i]);
        }
    }
}

2.1.4 开发自定义的View

package com.example.myview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;

public class RabbitView extends View {

    public float bitmapX;
    public float bitmapY;

    public RabbitView(Context context) {
        super(context);
        bitmapX = 290;
        bitmapY = 130;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
        Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.mipmap.rabbit);
        canvas.drawBitmap(bitmap, bitmapX, bitmapY, paint);
        if(bitmap.isRecycled()) {
            bitmap.recycle();
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@mipmap/background"
    tools:context=".MainActivity">


</FrameLayout>

package com.example.myview;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        FrameLayout layout = findViewById(R.id.layout);
        RabbitView rabbit = new RabbitView(this);
        rabbit.setOnTouchListener(new View.OnTouchListener(){
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                rabbit.bitmapX = event.getX();
                rabbit.bitmapY = event.getY();
                rabbit.invalidate();
                return true;
            }
        });
        layout.addView(rabbit);
    }
}

3 布局管理器

3.1什么是布局管理器

用于控制组件是如何摆放的。

3.2 有哪些常用的布局管理器

3.2.1 RelativeLayout

指定一个组件作为参考点,然后其他组件相对这个组件进行放置。

两个属性:

  • android:gravity,设置子组件的摆放方式
  • android:ignoreGravity,指定哪个组件可以不受第一个组件的影响

RelativeLayout.LayoutParams:

  • android:layout_above、android:layout_below、android:layout_toLeftOf、android:layout_toRightOf。设置组件相对于某一组件的位置
  • android:layout_alignParentBottom、android:layout_alignParentLeft、android:layout_alignParentRight、android:layout_alignParentTop。设置组件与父容器的哪一边对其,值均为布尔值。
  • android:layout_alignBottom、android:layout_alignLeft、android:layout_alignRight、android:alignTop。边界对齐
  • android:layout_centerHorizontal、android:layout_centerParent、android:layout_centerVertical。设置组件水平居中、中间位置、垂直居中

示例:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="@mipmap/bg"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:text="发现有Widget的新版本,您想现在就安装吗?" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="以后再说"
        android:layout_below="@id/textView1"
        android:layout_marginRight="10dp"
        android:layout_alignRight="@id/textView1"/>

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="立即安装"
        android:layout_below="@id/textView1"
        android:layout_toLeftOf="@id/button1"
        android:layout_marginRight="10dp"/>

</RelativeLayout>

3.2.2 LinearLayou

将组件按照纵向或横向进行排列

两个重要属性:

  • android:oriention,表示方向
  • android:gravity,设置组件内的安放位置

子组件的属性:

  • android:layout_weight,组件占剩余空间的比例

示例:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center|top"
    android:padding="16dp"
    tools:context=".MainActivity">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="QQ号/微信号/手机号"
        android:paddingBottom="10dp"
        android:drawableLeft="@mipmap/zhanghao"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="密码"
        android:paddingBottom="10dp"
        android:drawableLeft="@mipmap/mima"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="登录"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="10dp"
        android:text="登录遇到问题?"/>
</LinearLayout>

3.2.3 FrameLayout

主要用于显示层叠的内容,以及拖动的动画效果。

最先放置的组件在最下面

 两个重要是属性:

  • android:foreground,为这个帧布局设置一个前景图像
  • android:foregroundGravity,设置前景图像的位置

什么是前景图像?一个始终位于最上层的图像,其他图像无法覆盖它。

示例:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:foreground="@mipmap/foreground"
    android:foregroundGravity="bottom|right"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:background="#0000ff"
        android:layout_gravity="center"
        android:text="蓝色背景的正方形"/>
    <TextView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="#87CEEB"
        android:layout_gravity="center"
        android:text="天蓝色的正方形"/>
    <TextView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="#1E90FF"
        android:layout_gravity="center"
        android:text="水蓝色的正方形"/>

</FrameLayout>

3.2.4 TableLayout

表格布局管理器,以行列的形式来管理放入其中的UI组件

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@mipmap/biaoge"
    android:stretchColumns="0,3"
    tools:context=".MainActivity">

    <TableRow
        android:paddingTop="400dp">
        <TextView/>
        <TextView
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:text="账  号:"
            android:textSize="18sp"/>
        <EditText
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:hint="邮箱或者手机号"/>
        <TextView/>
    </TableRow>

    <TableRow>
        <TextView/>
        <TextView
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:text="密  码:"
            android:textSize="18sp"/>
        <EditText
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:hint="输入6-16位数字或字母"/>
        <TextView/>
    </TableRow>

    <TableRow>
        <TextView/>
        <Button
            android:text="注册"/>
        <Button
            android:text="登录"/>
        <TextView/>
    </TableRow>

    <TableRow>
        <TextView/>
        <TextView/>
        <TextView
            android:layout_height="match_parent"
            android:layout_width="wrap_content"
            android:text="忘记密码?"
            android:gravity="right"/>
        <TextView/>
    </TableRow>

</TableLayout>

3.2.5 GridLayout

与表格布局管理器相比,网格布局管理器可以跨列显示、跨行显示。

 三个重要属性:

  • columnCount:指定网格的最大列数
  • orientation:指定排列顺序
  • rowCount:指定网格的最大行数

 GridLayout.LayoutParams:

  • android:layout_column:指定子组件位于第几列
  • android:layout_columnSpan:指定子组件跨几列
  • android:layout_columnWeight:指定子组件在列上占剩余空间的权重
  • android:gravity:指定子组件在网格内的位置
  • android:layout_row:指定子组件位于第几行
  • android:layout_rowSpan:指定子组件跨几行
  • android:layout_rowWeight:指定子组件在行上占剩余空间的权重

 示例:

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnCount="6"
    android:rowCount="4"
    android:background="@mipmap/bg"
    tools:context=".MainActivity">

    <ImageView
        android:src="@mipmap/ico2"
        android:layout_column="5"
        android:layout_row="0"
        android:layout_marginRight="10dp"/>
    <ImageView
        android:src="@mipmap/a1"
        android:layout_column="1"
        android:layout_row="0"
        android:layout_columnSpan="4"
        android:layout_gravity="right"/>

    <ImageView
        android:src="@mipmap/ico1"
        android:layout_column="0"
        android:layout_row="1"
        android:layout_marginLeft="10dp"/>

    <ImageView
        android:src="@mipmap/b1"
        android:layout_columnSpan="4"
        android:layout_column="1"
        android:layout_row="1"
        android:layout_gravity="left"/>

    <ImageView
        android:src="@mipmap/ico2"
        android:layout_column="5"
        android:layout_row="2"
        android:layout_marginRight="10dp"/>
    <ImageView
        android:src="@mipmap/a2"
        android:layout_column="1"
        android:layout_row="2"
        android:layout_columnSpan="4"
        android:layout_gravity="right"/>

    <ImageView
        android:src="@mipmap/ico1"
        android:layout_column="0"
        android:layout_row="3"
        android:layout_marginLeft="10dp"/>

    <ImageView
        android:src="@mipmap/b2"
        android:layout_columnSpan="4"
        android:layout_column="1"
        android:layout_row="3"
        android:layout_gravity="left"/>

</GridLayout>

3.2.6 布局管理器的嵌套

几大原则:

  • 根布局管理器必须包含xmlns属性
  • 一个xml文件中,最多只能有一个根布局管理器
  • 不能嵌套太深,否则影响性能
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值