本文是哔哩哔哩上 安卓开发教程 的笔记
UI的概念:
就是用户界面的意思
① View
下面是官方的翻译
This class represents the basic building block for user interface components. A View occupies a rectangular area on the screen and is responsible for drawing and event handling. View is the base class for widgets, which are used to create interactive UI components (buttons, text fields, etc.). The android.view.ViewGroup subclass is the base class for layouts, which are invisible containers that hold other Views (or other ViewGroups) and define their layout properties
这个类代表着一个基本的建造阻止对用户的接口来讲.一个接口充满了一个矩阵的地区.View是这个基本的类对窗口来讲,一个用来创造可交互的UI组件.
ViewGroups是他的子类,定义为他们的布局的属性
注意:
View类位于android.view的包中,但是View的子类一般位于android.widget类包中
例如:
import android.view.View; //View
import android.widget.TextView; //View的子类
View类的属性:
① id
android:id 标识属性
id就是这个View类的名字,以后再给这个View类创建监听什么的时候用得到的一个标识
例子如下:
android:id="@+id/textView"
② background
android:background 背景属性
设置这个View类的背景,可以是颜色,也可以是图片
方法分别如下:
android:background="@drawable/a123"
android:background="#770000"
③ padding
android:padding 属性
android:paddingStart="24dp"
android:paddingTop="24dp"
android:paddingEnd="24dp"
android:paddingBottom="24dp"
这四个分别是
左 上 右 下
他们描述的是内边距
一个完整的例子如下:
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="120dp"
android:layout_marginTop="296dp"
android:background="#771111"
android:paddingStart="10dp"
android:paddingTop="50dp"
android:paddingEnd="50dp"
android:paddingBottom="24dp"
② ViewGroup
代表的是一个具体的容器
ViewGroup.LayoutParams 控制其子组件分布时,依赖的内部类
① ViewGroup.LayoutParams类
② ViewGroup.MarginLayoutParams类
ViewGroup.LayoutParams类
常用的有
高度和宽度的属性
android:layout_width=""
android:layout_height=""
① 可以设置为具体的数值
android:layout_width="100dp"
android:layout_height="200dp"
② 可以设置为
match_parent
wrap_content
还有一个有点过时了,这里不表
match_parent表示让当前控件的大小和父布局的大小一样,也就是由父布局来决定当前控件的大小
wrap_content表示让当前的控件大小能够刚好包含里面的内容,也就是由控件内容决定当前控件的大小
ViewGroup.MarginLayoutParams
主要是用来控制,子组件的外边距的
具体的属性如下图所示
Android UI组件的层次结构
③ 选择控制UI界面的方法
① 使用XML布局文件来控制UI界面(推荐)
② 再JAVA代码中控制UI界面
③ 使用XML和Java代码混合控制UI界面
④ 开发自定义的View
使用XML布局文件来控制UI界面
① 再Android应用的res/layout 目录下编写XML布局文件
② 再Activity中使用以下Java代码显示XMl文件中的内容
setContentView(R.layout.activity_main);
使用Java代码来控制UI界面
这个我们通过一个实例,来讲解
下面是MainActivity
package com.example.demo_03;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//创建一个布局管理器
FrameLayout frameLayout = new FrameLayout(this);
//设置背景图片
frameLayout.setBackgroundResource(R.mipmap.abc);
//把这个布局管理器,添加到这个Activity里面
setContentView(frameLayout);
//文本框组件
TextView textView = new TextView(this);
//设置文本框属性
textView.setText("开始游戏");
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP,18);
textView.setTextColor(Color.rgb(17,85,114));
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
//设置文本框居中显示
params.gravity = Gravity.CENTER;
textView.setLayoutParams(params);
//设置一个监听对象
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new AlertDialog.Builder(MainActivity.this).setTitle("系统提示")
.setMessage("游戏有风险,进入需要谨慎,真的要进入吗")
.setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.i("WARN","桌面台球,进入游戏");
}
}).setNegativeButton("退出", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.i("WARN","桌面台球,退出游戏");
finish();
}
}).show(); //显示对话框
}
});
frameLayout.addView(textView); // 将text1添加到布局管理器中
}
}
使用XMl和Java代码混合控制UI界面
我们将一般组件的代码放到XML中,将复杂组件的代码放到Java中
下面还是一个实例
① 首先,我们创建一个默认的Demo
② 然后,我们在更改其中的默认文件,也就是activity_main里面的内容
②-① 我们先将他的布局管理器改为 GridLayout(网格布局管理器)
②-② 然后我们在添加 id 属性 和排列属性(orientation) 排列属性改为 horizontal(水平)
②-③ 然后我们在吧行和列添加进去 rowCount columnCount
添加完毕后的结果如下:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout" android:orientation="horizontal" android:rowCount="3" android:columnCount="4" 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" />
</GridLayout>
③ 我们更改MainActivity.java里面的内容
package com.example.demo_04;
import androidx.appcompat.app.AppCompatActivity;
import android.media.Image;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.ViewGroup;
import android.widget.GridLayout;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
//创建一个ImageView的数组,用来保存图像
private ImageView[] img = new ImageView[12];
//int数组,用来记录,图片的地址
//R.mipmap就是图片的地址
private int[] imagePath = new int[]{
R.mipmap.img01,R.mipmap.img02,R.mipmap.img03,R.mipmap.img04,
R.mipmap.img05,R.mipmap.img06,R.mipmap.img07,R.mipmap.img08,
R.mipmap.img09,R.mipmap.img10,R.mipmap.img11,R.mipmap.img12,
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取到图片文件,并且添加到网格布局管理器中
//findViewByID 是一个蛮复杂的方法,这里暂时,先跳过
GridLayout layout = findViewById(R.id.layout);
//设置图片的循环
for(int i=0;i<imagePath.length;i++){
//context就是环境,应该是放在哪里的意思
img[i]=new ImageView(MainActivity.this);
//setImageResource就是设置一个图片,进去 drawable 属性就是静态的图片属性
//setImageResource可能会出现问题,现在已经推荐使用别的了
//具体的地址This does Bitmap reading and decoding on the UI thread, which can cause a latency hiccup. If that's a concern, consider using setImageDrawable(android.graphics.drawable.Drawable) or setImageBitmap(android.graphics.Bitmap) and BitmapFactory instead
img[i].setImageResource(imagePath[i]);
//设置内边距
img[i].setPadding(2,2,2,2);
//设置图片的宽度和高度
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(300,200);
//讲这个宽度和高度,应用于这些图片
img[i].setLayoutParams(params);
//把这些图片添加到layout 布局管理器中
layout.addView(img[i]);
}
}
}
开发自定义的View
虽然安卓已经有许多定义好的View类供我们使用,但是在实际的开发中,还是不能满足我们的实际需求,所以我们还是需要自己开发View组件
① 在XML布局文件里面 添加一个FrameLayout布局管理器
② 然后再Java类里面创建View类组件—这个类要继承View类
③ 再主程序里面实例化那个Java类(继承了View类的)
下面是一个实例
① 先把需要使用的资源文件房进去
② 改写布局文件
activty_main
<?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:background="@mipmap/background" android:id="@+id/mylayout" tools:context=".MainActivity">
</FrameLayout>
③ 添加一个自定义的View类 Sister
package com.example.demo_05;
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 SisterView extends View {
//这两个值,分别是X,Y的坐标
public float bitmapX;
public float bitmapY;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//创建一个画笔对象
Paint paint = new Paint();
//Bitmap是一个位图对象 后面的那个方法,返回的就是一个bitmap的对象
Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(),R.mipmap.sister);
//canvas是画布类,用来保存位图的
//drawBitmap这个方法的作用是在图片的左上方绘制图片
//canvas.drawBitmap(bitmap,bitmapX,bitmapY,paint);
//改了哈,代码,让图片可以居中绘制.
canvas.drawBitmap(bitmap, bitmapX - bitmap.getWidth() / 2, bitmapY - bitmap.getHeight() / 2, paint);
//强制回收图片
if(bitmap.isRecycled()){
bitmap.recycle();
}
}
//自动重写构造方法
public SisterView(Context context) {
super(context);
bitmapX =290;
bitmapY =130;
}
}
④ 主程序里面的方法
package com.example.demo_05;
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 SisterView extends View {
//这两个值,分别是X,Y的坐标
public float bitmapX;
public float bitmapY;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//创建一个画笔对象
Paint paint = new Paint();
//Bitmap是一个位图对象 后面的那个方法,返回的就是一个bitmap的对象
Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(),R.mipmap.sister);
//canvas是画布类,用来保存位图的
//drawBitmap这个方法的作用是在图片的左上方绘制图片
//canvas.drawBitmap(bitmap,bitmapX,bitmapY,paint);
//改了哈,代码,让图片可以居中绘制.
canvas.drawBitmap(bitmap, bitmapX - bitmap.getWidth() / 2, bitmapY - bitmap.getHeight() / 2, paint);
//强制回收图片
if(bitmap.isRecycled()){
bitmap.recycle();
}
}
//自动重写构造方法
public SisterView(Context context) {
super(context);
bitmapX =290;
bitmapY =130;
}
}
在记录一个Small Trips吧
在绘制图像的时候,因为
canvas.drawBitmap()默认的绘制方向是左上角,
如果我们想要图像以中心为坐标的话,就相当于,把原来的图像向左上角移动
所以我们要减去
图如下: