安卓基础

安卓版本

image.png

Log.e:表示错误信息,比如可能导致程序崩溃的异常。
Log.w:表示警告信息。
Log.i:表示一般消息。
Log.d:表示调试信息,可把程序运行时的变量值打印出来,方便跟踪调试。
Log.v:表示冗余信息。

APP 目录结构


image.png

一个是app(代表app模块);另一个是Gradle Scripts。其
中,app下面又有3个子目录,其功能说明如下:
(1)manifests子目录,下面只有一个XML文件,即AndroidManifest.xml,它是App的运行配置文
件。
(2)java子目录,下面有3个com.example.myapp包,其中第一个包存放当前模块的Java源代码,后
面两个包存放测试用的Java代码。
(3)res子目录,存放当前模块的资源文件。res下面又有4个子目录:
drawable目录存放图形描述文件与图片文件。
layout目录存放App页面的布局文件。
mipmap目录存放App的启动图标。
values目录存放一些常量定义文件,例如字符串常量strings.xml、像素常量dimens.xml、颜色常
量colors.xml、样式风格定义styles.xml等。
Gradle Scripts下面主要是工程的编译配置文件,主要有:
(1)build.gradle,该文件分为项目级与模块级两种,用于描述App工程的编译规则。
(2)proguard-rules.pro,该文件用于描述Java代码的混淆规则。
(3)gradle.properties,该文件用于配置编译工程的命令行参数,一般无须改动。
(4)settings.gradle,该文件配置了需要编译哪些模块。初始内容为include ':app',表示只编译app模块。
(5)local.properties,项目的本地配置文件,它在工程编译时自动生成,用于描述开发者电脑的环境配置,包括SDK的本地路径、NDK的本地路径等。

编译配置文件build.gradle

新创建的App项目默认有两个build.gradle,一个是Project项目级别的build.gradle;另一个是Module
模块级别的build.gradle。
项目级别的build.gradle指定了当前项目的总体编译规则,打开该文件在buildscript下面找到
repositories和dependencies两个节点,其中repositories节点用于设置Android Studio插件的网络仓
库地址,而dependencies节点用于设置gradle插件的版本号。由于官方的谷歌仓库位于国外,下载速度
相对较慢,因此可在repositories节点添加阿里云的仓库地址,方便国内开发者下载相关插件。修改之后
的buildscript节点内容如下所示:

buildscript {
    repositories {
// 以下四行添加阿里云的仓库地址,方便国内开发者下载相关插件
        maven { url 'https://maven.aliyun.com/repository/jcenter' }
        maven { url 'https://maven.aliyun.com/repository/google'}
        maven { url 'https://maven.aliyun.com/repository/gradle-plugin'}
        maven { url 'https://maven.aliyun.com/repository/public'}
        google()
        jcenter()
    }
    dependencies {
// 配置gradle插件版本,下面的版本号就是Android Studio的版本号
        classpath 'com.android.tools.build:gradle:4.1.0'
    }
}

模块级别的build.gradle对应于具体模块,每个模块都有自己的build.gradle,它指定了当前模块的详细编译规则。
build.gradle补充文字注释,方便更好地理解每个参数的用途。

android {
// 指定编译用的SDK版本号。比如30表示使用Android 11.0编译
    compileSdkVersion 30
// 指定编译工具的版本号。这里的头两位数字必须与compileSdkVersion保持一致,具体的版本号可
    在sdk安装目录的“sdk\build-tools”下找到
    buildToolsVersion "30.0.3"
    defaultConfig {
// 指定该模块的应用编号,也就是App的包名
        applicationId "com.example.chapter02"
// 指定App适合运行的最小SDK版本号。比如19表示至少要在Android 4.4上运行
        minSdkVersion 19
// 指定目标设备的SDK版本号。表示App最希望在哪个版本的Android上运行
        targetSdkVersion 30
// 指定App的应用版本号
        versionCode 1
// 指定App的应用版本名称
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android�optimize.txt'), 'proguard-rules.pro'
        }
    }
}
// 指定App编译的依赖信息
dependencies {
// 指定引用jar包的路径
    implementation fileTree(dir: 'libs', include: ['*.jar'])
// 指定编译Android的高版本支持库。如AppCompatActivity必须指定编译appcompat库
//appcompat库各版本见
    https://mvnrepository.com/artifact/androidx.appcompat/appcompat
    implementation 'androidx.appcompat:appcompat:1.2.0'
// 指定单元测试编译用的junit版本号
    testImplementation 'junit:junit:4.13'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

为啥这两种编译配置文件的扩展名都是Gradle呢?这是因为它们采用了Gradle工具完成编译构建操作。
Gradle工具的版本配置在gradle\wrapper\gradle-wrapper.properties,也可以依次选择菜单
File→Project Structure→Project,在弹出的设置页面中修改Gradle Version。注意每个版本的Android
Studio都有对应的Gradle版本,只有二者的版本正确对应,App工程才能成功编译。比如Android
Studio 4.1对应的Gradle版本为6.5,更多的版本对应关系见https://developer.android.google.cn/studi
o/releases/gradle-plugin#updating-plugin

运行配置文件AndroidManifest.xml

 <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.chapter02">
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".Main2Activity"></activity>
            <!-- activity节点指定了该App拥有的活动页面信息,其中拥有
            android.intent.action.MAIN的activity说明它是入口页面 -->
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>
  • android:allowBackup,是否允许应用备份。允许用户备份系统应用和第三方应用的apk安装包和应用数据,以便在刷机或者数据丢失后恢复应用,用户即可通过adb backup和adb restore来进行对应用数据的备份和恢复。为true表示允许,为false则表示不允许。
  • android:icon,指定App在手机屏幕上显示的图标。
  • android:label,指定App在手机屏幕上显示的名称。
  • android:roundIcon,指定App的圆角图标。
  • android:supportsRtl,是否支持阿拉伯语/波斯语这种从右往左的文字排列顺序。为true表示支持,为false则表示不支持。
  • android:theme,指定App的显示风格。

注意到application下面还有个activity节点,它是活动页面的注册声明,只有在AndroidManifest.xml中
正确配置了activity节点,才能在运行时访问对应的活动页面。初始配置的MainActivity正是App的默认
主页,之所以说该页面是App主页,是因为它的activity节点内部还配置了以下的过滤信息:

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

其中action节点设置的android.intent.action.MAIN表示该页面是App的入口页面,启动App时会最先打
开该页面。而category节点设置的android.intent.category.LAUNCHER决定了是否在手机屏幕上显示
App图标,如果同时有两个activity节点内部都设置了android.intent.category.LAUNCHER,那么桌面就
会显示两个App图标。以上的两种节点规则可能一开始不太好理解,读者只需记住默认主页必须同时配
置这两种过滤规则即可。

页面跳转

// 活动页面跳转,从MainActivity跳到Main2Activity
startActivity(new Intent(MainActivity.this, Main2Activity.class));

可以简化

startActivity(new Intent(this, Main2Activity.class));

布局

xml可以直接设置宽高,代码也可以设置宽高,用代码改变宽高的步骤如下:
首先确保XML中的宽高属性值为wrap_content,这样才允许在代码中修改宽高。接着打开该页面对应的Java代
码,依序执行以下3个步骤:

  1. 调用控件对象的getLayoutParams方法,获取该控件的布局参数,参数类型为ViewGroup.LayoutParams。
  2. 布局参数的width属性表示宽度,height属性表示高度,修改这两个属性值,即可调整控件的宽高。
  3. 调用控件对象的setLayoutParams方法,填入修改后的布局参数使之生效。

不过布局参数的width和height两个数值默认是px单位,需要将dp单位的数值转换为px单位的数值。 示例:

// 获取名为tv_code的文本视图
TextView tv_code = findViewById(R.id.tv_code);
// 获取tv_code的布局参数(含宽度和高度)
ViewGroup.LayoutParams params = tv_code.getLayoutParams();
// 修改布局参数中的宽度数值,注意默认px单位,需要把dp数值转成px数值
params.width = Utils.dip2px(this, 300);
tv_code.setLayoutParams(params); // 设置tv_code的布局参数

视图之间的间距

设置视图的间距有两种方式:

  1. 采用layout_margin属性,它指定了当前视图与周围平级视图之间的距离。包括layout_margin、layout_marginLeft、layout_marginTop、layout_marginRight、layout_marginBottom
  2. 采用padding属性,它指定了当前视图与内部下级视图之间的距离。包括padding、paddingLeft、paddingTop、paddingRight、paddingBottom

视图的对齐方式

  1. 采用layout_gravity属性,它指定了当前视图相对于上级视图的对齐方式。
  2. 采用gravity属性,它指定了下级视图相对于当前视图的对齐方式。

layout_gravity与gravity的取值包括:left、top、right、bottom,还可以用竖线连接各取值,例如“left|top”表示即靠左又靠上,也就是朝左上角对齐。

布局

线性布局 LinearLayout

线性布局内部的各视图有两种排列方式,默认水平排布:

  • orientation属性值为horizontal时,内部视图在水平方向从左往右排列。
  • orientation属性值为vertical时,内部视图在垂直方向从上往下排列。

权重属性名叫layout_weight,但该属性不在LinearLayout节点设置,而在线性布局的直接下级视图设置,表示该下级视图占据的宽高比例。

  • layout_width填0dp时,layout_weight表示水平方向的宽度比例。
  • layout_height填0dp时,layout_weight表示垂直方向的高度比例

相对布局RelativeLayout

相对布局的下级视图位置由其他视图决定。用于确定下级视图位置的参照物分两种:

  • 与该视图自身平级的视图;
  • 该视图的上级视图(也就是它归属的RelativeLayout)

如果不设定下级视图的参照物,那么下级视图默认显示在RelativeLayout内部的左上角。
相对位置的取值:


image.png

网格布局GridLayout

网格布局默认从左往右、从上到下排列,它新增了两个属性:

  1. columnCount属性,它指定了网格的列数,即每行能放多少个视图;
  2. rowCount属性,它指定了网格的行数,即每列能放多少个视图;


    image.png

控件

滚动视图ScrollView

滚动视图有两种:

  1. ScrollView,它是垂直方向的滚动视图;垂直方向滚动时,layout_width属性值设置为match_parent,layout_height属性值设置为wrap_content。
  2. HorizontalScrollView,它是水平方向的滚动视图;水平方向滚动时,layout_width属性值设置为wrap_content,layout_height属性值设置为match_parent。

按钮控件Button

按钮控件Button由TextView派生而来,它们之间的区别有:

  • Button拥有默认的按钮背景,而TextView默认无背景;
  • Button的内部文本默认居中对齐,而TextView的内部文本默认靠左对齐;
  • Button会默认将英文字母转为大写,而TextView保持原始的英文大小写;

比TextView多的属性:

  1. textAllCaps属性,它指定了是否将英文字母转为大写,为true是表示自动转为大写,为false表示不做大写转换。
  2. onClick属性,它用来接管用户的点击动作,指定了点击按钮时要触发哪个方法;
<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Hello World"
    android:textAllCaps="false"
    android:onClick="doClick"
    />
  • 点击事件和长按事件
// 从布局文件中获取名为btn_click_single的按钮控件
Button btn_click_single = findViewById(R.id.btn_click_single);
// 给btn_click_single设置点击监听器,一旦用户点击按钮,就触发监听器的onClick方法
btn_click_single.setOnClickListener(new MyOnClickListener());

指定监听器:

// 定义一个点击监听器,它实现了接口View.OnClickListener
class MyOnClickListener implements View.OnClickListener {
    @Override
    public void onClick(View v) { // 点击事件的处理方法
        String desc = String.format("%s 您点击了按钮:%s",
                DateUtil.getNowTime(), ((Button)
                        v).getText());
        tv_result.setText(desc); // 设置文本视图的文本内容
    }
}

ImageView 图像视图

可以设置scaleType设置图像的拉伸模式


image.png

类型展示:


image.png

图像按钮ImageButton

  • ImageButton是显示图片的图像按钮,但它继承自ImageView,而非继承Button。
    ImageButton和Button之间的区别有:
  1. Button既可显示文本也可显示图片,ImageButton只能显示图片不能显示文本。
  2. ImageButton上的图像可按比例缩放,而Button通过背景设置的图像会拉伸变形。
  3. Button只能靠背景显示一张图片,而ImageButton可分别在前景和背景显示图片,从而实现两张图片叠加的效果。

ImageButton默认的缩放类型为center,而ImageView默认的缩放类型为fitCenter。

同时展示文本与图像的可能途径包括:
(1)利用LinearLayout对ImageView和TextView组合布局。
(2)通过按钮控件Button的drawable***属性设置文本周围的图标。

  1. drawableTop:指定文字上方的图片。
  2. drawableBottom:指定文字下方的图片。
  3. drawableLeft:指定文字左边的图片。
  4. drawableRight:指定文字右边的图片。
  5. drawablePadding:指定图片与文字的间距。


    image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352

推荐阅读更多精彩内容