文章目录
一、用户界面设计基础
1、UI设计相关的概念
view:占据屏幕上的一块矩形区域,负责提供组件绘制和事件处理的方法,在安卓当中,view通常是以view类的形式出现的。view类是所有UI组件的基类,所以一般情况下不直接使用view类,而是使用其子类。
- view类位于android.view包中;View类的子类一般都位于android.widget包当中。对于view的一些属性,不仅可以使用xml来配置,还可以使用java的方法来进行设置。
【1】View类常用的属性
1、id属性:用于对属性设置一个唯一的标识,类似于身份证号码。
android:id="@+id/user" //定义id属性
2、background属性:用于设置背景的,比如我们需要为布局管理器设置一张背景图片。该属性可以使用图片资源,也可以使用具体的颜色值。
android:background="@mipmap/bg" //bg就是图片资源的名称
由于我们使用了mipmap,因此需要将资源先复制到mipmap路径下。
android:background="#FF6600" //直接设置颜色值
3、padding属性:用于设置上下左右四个内边距的。
android:padding="16dp"
android:padding="@dimen/activity_margin"
如果想要上下左右分别设置内边距的话:
1、paddingLeft(paddingStart)
2、paddingTop
3、paddingRight(paddingEnd)
4、paddingBotton
注:Start和End在API大于17的时候可以使用。
【2】ViewGroup
ViewGroup是控制View是如何摆放的,是View类的扩展,用来容纳其他组件的容器。由于ViewGroup是抽象类,因此一般使用ViewGroup的子类。比如布局管理器,就是ViewGroup的子类。
ViewGroup控制其子组件分布时依赖的内部类:
1、ViewGroup.LayoutParams类
用来控制布局的高度和宽度的。一般我们使用以下两个属性:
【1】layout_height:设置高度
【2】layout_width:设置宽度
下面的三个常量同样可以设置高度和宽度:
- FILL_PARENT:设置与父容器相同的,即设置组件的宽度与父容器是一样的。
- MATCH_PARENT:和第一个一样。无区别。
- WRAP_CONTENT:组件的大小根据自身的内容进行确定。
2、ViewGroup.MarginLayoutParams类
用来控制子组件的外边距,外边距就是在组件四周的区域。
【3】安卓UI组件的层次结构
在安卓当中,所有的UI界面都是由View类或者ViewGroup类以及其子类组合而成的。
2、控制UI界面的四种方法
【1】使用XML布局文件控制UI界面(推荐)
这样可以把界面布局和逻辑控制的Java代码分离开来。使程序结构更加清晰明了。
- 1、在安卓应用的res/layout目录下编写XML布局文件。
- 2、在Activity中使用Java代码显示XML文件中的布局内容。
setContentView(R.layout.activity_main);
案例:
使用xml完成一个带有背景图片的应用界面设置。
创建一个新的module,并在mipmap下面添加背景图片。
1、修改布局管理器
2、为其设计一个background属性
android:background="@mipmap/background"
【2】在Java代码当中控制UI界面
实例:完全通过Java代码实现游戏界面的开始。
1、删除下图文件
2、创建帧布局管理器FrameLayout
通过new关键字创建实例,参数是一个上下文对象,使用this进行指定
FrameLayout frameLayout=new FrameLayout(this);//创建一个帧布局管理器:通过new关键字创建实例
//参数是一个上下文对象,使用this进行指定
3、导入背景图片
package com.example.javalayout;
import androidx.appcompat.app.AppCompatActivity;
import android.app.AlertDialog;
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);//创建一个真布局管理器:通过new关键字创建实例
//参数是一个上下文对象,使用this进行指定
frameLayout.setBackgroundResource(R.mipmap.background);//添加背景图片
setContentView(frameLayout);
TextView text1=new TextView(this);
text1.setText("开始游戏");//设置文字
text1.setTextSize(TypedValue.COMPLEX_UNIT_SP,18);//设置文字大小
text1.setTextColor(Color.rgb(17,85,114));
FrameLayout.LayoutParams params=new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.gravity= Gravity.CENTER;//设置文本框组件居中显示
text1.setLayoutParams(params);
//为文本框组件设置单击事件,通过匿名内部类来构造
text1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new AlertDialog.Builder(MainActivity.this).setTitle("系统提示")
.setMessage("游戏有风险,进去需谨慎,真的要进入吗?")
.setPositiveButton("确定",
new android.content.DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
Log.i("桌面台球","进入游戏");
}}).setNegativeButton("退出", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Log.i("桌面台球","退出游戏");
finish();
}
}).show();
}
});
//把文本框组件添加到布局管理器当中
frameLayout.addView(text1);
}
}
实现效果:
【3】使用XML和Java代码混合控制UI界面
将一些变化不大的代码放到XML组件当中,将一些复杂组件的代码放在java文件当中。
QQ相册显示实例:添加网格管理器
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout"
android:orientation="horizontal"
android:rowCount="3"
android:columnCount="4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
tools:context=".MainActivity">
</GridLayout>
导入图片资源:
在java当中编写代码:
创建保存图片资源的数组变量。
//定义一个保存图像视图的数组
private ImageView[] img=new ImageView[12];
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,
};
在onCreate方法当中获取布局文件,并且创建要显示图片的组件,然后添加到布局管理器当中:
package com.example.xmljavalayout;
import androidx.appcompat.app.AppCompatActivity;
import android.media.Image;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.GridLayout;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
//定义一个保存图像视图的数组
private ImageView[] img=new ImageView[12];
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,
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridLayout layout=(GridLayout)findViewById(R.id.layout);
for(int i=0;i<imagePath.length;i++){
img[i]=new ImageView(MainActivity.this);
img[i].setImageResource(imagePath[i]);
img[i].setPadding(2,2,2,2);
ViewGroup.LayoutParams params=new ViewGroup.LayoutParams(116,68);
img[i].setLayoutParams(params);
layout.addView(img[i]);
}
}
}
效果:可以看到有些图片没有显示出来
切换至横屏:
【4】开发自定义的View
实例:通过自定义view组件实现跟随手指的小兔子
设置xml:
<?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:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:id="@+id/mylayout"
android:background="@mipmap/background"
tools:context=".MainActivity">
</FrameLayout>
创建一个新的java类:
通过鼠标重写onDraw方法:
RabbitView.java:
package com.example.follow;
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 {
//让这个类继承自安卓包当中的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();
}
}
}
MainActivity.java:
package com.example.follow;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
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 frameLayout=(FrameLayout) findViewById(R.id.mylayout);//获取布局管理器
RabbitView rabbit=new RabbitView(this);
//添加触摸事件监听器
rabbit.setOnTouchListener(new View.OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
//编写小兔子跟随手指移动的方法
//1、设置小兔子的X坐标
rabbit.bitmapX=motionEvent.getX();
rabbit.bitmapY=motionEvent.getY();
return true;
}
});
//把小兔子添加到布局管理器当中,如果不添加的话就不会显示到布局管理器当中
frameLayout.addView(rabbit);
}
}