AndroidManifest.xml:Android全局描述文件,列出项目相关属性,配置activity等。
android:icon="@mipmap/ic_launcher" 设置应用图标
android:roundIcon="@mipmap/ic_launcher_round" 设置圆形图标
android:theme="@style/AppTheme" 设置主题
res:保存资源文件
drawable:存放位图文件(PNG、JPEG或GIF)、9Patch图片文件、绘制几何图形的资源文件
mipmap子目录:(保证用户在不同分辨率的手机看到最佳效果的图片)
目录名 | 存放大小 |
---|---|
mipmap-mdpi | 48*48 |
mipmap-hdpi | 72*72 |
mipmap-xhdpi | 96*96 |
mipmap-xxhdpi | 144*144 |
mipmap-xxxhdpi | 192*192 |
drawable和mipmap区别:
UI设计相关的概念:
View:视图,占据一个矩形位置,负责提供组件绘制和事件处理的方法。
View类位于android.view包中;View类的子类一般都位于android.widget包中。
View类常用属性:
属性 | 作用 |
---|---|
android:id属性 | 为组件设置唯一标识 |
android:background属性 | 为组件设置背景 |
android:padding属性 | 为组件设置内边距 |
android:paddingLeft属性 | 为组件设置左内边距 |
android:paddingTop属性 | 为组件设置顶内边距 |
android:paddingRight属性 | 为组件设置右内边距 |
android:paddingBottom属性 | 为组件设置底内边距 |
android:paddingStart属性 | 为组件设置左内边距 |
android:paddingEnd属性 | 为组件设置右内边距 |
ViewGroup:容器,控制View是如何摆放的。
ViewGroup类继承自View类,是View类的扩展,是用来容纳其他组件的容器,是抽象类,一般使用ViewGroup的子类作为容器。
ViewGroup控制其子组件分布时依赖的内部类:
ViewGroup.LayoutParams类:用于控制布局的位置、高度和宽度,通常使用android:layout_height和android:layout_width属性。可以给这两个属性设置具体的数值,也可以用提供的常量来表示。
常量 | 效果 |
---|---|
FILL_PARENT | 设置组件的宽度与父容器相同 |
MATCH_PARENT | 设置组件的宽度与父容器相同 |
WRAP_CONTENT | 包裹自身的内容,根据内容确定组件的大小 |
ViewGroup.MarginLayoutParams类:用于控制子组件的外边距。
常用属性:
属性 | 作用 |
---|---|
android:layout_marginLeft属性 | 为组件设置左外边距 |
android:layout_marginTop属性 | 为组件设置顶外边距 |
android:layout_marginRight属性 | 为组件设置右外边距 |
android:layout_marginBottom属性 | 为组件设置底外边距 |
android:layout_marginStart属性 | 为组件设置左外边距 |
android:layout_marginEnd属性 | 为组件设置右外边距 |
控制UI界面:
使用XML布局文件控制UI界面:
setContentView(R.layout.activity_main);
练习部分的java代码
package com.jasmyn.demo1;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
练习部分的strings.xml
demo1
开始游戏
练习部分的activity_main.xml
在Java代码中控制UI界面:
package com.jasmyn.demo2;
import android.content.DialogInterface;
import android.graphics.Color;
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;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FrameLayout frameLayout = new FrameLayout(this);
frameLayout.setBackgroundResource(R.mipmap.bg);
setContentView(frameLayout);
TextView textView = new TextView(this);
textView.setText("开始游戏");
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP,18);
textView.setTextColor(Color.rgb(17,85,114));
textView.setBackgroundColor(Color.rgb(117,182,236));
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("lhj","进入游戏");
}
}).setNegativeButton("退出", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.i("lhj","退出游戏");
finish(); // 结束当前activity
}
}).show();
}
});
frameLayout.addView(textView);
}
}
使用XML和Java代码混合控制UI界面:
<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/layout"
android:orientation="horizontal"
android:rowCount="3"
android:columnCount="4"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
GridLayout>
package com.jasmyn.demo3;
import android.view.ViewGroup;
import android.widget.GridLayout;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private ImageView[] imageView = 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,R.mipmap.img10,R.mipmap.img11,R.mipmap.img12
};
@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 < imagePath.length; i++){
imageView[i] = new ImageView(MainActivity.this);
imageView[i].setImageResource(imagePath[i]);
imageView[i].setPadding(2,2,2,2);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(getWindowManager().getDefaultDisplay().getWidth()/4,
getWindowManager().getDefaultDisplay().getHeight()/3);
imageView[i].setLayoutParams(params);
layout.addView(imageView[i]);
}
}
}
开发自定义的View:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/grass"
android:id="@+id/layout"
tools:context=".MainActivity">
FrameLayout>
package com.jasmyn.demo4;
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);
// 调整位图的尺寸为原图的0.35倍
android.graphics.Matrix mt = new android.graphics.Matrix();
mt.postScale((float) 0.35, (float) 0.35);
Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), mt, true);
canvas.drawBitmap(resizeBmp,bitmapX,bitmapY,paint);
if (resizeBmp.isRecycled()){
resizeBmp.recycle();
}
// canvas.drawBitmap(bitmap,bitmapX,bitmapY,paint);
// if (bitmap.isRecycled()){
// bitmap.recycle();
// }
}
}
package com.jasmyn.demo4;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FrameLayout frameLayout = findViewById(R.id.layout);
final RabbitView rabbitView = new RabbitView(this);
rabbitView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
rabbitView.bitmapX = event.getX();
rabbitView.bitmapY = event.getY();
rabbitView.invalidate();
return true;
}
});
frameLayout.addView(rabbitView);
}
}
什么是布局管理器:用于控制组件是如何摆放的。
常用的布局管理器:
布局 | 名称 |
---|---|
RelativeLayout | 相对布局管理器 |
LinearLayout | 线性布局管理器 |
FrameLayout | 帧布局管理器 |
TableLayout | 表格布局管理器 |
AbsoluteLayout | 绝对布局管理器【已过期】 |
GridLayout | 网格布局管理器 |
ConstraintLayout | 约束布局 |
相对布局管理器:
属性 | 作用 |
---|---|
xmlns:android | 表示Android命名空间 |
xmlns:tools | 定义工具命名空间 |
android:gravity | 设置布局管理器中各子组件的摆放方式 |
android:ignoreGravity | 指定子组件不受android:gravity属性的影响 |
线性布局管理器:
使用 标记定义线性布局管理器
主要属性:
android:orientation属性:设置布局管理器内组件的排列方式
android:gravity属性:设置布局管理器内组件的显示位置,可写多个参数
子组件的属性:
android:layout_weight属性:设置组件所占的权重,分配剩余空间
帧布局管理器:
可以用于显示层叠的内容,并且可以实现拖动的动画效果。
使用 标记定义帧布局管理器
主要属性:
android:foreground属性:为当前的帧布局管理器设置前景图像【始终位于最上层的图像】
android:foregroundGravity属性:用于设置前景图像的位置
表格布局管理器:
以行列的形式管理放入其中的组件
使用 标记定义表格布局管理器
android:collapseColumns="1"表示隐藏第二列
android:stretchColumns="1"表示拉伸第二列【剩余空间】
android:shrinkColumns="1"表示第二列允许被收缩
当多列允许隐藏拉伸收缩时使用【,】分开各列的序号
不使用标记直接放入组件时直接占一行
网格布局管理器:
比表格布局管理器更加灵活,内容可以跨列显示,也可以跨行显示。
使用 标记定义网格布局管理器
主要属性:
android:columnCount属性:指定网格的最大列数
android:orientation属性:指定没有为组件分配行列时,组件的排列方式
android:rowCount属性:指定网格的最大行数
属性 | 作用 |
---|---|
android:layout_column | 用于指定子组件位于网格的第几列 |
android:layout_columnSpan | 用于指定子组件横向跨几列 |
android:layout_columnWeight | 用于指定子组件在水平方向的权重 |
android:layout_gravity | 用于指定子组件采取什么方式占据网格的空间 |
android:layout_row | 用于指定子组件位于网格的第几行 |
android:layout_rowSpan | 用于指定子组件纵向跨几行 |
android:layout_rowWeight | 用于指定子组件在垂直方向的权重 |
布局管理器的嵌套:
布局管理器的嵌套原则:
1、根布局管理器必须包含xmlns属性;
2、在一个布局文件中,最多只能有一个根布局管理器,如果需要有多个还需要使用一个根布局管理器将它们括起来;
3、不能嵌套太深,如果嵌套太深,则会影响性能。
基本UI组件:
文本框组件:
编辑框组件:
android:lines="5"设置文本框占5行,设置的同时去除inputType属性。
按钮组件:
图片按钮:
单选按钮:
复选框:
常用监听器:
问题 | 解释 |
---|---|
什么是监听器? | 当有组件触发设置好的监听器时,执行写好的代码,例如:单击事件监听器 |
为普通按钮添加单击事件监听器:
方法一、匿名内部类作为单击事件监听器
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"单击了按钮1",Toast.LENGTH_SHORT).show();
}
});
}
}
方法二、通过onClick属性实现
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void myClick(View view) {
Toast.makeText(MainActivity.this,"单击了按钮2",Toast.LENGTH_LONG).show();
}
}
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/button1"
android:onClick="myClick"
android:text="按钮2"/>
ImageButton和Button的区别:
相同点 | 不同点 |
---|---|
单击时都可以触发onClick事件 | ImageButton没有android:text属性 |
将多个单选按钮设置成一组,需要使用RadioGroup标记:
<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="男"/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="女"/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保密"/>
RadioGroup>
部分常用组件:
日期选择器:
时间选择器:
计时器:
计时器常用方法:
方法 | 作用 |
---|---|
setBase() | 设置计时器的起始时间 |
setFormat() | 设置显示时间的格式 |
start() | 指定开始计时 |
stop() | 指定停止计时 |
setOnChronometerTickListener() | 为计时器绑定事件监听器,当计时器改变时触发该监听器 |
————————
Activity的启动和结束:
从当前页面跳转到跳到新页面,跳转代码如下:
startActivity(new Intent(源页面.this,目标页面.class));
从当前页面回到上一个页面,相当于关闭当前页面,返回代码如下:
finish(); // 结束当前的活动页面
Activity的生命周期:
各状态之间的切换过程: