Android原生开发基础

Android实战

Android 原生开发基础 知识点

1 介绍了解
2 系统体系架构
3 四大应用组件
4 移动操作系统优缺点
5 开发工具
6 配置工具
7 下载相关资源
8JDK下载安装流程
9配置好SDK和JDK环境
10 第一个Hello word
11 AS开发前常用设置
12模拟器使用运行
13 真机调试
14 AndroidUI基础布局
15 加载展示XML布局
16 布局XML中 ID 和 属性
17 布局参数类LayoutParmas和xml布局属性
18 尺寸单位dppx
19 布局margin和padding
20 线性布局LinearLayout
21 相对布局RelativeLayout
22 帧布局FrameLayout
23 网格布局GridLayout
24 文本控件TextView的常用属性
gravity 共用属性 视图 /视图容器 都有 的 属性

gravity和layout_gravity

25 shape给TextView形状和图片

26文本输入框EditText
27按钮控件Button使用StateListDrawable
28图像视图ImageView
29RadioButton和CheckBox
30开关Switch和ToggleButton
31进度条ProgressBar
32拖动条SeekBar
33滚动条控件ScrollView
34日期与时间控件
35适配器Adapter与AdapterView
36ListView控件使用方式
37适配器BaseAdapter的优化
38 ListView布局风格Item
39 网格视图GridView
40 列表选项控件Spinner
41 可折叠列表ExpandableListView
42 Toast吐司控件
43 对话框控件AlertDailog
44 事件分发机制
45 悬浮框控件PopupWindow
46 Android如何创建和启动Activity组件

Activity 解释
AppcompatActivity
setContentView 设置 视图
注册 Activity 和 属性 路径配置
显示启动 隐式启动

47 分析Activity组件的生命周期

OnCreate 加载布局 视图
Dialog类型窗口 的 生命周期

Resume重现 可见

48 Activity组件间的通信方式
49 Activity回退堆栈back-stack概念

回退 堆棧 來存儲 管理 Activity Task容器
入栈 出栈 后进先出 没了 就 销毁

50 Activity启动模式之standard模式

standard 不会复用

51 Activity启动模式之singleTop模式

singleTop 复用

P58 第58课 Activity启动模式之singleTask模式
P59 第59课 Activity启动模式之singleInstance模式
P60 第60课 线程概念及三种创建方式

程序 内存空间 进程
Thread 类 run 方法
Runnable run方法
Callable 与 Future 线程
并行执行
构造方法 Thread 传 Runnable
Call 这个 实现 可以返回值
用 FutureTask 来 取值
阻塞 线程 等待 延时 把 值 取出来

P61 第61课 Service组件通过startService启动的生命周期
Service 可复用
P62 第62课 Service组件通过bindService启动的生命周期

binder类 客户端 与 服务 通信
Activity 接收 return 的 值
监听类

P63 第63课 BroadcastReceiver广播组件之动态注册
P64 第64课 BroadcastReceiver广播组件之静态注册

注册 接收
显式 发送广播

P65 第65课 通过ContentProvider组件访问系统应用数据

动态获取 权限

暴露URI

P66 第66课 通过ContentProvider组件暴露应用内部数据给第三方

往 表里 写数据
跨进程 ![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/877f64f84111abeb09071211bf748553.png)

P67 第67课 Fragment两种创建方式

一变多 运行在 一个 界面里 寄宿在 Activity 里
静态标签 加载
自定义的 fragment
动态加载

android实战-视频类app-3 项目UI主框架搭建

3 项目UI主框架搭建

5滑动视图

android实战-视频类app-4 MVP项目架构实现精华

1介绍补充
2 布局结构分析
3实现布局
4 配置网络请求框架
5实现接口
6接口测试UI实现
7下拉刷新组件集成

Android —— 列表视图 listView
Android —— Spinner下拉列表
Android——UI主框架搭建-实现主页Tab框架
Android——基于MVP项目架构 配置网络请求框架(五)
Android——欢迎 引导 页

引导页和欢迎页面 增加用户体验
#1准备图片素材,和底部原点。

#2新建两个类,GuideActivity,SplashActivity,

Android——币种转换App

布局
splash 期间获取数据

Android——上传截图相似度对比

引荐

相似图片搜索的原理
Android里的方法来实现

Android——登陆逻辑实现

结构设计

Android——登陆后台数据接口交互IDEA

客户端与服务器端的通信

接下来我们开发WebService 服务工程

检查配置Maven

新建maven WEB项目 ![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/c49d163f60bdcdc3337c96b5ff17377e.png)

maven web模板项目结构

新建

Android——登陆界面xml实现

布局文件—xml实现用户登录界面

1.在res/layout/activity_main.xml中编写布局内容:
去掉项目中页面顶部的项目名

Android 原生开发基础 知识点

1 介绍了解

发展历史 发行版本

图片[1] - Android原生开发基础 - 宋马
图片[2] - Android原生开发基础 - 宋马
图片[3] - Android原生开发基础 - 宋马
图片[4] - Android原生开发基础 - 宋马
图片[5] - Android原生开发基础 - 宋马

2 系统体系架构

图片[6] - Android原生开发基础 - 宋马
图片[7] - Android原生开发基础 - 宋马
图片[8] - Android原生开发基础 - 宋马
图片[9] - Android原生开发基础 - 宋马
图片[10] - Android原生开发基础 - 宋马
图片[11] - Android原生开发基础 - 宋马
图片[12] - Android原生开发基础 - 宋马
图片[13] - Android原生开发基础 - 宋马

3 四大应用组件

4 移动操作系统优缺点

5 开发工具

图片[14] - Android原生开发基础 - 宋马
图片[15] - Android原生开发基础 - 宋马
图片[16] - Android原生开发基础 - 宋马
图片[17] - Android原生开发基础 - 宋马

6 配置工具

图片[18] - Android原生开发基础 - 宋马
图片[19] - Android原生开发基础 - 宋马

图片[20] - Android原生开发基础 - 宋马
图片[21] - Android原生开发基础 - 宋马





步骤
新建环境变量的系统变量,变量名为“ANDROID_ADV_HOME”,变量值为存模拟器的地址。
删除模拟器默认的存放地址,即C:Users用户名.android。

(注:如果新建系统变量后没有删除默认的存放地址,则以后创建的模拟器仍存放在默认的地址)
新建模拟器验证修改是否成功。 


7 下载相关资源

图片[22] - Android原生开发基础 - 宋马
图片[23] - Android原生开发基础 - 宋马

8JDK下载安装流程

图片[24] - Android原生开发基础 - 宋马
图片[25] - Android原生开发基础 - 宋马
图片[26] - Android原生开发基础 - 宋马
图片[27] - Android原生开发基础 - 宋马
图片[28] - Android原生开发基础 - 宋马
图片[29] - Android原生开发基础 - 宋马

9配置好SDK和JDK环境

图片[30] - Android原生开发基础 - 宋马
图片[31] - Android原生开发基础 - 宋马
图片[32] - Android原生开发基础 - 宋马
图片[33] - Android原生开发基础 - 宋马
图片[34] - Android原生开发基础 - 宋马
图片[35] - Android原生开发基础 - 宋马
图片[36] - Android原生开发基础 - 宋马

10 第一个Hello word

图片[37] - Android原生开发基础 - 宋马
图片[38] - Android原生开发基础 - 宋马
图片[39] - Android原生开发基础 - 宋马
图片[40] - Android原生开发基础 - 宋马
图片[41] - Android原生开发基础 - 宋马
图片[42] - Android原生开发基础 - 宋马

11 AS开发前常用设置

图片[43] - Android原生开发基础 - 宋马
图片[44] - Android原生开发基础 - 宋马
图片[45] - Android原生开发基础 - 宋马
图片[46] - Android原生开发基础 - 宋马
图片[47] - Android原生开发基础 - 宋马

12模拟器使用运行

图片[48] - Android原生开发基础 - 宋马
图片[49] - Android原生开发基础 - 宋马
图片[50] - Android原生开发基础 - 宋马
图片[51] - Android原生开发基础 - 宋马
图片[52] - Android原生开发基础 - 宋马
HAXM

图片[53] - Android原生开发基础 - 宋马
图片[54] - Android原生开发基础 - 宋马
图片[55] - Android原生开发基础 - 宋马

13 真机调试

图片[56] - Android原生开发基础 - 宋马
图片[57] - Android原生开发基础 - 宋马
图片[58] - Android原生开发基础 - 宋马
图片[59] - Android原生开发基础 - 宋马
图片[60] - Android原生开发基础 - 宋马
图片[61] - Android原生开发基础 - 宋马
图片[62] - Android原生开发基础 - 宋马
图片[63] - Android原生开发基础 - 宋马

14 AndroidUI基础布局

图片[64] - Android原生开发基础 - 宋马
图片[65] - Android原生开发基础 - 宋马
图片[66] - Android原生开发基础 - 宋马
图片[67] - Android原生开发基础 - 宋马
图片[68] - Android原生开发基础 - 宋马
图片[69] - Android原生开发基础 - 宋马
viewgroup视图容器—>view —> 视图

线性布局

约束性布局

都是 viewgroup的子类

只有一个 根 viewgroup

图片[70] - Android原生开发基础 - 宋马
图片[71] - Android原生开发基础 - 宋马
图片[72] - Android原生开发基础 - 宋马
图片[73] - Android原生开发基础 - 宋马
XML 标签 内 都是 一个 JAVA 类 都可以 new 实例化 一个 对象

视图容器

视图

属性

再把视图装到视图容器中

15 加载展示XML布局

图片[74] - Android原生开发基础 - 宋马
XML 代码 布局

LinearLayout 视图容器 标签

视图 + 按钮

根元素

图片[75] - Android原生开发基础 - 宋马
图片[76] - Android原生开发基础 - 宋马
组件 创建 的 回调

setcontentview 加载 XML

图片[77] - Android原生开发基础 - 宋马
图片[78] - Android原生开发基础 - 宋马
约束布局

16 布局XML中 ID 和 属性

图片[79] - Android原生开发基础 - 宋马
图片[80] - Android原生开发基础 - 宋马
图片[81] - Android原生开发基础 - 宋马
图片[82] - Android原生开发基础 - 宋马

17 布局参数类LayoutParmas和xml布局属性

图片[83] - Android原生开发基础 - 宋马
图片[84] - Android原生开发基础 - 宋马
图片[85] - Android原生开发基础 - 宋马
约束布局 继承 视图容器 (抽象类 )

图片[86] - Android原生开发基础 - 宋马
图片[87] - Android原生开发基础 - 宋马
嵌套类 LayoutParams
图片[88] - Android原生开发基础 - 宋马
图片[89] - Android原生开发基础 - 宋马
LayoutParams 的 一个 子类 继承于 LP

图片[90] - Android原生开发基础 - 宋马
定位位置

视图 布局

通过 视图 获得 LayoutParams

通过 tv 模板试图 传递参数

px不行 适配 各种 屏幕

wrap 自己

match 父视图

18 尺寸单位dppx

图片[91] - Android原生开发基础 - 宋马
视图 在 视图容器中 都有 坐标点 宽高

相对于 父视图 的 位置

单位 Px 像素

布局 —- 视图容器

图片[92] - Android原生开发基础 - 宋马
图片[93] - Android原生开发基础 - 宋马
图片[94] - Android原生开发基础 - 宋马
都是 px 值

图片[95] - Android原生开发基础 - 宋马
图片[96] - Android原生开发基础 - 宋马

19 布局margin和padding

图片[97] - Android原生开发基础 - 宋马
图片[98] - Android原生开发基础 - 宋马
图片[99] - Android原生开发基础 - 宋马

视图 只有 内边距

20 线性布局LinearLayout

图片[100] - Android原生开发基础 - 宋马
图片[101] - Android原生开发基础 - 宋马
图片[102] - Android原生开发基础 - 宋马

图片[103] - Android原生开发基础 - 宋马
权重 高度 宽度 为0

图片[104] - Android原生开发基础 - 宋马

21 相对布局RelativeLayout

图片[105] - Android原生开发基础 - 宋马
图片[106] - Android原生开发基础 - 宋马
图片[107] - Android原生开发基础 - 宋马
图片[108] - Android原生开发基础 - 宋马
图片[109] - Android原生开发基础 - 宋马
图片[110] - Android原生开发基础 - 宋马图片[110] - Android原生开发基础 - 宋马
图片[111] - Android原生开发基础 - 宋马
图片[112] - Android原生开发基础 - 宋马
图片[113] - Android原生开发基础 - 宋马
图片[114] - Android原生开发基础 - 宋马
图片[115] - Android原生开发基础 - 宋马

22 帧布局FrameLayout

图片[116] - Android原生开发基础 - 宋马
图片[117] - Android原生开发基础 - 宋马

悬浮按钮 最上层

23 网格布局GridLayout

图片[118] - Android原生开发基础 - 宋马
图片[119] - Android原生开发基础 - 宋马
图片[120] - Android原生开发基础 - 宋马
图片[121] - Android原生开发基础 - 宋马
键盘 效果

24 文本控件TextView的常用属性

图片[122] - Android原生开发基础 - 宋马
文本控件 视图

图片[123] - Android原生开发基础 - 宋马
sp 文本 尺寸单位 不能用 dp

gravity 共用属性 视图 /视图容器 都有 的 属性

gravity和layout_gravity

两者都是设置对齐方式
内部的属性值相同

 center_horizontal表示在水平方向上的位置为中间

图片[124] - Android原生开发基础 - 宋马
图片[125] - Android原生开发基础 - 宋马
图片[126] - Android原生开发基础 - 宋马
图片[127] - Android原生开发基础 - 宋马
背景 也是 共用属性

图片[128] - Android原生开发基础 - 宋马
图片[129] - Android原生开发基础 - 宋马
图片[130] - Android原生开发基础 - 宋马
利于 复用

25 shape给TextView形状和图片

图片[131] - Android原生开发基础 - 宋马
图片[132] - Android原生开发基础 - 宋马
图片[133] - Android原生开发基础 - 宋马

图片[134] - Android原生开发基础 - 宋马
图片[135] - Android原生开发基础 - 宋马
图片[136] - Android原生开发基础 - 宋马
图片[137] - Android原生开发基础 - 宋马
图片[138] - Android原生开发基础 - 宋马
图片[139] - Android原生开发基础 - 宋马
图片[140] - Android原生开发基础 - 宋马
图片[141] - Android原生开发基础 - 宋马
图片[142] - Android原生开发基础 - 宋马
图片[143] - Android原生开发基础 - 宋马
图片[144] - Android原生开发基础 - 宋马
图片[145] - Android原生开发基础 - 宋马
图片[146] - Android原生开发基础 - 宋马
图片[147] - Android原生开发基础 - 宋马
图片[148] - Android原生开发基础 - 宋马
图片[149] - Android原生开发基础 - 宋马
图片[150] - Android原生开发基础 - 宋马
图片[151] - Android原生开发基础 - 宋马
图片[152] - Android原生开发基础 - 宋马
vangle 渐变角度

图片[153] - Android原生开发基础 - 宋马

比 图片 占用小

@ ====》res 目录

图片[154] - Android原生开发基础 - 宋马
图片[155] - Android原生开发基础 - 宋马
图片[156] - Android原生开发基础 - 宋马





26文本输入框EditText

图片[157] - Android原生开发基础 - 宋马
图片[158] - Android原生开发基础 - 宋马
图片[159] - Android原生开发基础 - 宋马
图片[160] - Android原生开发基础 - 宋马
图片[161] - Android原生开发基础 - 宋马
默认提示文本 图片[162] - Android原生开发基础 - 宋马
获取 内容文本

图片[163] - Android原生开发基础 - 宋马
密码格式图片[164] - Android原生开发基础 - 宋马
图片[165] - Android原生开发基础 - 宋马
图片[166] - Android原生开发基础 - 宋马
图片[167] - Android原生开发基础 - 宋马
图片[168] - Android原生开发基础 - 宋马





27按钮控件Button使用StateListDrawable

图片[169] - Android原生开发基础 - 宋马
图片[170] - Android原生开发基础 - 宋马
图片[171] - Android原生开发基础 - 宋马
图片[172] - Android原生开发基础 - 宋马
图片[173] - Android原生开发基础 - 宋马
图片[174] - Android原生开发基础 - 宋马
图片[175] - Android原生开发基础 - 宋马
图片[176] - Android原生开发基础 - 宋马
图片[177] - Android原生开发基础 - 宋马
获取 控件 的 属性

控制 点击





28图像视图ImageView

图片[178] - Android原生开发基础 - 宋马
图片[179] - Android原生开发基础 - 宋马
图片[180] - Android原生开发基础 - 宋马
图片[181] - Android原生开发基础 - 宋马
图片[182] - Android原生开发基础 - 宋马
图片[183] - Android原生开发基础 - 宋马
图片[184] - Android原生开发基础 - 宋马
图片[185] - Android原生开发基础 - 宋马
图片[186] - Android原生开发基础 - 宋马
图片[187] - Android原生开发基础 - 宋马
图片[188] - Android原生开发基础 - 宋马
图片[189] - Android原生开发基础 - 宋马
图片[190] - Android原生开发基础 - 宋马
图片[191] - Android原生开发基础 - 宋马
图片[192] - Android原生开发基础 - 宋马
图片[193] - Android原生开发基础 - 宋马
图片[194] - Android原生开发基础 - 宋马
图片[195] - Android原生开发基础 - 宋马
图片[196] - Android原生开发基础 - 宋马
图片[197] - Android原生开发基础 - 宋马
缩放 只针对 src 属性 图片[198] - Android原生开发基础 - 宋马
图片[199] - Android原生开发基础 - 宋马
图片[200] - Android原生开发基础 - 宋马
图片[201] - Android原生开发基础 - 宋马
图片[202] - Android原生开发基础 - 宋马
图片[203] - Android原生开发基础 - 宋马
图片[204] - Android原生开发基础 - 宋马
图片[205] - Android原生开发基础 - 宋马
图片[206] - Android原生开发基础 - 宋马
图片[207] - Android原生开发基础 - 宋马
图片[208] - Android原生开发基础 - 宋马
xy 拉伸 按比例

继承 这个 imageview 自定义





29RadioButton和CheckBox

图片[209] - Android原生开发基础 - 宋马
图片[210] - Android原生开发基础 - 宋马
图片[211] - Android原生开发基础 - 宋马
图片[212] - Android原生开发基础 - 宋马
图片[213] - Android原生开发基础 - 宋马
继承于 线性布局 是一个 视图容器

图片[214] - Android原生开发基础 - 宋马
图片[215] - Android原生开发基础 - 宋马
图片[216] - Android原生开发基础 - 宋马
图片[217] - Android原生开发基础 - 宋马
图片[218] - Android原生开发基础 - 宋马
图片[219] - Android原生开发基础 - 宋马
图片[220] - Android原生开发基础 - 宋马
应用清单 图片[221] - Android原生开发基础 - 宋马
图片[222] - Android原生开发基础 - 宋马
图片[223] - Android原生开发基础 - 宋马
获取 子视图 个数 遍历

得到 radiobtn

判断 checked

图片[224] - Android原生开发基础 - 宋马
图片[225] - Android原生开发基础 - 宋马
图片[226] - Android原生开发基础 - 宋马
图片[227] - Android原生开发基础 - 宋马
图片[228] - Android原生开发基础 - 宋马
图片[229] - Android原生开发基础 - 宋马
图片[230] - Android原生开发基础 - 宋马
图片[231] - Android原生开发基础 - 宋马
图片[232] - Android原生开发基础 - 宋马
图片[233] - Android原生开发基础 - 宋马
图片[234] - Android原生开发基础 - 宋马
图片[235] - Android原生开发基础 - 宋马
图片[236] - Android原生开发基础 - 宋马
图片[237] - Android原生开发基础 - 宋马
图片[238] - Android原生开发基础 - 宋马
点击 按钮 监听

图片[239] - Android原生开发基础 - 宋马
图片[240] - Android原生开发基础 - 宋马
drawable 实现

图片[241] - Android原生开发基础 - 宋马
图片[242] - Android原生开发基础 - 宋马
图片[243] - Android原生开发基础 - 宋马
图片[244] - Android原生开发基础 - 宋马
图片[245] - Android原生开发基础 - 宋马
图片[246] - Android原生开发基础 - 宋马
图片[247] - Android原生开发基础 - 宋马
图片[248] - Android原生开发基础 - 宋马





30开关Switch和ToggleButton

图片[249] - Android原生开发基础 - 宋马
图片[250] - Android原生开发基础 - 宋马
图片[251] - Android原生开发基础 - 宋马
图片[252] - Android原生开发基础 - 宋马
图片[253] - Android原生开发基础 - 宋马
图片[254] - Android原生开发基础 - 宋马
图片[255] - Android原生开发基础 - 宋马
图片[256] - Android原生开发基础 - 宋马
图片[257] - Android原生开发基础 - 宋马

图片[258] - Android原生开发基础 - 宋马
图片[259] - Android原生开发基础 - 宋马
图片[260] - Android原生开发基础 - 宋马
图片[261] - Android原生开发基础 - 宋马
图片[262] - Android原生开发基础 - 宋马
图片[263] - Android原生开发基础 - 宋马
图片[264] - Android原生开发基础 - 宋马
图片[265] - Android原生开发基础 - 宋马
图片[266] - Android原生开发基础 - 宋马
图片[267] - Android原生开发基础 - 宋马

实现这个 接口

绑定 this 这个 acitivity图片[268] - Android原生开发基础 - 宋马
图片[269] - Android原生开发基础 - 宋马

传入 对象

通过 id 判断

图片[270] - Android原生开发基础 - 宋马





31进度条ProgressBar

图片[271] - Android原生开发基础 - 宋马
下载 和 视频 播放 图片[272] - Android原生开发基础 - 宋马
图片[273] - Android原生开发基础 - 宋马
图片[274] - Android原生开发基础 - 宋马
图片[275] - Android原生开发基础 - 宋马
图片[276] - Android原生开发基础 - 宋马
图片[277] - Android原生开发基础 - 宋马

Oncreate 的 生命周期

每过一秒

就加10

用 handler 来 更新进度

安卓 消息机制 发了个 空消息

图片[278] - Android原生开发基础 - 宋马

在这 接收

再 更新

为什么 不在 线程 里 调用 这个 progress方法

安卓 应该在 UI线程 里 去做 图片[279] - Android原生开发基础 - 宋马

样式

图片[280] - Android原生开发基础 - 宋马
图片[281] - Android原生开发基础 - 宋马

存放 安卓系统 一些 java 库 安卓 库

自定义 样式 吧 太丑





32拖动条SeekBar

图片[282] - Android原生开发基础 - 宋马
图片[283] - Android原生开发基础 - 宋马
图片[284] - Android原生开发基础 - 宋马
图片[285] - Android原生开发基础 - 宋马
图片[286] - Android原生开发基础 - 宋马
图片[287] - Android原生开发基础 - 宋马
图片[288] - Android原生开发基础 - 宋马
图片[289] - Android原生开发基础 - 宋马
视频播放器 进度条 图片[290] - Android原生开发基础 - 宋马
图片[291] - Android原生开发基础 - 宋马
图片[292] - Android原生开发基础 - 宋马
图片[293] - Android原生开发基础 - 宋马
图片[294] - Android原生开发基础 - 宋马
图片[295] - Android原生开发基础 - 宋马
图片[296] - Android原生开发基础 - 宋马





33滚动条控件ScrollView

图片[297] - Android原生开发基础 - 宋马
图片[298] - Android原生开发基础 - 宋马
图片[299] - Android原生开发基础 - 宋马
图片[300] - Android原生开发基础 - 宋马
图片[301] - Android原生开发基础 - 宋马

也是个 容器

文本 滚动浏览 图片[302] - Android原生开发基础 - 宋马
图片[303] - Android原生开发基础 - 宋马
图片[304] - Android原生开发基础 - 宋马
图片[305] - Android原生开发基础 - 宋马
图片[306] - Android原生开发基础 - 宋马





34日期与时间控件

图片[307] - Android原生开发基础 - 宋马
图片[308] - Android原生开发基础 - 宋马
图片[309] - Android原生开发基础 - 宋马
图片[310] - Android原生开发基础 - 宋马
图片[311] - Android原生开发基础 - 宋马
图片[312] - Android原生开发基础 - 宋马
图片[313] - Android原生开发基础 - 宋马
图片[314] - Android原生开发基础 - 宋马
图片[315] - Android原生开发基础 - 宋马
图片[316] - Android原生开发基础 - 宋马
图片[317] - Android原生开发基础 - 宋马
图片[318] - Android原生开发基础 - 宋马
图片[319] - Android原生开发基础 - 宋马
图片[320] - Android原生开发基础 - 宋马
图片[321] - Android原生开发基础 - 宋马
图片[322] - Android原生开发基础 - 宋马
图片[323] - Android原生开发基础 - 宋马
图片[324] - Android原生开发基础 - 宋马
图片[325] - Android原生开发基础 - 宋马
图片[326] - Android原生开发基础 - 宋马
图片[327] - Android原生开发基础 - 宋马
图片[328] - Android原生开发基础 - 宋马
图片[329] - Android原生开发基础 - 宋马
图片[330] - Android原生开发基础 - 宋马
图片[331] - Android原生开发基础 - 宋马
图片[332] - Android原生开发基础 - 宋马
图片[333] - Android原生开发基础 - 宋马
图片[334] - Android原生开发基础 - 宋马
图片[335] - Android原生开发基础 - 宋马
图片[336] - Android原生开发基础 - 宋马
图片[337] - Android原生开发基础 - 宋马
图片[338] - Android原生开发基础 - 宋马

触发回调





35适配器Adapter与AdapterView

图片[339] - Android原生开发基础 - 宋马
图片[340] - Android原生开发基础 - 宋马
图片[341] - Android原生开发基础 - 宋马
图片[342] - Android原生开发基础 - 宋马
图片[343] - Android原生开发基础 - 宋马
图片[344] - Android原生开发基础 - 宋马
图片[345] - Android原生开发基础 - 宋马
图片[346] - Android原生开发基础 - 宋马
图片[347] - Android原生开发基础 - 宋马
图片[348] - Android原生开发基础 - 宋马

适配器 控件 继承 视图容器

list 需要 适配器 展示 数据

适配器 类 的 子类 图片[349] - Android原生开发基础 - 宋马
图片[350] - Android原生开发基础 - 宋马
图片[351] - Android原生开发基础 - 宋马

放好 数据源 图片[352] - Android原生开发基础 - 宋马

item 比较复杂的 结构 继承 Baseadapter





36ListView控件使用方式

图片[353] - Android原生开发基础 - 宋马
图片[354] - Android原生开发基础 - 宋马
图片[355] - Android原生开发基础 - 宋马
图片[356] - Android原生开发基础 - 宋马

创建个 数据 对象 实体类

自定义 adapter图片[357] - Android原生开发基础 - 宋马
图片[358] - Android原生开发基础 - 宋马
图片[359] - Android原生开发基础 - 宋马

重写 图片[360] - Android原生开发基础 - 宋马

position 每一行 的 下标

getview 返回 每一项 布局结构 图片[361] - Android原生开发基础 - 宋马

获取布局对象

converView 每个 item 的 视图对象

自定义 adapter 和 布局结构

C与 V 绑定 图片[362] - Android原生开发基础 - 宋马
图片[363] - Android原生开发基础 - 宋马
图片[364] - Android原生开发基础 - 宋马

list item 的 点击事件 图片[365] - Android原生开发基础 - 宋马





37适配器BaseAdapter的优化

图片[366] - Android原生开发基础 - 宋马
图片[367] - Android原生开发基础 - 宋马
图片[368] - Android原生开发基础 - 宋马

ontentview 就是 列表中每一项 view

系统自动缓存

可以直接复用 不用每次再重新加载 xml 避免 系统资源浪费

class 存储 item 的 对象

再加载 实现 加载进去 存到对象

把 视图对象 加在 viewHolder 也存起来

图片[369] - Android原生开发基础 - 宋马

标签

视图 以标签形式 保存对象

缓存 存取 方便 可复用

再赋值





38 ListView布局风格Item

图片[370] - Android原生开发基础 - 宋马
图片[371] - Android原生开发基础 - 宋马

返回 指定 試圖 類型

返回 几种 不同 的 item图片[372] - Android原生开发基础 - 宋马
图片[373] - Android原生开发基础 - 宋马
图片[374] - Android原生开发基础 - 宋马

两种 风格 布局

写 两个 layout图片[375] - Android原生开发基础 - 宋马
图片[376] - Android原生开发基础 - 宋马
图片[377] - Android原生开发基础 - 宋马
图片[378] - Android原生开发基础 - 宋马

基于 优化 变成 viewHolder

只要是 getview 加载 不同布局 和 渲染不同数据 图片[379] - Android原生开发基础 - 宋马

视图对象 赋值

holder缓存起来

布局 type 数据 区分图片[380] - Android原生开发基础 - 宋马





39 网格视图GridView

这个view 也是 配合 adapter 使用

图片[381] - Android原生开发基础 - 宋马
图片[382] - Android原生开发基础 - 宋马
图片[383] - Android原生开发基础 - 宋马

adapter 适配器 C层

item 布局风格

实现 它的几个 方法

加载 每个 item grid 布局 图片[384] - Android原生开发基础 - 宋马
图片[385] - Android原生开发基础 - 宋马
图片[386] - Android原生开发基础 - 宋马
图片[387] - Android原生开发基础 - 宋马

多种方式 列表 继承于 视图容器 取代 view 进阶





40 列表选项控件Spinner

图片[388] - Android原生开发基础 - 宋马
也需要 配合 adapter 使用 图片[389] - Android原生开发基础 - 宋马
图片[390] - Android原生开发基础 - 宋马

自定义 下拉 效果 图片[391] - Android原生开发基础 - 宋马

通过 id 找到 spinner

提供数据源 图片[392] - Android原生开发基础 - 宋马
图片[393] - Android原生开发基础 - 宋马
图片[394] - Android原生开发基础 - 宋马

一个实体类

自定义 adapter

定义 每个 item的 风格 跟之前 的 自定义 view一样

图片[395] - Android原生开发基础 - 宋马

绑定适配器

点击事件

触发 方法 得到 下标图片[396] - Android原生开发基础 - 宋马





41 可折叠列表ExpandableListView

图片[397] - Android原生开发基础 - 宋马

自定义适配器

图片[398] - Android原生开发基础 - 宋马
图片[399] - Android原生开发基础 - 宋马
图片[400] - Android原生开发基础 - 宋马

这个 组

子项

子item

自定义 时候 实现 这几个 方法

创建 俩个 集合 图片[401] - Android原生开发基础 - 宋马

item集合

图片[402] - Android原生开发基础 - 宋马

自定义的 适配器

把两个 数据源 传进来 图片[403] - Android原生开发基础 - 宋马
组 对象 child 子列表 数据

布局 结构 渲染 数据 图片[404] - Android原生开发基础 - 宋马
图片[405] - Android原生开发基础 - 宋马

点击事件





42 Toast吐司控件

图片[406] - Android原生开发基础 - 宋马
图片[407] - Android原生开发基础 - 宋马

widget 包 下 单独 组件类

三个参数

上下文

文本内容

弹出时间 图片[408] - Android原生开发基础 - 宋马
图片[409] - Android原生开发基础 - 宋马
图片[410] - Android原生开发基础 - 宋马
图片[411] - Android原生开发基础 - 宋马
图片[412] - Android原生开发基础 - 宋马
图片[413] - Android原生开发基础 - 宋马
图片[414] - Android原生开发基础 - 宋马
图片[415] - Android原生开发基础 - 宋马
图片[416] - Android原生开发基础 - 宋马
图片[417] - Android原生开发基础 - 宋马
图片[418] - Android原生开发基础 - 宋马
图片[419] - Android原生开发基础 - 宋马
图片[420] - Android原生开发基础 - 宋马
图片[421] - Android原生开发基础 - 宋马
图片[422] - Android原生开发基础 - 宋马
图片[423] - Android原生开发基础 - 宋马
图片[424] - Android原生开发基础 - 宋马
图片[425] - Android原生开发基础 - 宋马
图片[426] - Android原生开发基础 - 宋马
图片[427] - Android原生开发基础 - 宋马
图片[428] - Android原生开发基础 - 宋马
图片[429] - Android原生开发基础 - 宋马
图片[430] - Android原生开发基础 - 宋马
图片[431] - Android原生开发基础 - 宋马
图片[432] - Android原生开发基础 - 宋马
图片[433] - Android原生开发基础 - 宋马
图片[434] - Android原生开发基础 - 宋马





43 对话框控件AlertDailog

图片[435] - Android原生开发基础 - 宋马
组件 图片[436] - Android原生开发基础 - 宋马
图片[437] - Android原生开发基础 - 宋马
图片[438] - Android原生开发基础 - 宋马
图片[439] - Android原生开发基础 - 宋马
图片[440] - Android原生开发基础 - 宋马

lesson 数据源 列表 图片[441] - Android原生开发基础 - 宋马
图片[442] - Android原生开发基础 - 宋马
图片[443] - Android原生开发基础 - 宋马
图片[444] - Android原生开发基础 - 宋马
图片[445] - Android原生开发基础 - 宋马
图片[446] - Android原生开发基础 - 宋马
图片[447] - Android原生开发基础 - 宋马
图片[448] - Android原生开发基础 - 宋马
图片[449] - Android原生开发基础 - 宋马
图片[450] - Android原生开发基础 - 宋马
图片[451] - Android原生开发基础 - 宋马





44 事件分发机制

图片[452] - Android原生开发基础 - 宋马
图片[453] - Android原生开发基础 - 宋马
图片[454] - Android原生开发基础 - 宋马

dispatch 分发

intercept 拦截

图片[455] - Android原生开发基础 - 宋马
图片[456] - Android原生开发基础 - 宋马
图片[457] - Android原生开发基础 - 宋马
图片[458] - Android原生开发基础 - 宋马
图片[459] - Android原生开发基础 - 宋马
图片[460] - Android原生开发基础 - 宋马
图片[461] - Android原生开发基础 - 宋马

自定义 线性 和 button 视图

图片[462] - Android原生开发基础 - 宋马
图片[463] - Android原生开发基础 - 宋马
图片[464] - Android原生开发基础 - 宋马
图片[465] - Android原生开发基础 - 宋马
图片[466] - Android原生开发基础 - 宋马
图片[467] - Android原生开发基础 - 宋马
图片[468] - Android原生开发基础 - 宋马
图片[469] - Android原生开发基础 - 宋马
图片[470] - Android原生开发基础 - 宋马
图片[471] - Android原生开发基础 - 宋马
图片[472] - Android原生开发基础 - 宋马
图片[473] - Android原生开发基础 - 宋马
图片[474] - Android原生开发基础 - 宋马
图片[475] - Android原生开发基础 - 宋马
图片[476] - Android原生开发基础 - 宋马
图片[477] - Android原生开发基础 - 宋马
图片[478] - Android原生开发基础 - 宋马
图片[479] - Android原生开发基础 - 宋马
图片[480] - Android原生开发基础 - 宋马
图片[481] - Android原生开发基础 - 宋马
图片[482] - Android原生开发基础 - 宋马
图片[483] - Android原生开发基础 - 宋马
图片[484] - Android原生开发基础 - 宋马
图片[485] - Android原生开发基础 - 宋马
图片[486] - Android原生开发基础 - 宋马

dispatchtouchevent

图片[487] - Android原生开发基础 - 宋马
图片[488] - Android原生开发基础 - 宋马
Activity 不会向下分发

图片[489] - Android原生开发基础 - 宋马
图片[490] - Android原生开发基础 - 宋马
图片[491] - Android原生开发基础 - 宋马
图片[492] - Android原生开发基础 - 宋马
终止之后的 ontouchEvent也 不执行
图片[493] - Android原生开发基础 - 宋马
同 popupwindow
图片[494] - Android原生开发基础 - 宋马
true 分发事件 会被拦截
图片[495] - Android原生开发基础 - 宋马
图片[496] - Android原生开发基础 - 宋马
图片[497] - Android原生开发基础 - 宋马
图片[498] - Android原生开发基础 - 宋马
就会 执行 onTouchEvent
图片[499] - Android原生开发基础 - 宋马
图片[500] - Android原生开发基础 - 宋马
图片[501] - Android原生开发基础 - 宋马





45 悬浮框控件PopupWindow

图片[502] - Android原生开发基础 - 宋马
图片[503] - Android原生开发基础 - 宋马
图片[504] - Android原生开发基础 - 宋马
图片[505] - Android原生开发基础 - 宋马
图片[506] - Android原生开发基础 - 宋马
图片[507] - Android原生开发基础 - 宋马
图片[508] - Android原生开发基础 - 宋马
图片[509] - Android原生开发基础 - 宋马
图片[510] - Android原生开发基础 - 宋马
图片[511] - Android原生开发基础 - 宋马
图片[512] - Android原生开发基础 - 宋马
图片[513] - Android原生开发基础 - 宋马
图片[514] - Android原生开发基础 - 宋马
图片[515] - Android原生开发基础 - 宋马
图片[516] - Android原生开发基础 - 宋马





46 Android如何创建和启动Activity组件

Activity 解释

AppcompatActivity

图片[517] - Android原生开发基础 - 宋马图片[517] - Android原生开发基础 - 宋马图片[517] - Android原生开发基础 - 宋马图片[517] - Android原生开发基础 - 宋马图片[517] - Android原生开发基础 - 宋马

setContentView 设置 视图

图片[518] - Android原生开发基础 - 宋马

注册 Activity 和 属性 路径配置

显示启动 隐式启动

图片[519] - Android原生开发基础 - 宋马
图片[520] - Android原生开发基础 - 宋马
图片[521] - Android原生开发基础 - 宋马
匿名启动

主题 对话框 显示 Activity
图片[522] - Android原生开发基础 - 宋马





47 分析Activity组件的生命周期

图片[523] - Android原生开发基础 - 宋马

OnCreate 加载布局 视图

图片[524] - Android原生开发基础 - 宋马
图片[525] - Android原生开发基础 - 宋马
图片[526] - Android原生开发基础 - 宋马
图片[527] - Android原生开发基础 - 宋马
图片[528] - Android原生开发基础 - 宋马

图片[529] - Android原生开发基础 - 宋马
图片[530] - Android原生开发基础 - 宋马
图片[531] - Android原生开发基础 - 宋马

Dialog类型窗口 的 生命周期

图片[532] - Android原生开发基础 - 宋马

Resume重现 可见





48 Activity组件间的通信方式

图片[533] - Android原生开发基础 - 宋马
图片[534] - Android原生开发基础 - 宋马
图片[535] - Android原生开发基础 - 宋马
图片[536] - Android原生开发基础 - 宋马
图片[537] - Android原生开发基础 - 宋马
图片[538] - Android原生开发基础 - 宋马
图片[539] - Android原生开发基础 - 宋马
图片[540] - Android原生开发基础 - 宋马
图片[541] - Android原生开发基础 - 宋马
图片[542] - Android原生开发基础 - 宋马
图片[543] - Android原生开发基础 - 宋马
图片[544] - Android原生开发基础 - 宋马
图片[545] - Android原生开发基础 - 宋马

49 Activity回退堆栈back-stack概念

图片[546] - Android原生开发基础 - 宋马

回退 堆棧 來存儲 管理 Activity Task容器

入栈 出栈 后进先出 没了 就 销毁

50 Activity启动模式之standard模式

图片[547] - Android原生开发基础 - 宋马

standard 不会复用

图片[548] - Android原生开发基础 - 宋马
图片[549] - Android原生开发基础 - 宋马

51 Activity启动模式之singleTop模式

singleTop 复用

图片[550] - Android原生开发基础 - 宋马
图片[551] - Android原生开发基础 - 宋马
图片[552] - Android原生开发基础 - 宋马

P58 第58课 Activity启动模式之singleTask模式

图片[553] - Android原生开发基础 - 宋马
图片[554] - Android原生开发基础 - 宋马
图片[555] - Android原生开发基础 - 宋马

P59 第59课 Activity启动模式之singleInstance模式

图片[556] - Android原生开发基础 - 宋马

P60 第60课 线程概念及三种创建方式

程序 内存空间 进程

图片[557] - Android原生开发基础 - 宋马

Thread 类 run 方法

Runnable run方法

Callable 与 Future 线程

图片[558] - Android原生开发基础 - 宋马
图片[559] - Android原生开发基础 - 宋马
图片[560] - Android原生开发基础 - 宋马图片[560] - Android原生开发基础 - 宋马
图片[561] - Android原生开发基础 - 宋马

并行执行

图片[562] - Android原生开发基础 - 宋马
图片[563] - Android原生开发基础 - 宋马图片[563] - Android原生开发基础 - 宋马

构造方法 Thread 传 Runnable

图片[564] - Android原生开发基础 - 宋马

Call 这个 实现 可以返回值

用 FutureTask 来 取值

阻塞 线程 等待 延时 把 值 取出来

图片[565] - Android原生开发基础 - 宋马

P61 第61课 Service组件通过startService启动的生命周期

Service 可复用

图片[566] - Android原生开发基础 - 宋马
图片[567] - Android原生开发基础 - 宋马
图片[568] - Android原生开发基础 - 宋马
图片[569] - Android原生开发基础 - 宋马
图片[570] - Android原生开发基础 - 宋马
图片[571] - Android原生开发基础 - 宋马
图片[572] - Android原生开发基础 - 宋马
图片[573] - Android原生开发基础 - 宋马

P62 第62课 Service组件通过bindService启动的生命周期

binder类 客户端 与 服务 通信

图片[574] - Android原生开发基础 - 宋马

图片[575] - Android原生开发基础 - 宋马
图片[576] - Android原生开发基础 - 宋马

Activity 接收 return 的 值

监听类

图片[577] - Android原生开发基础 - 宋马
图片[578] - Android原生开发基础 - 宋马图片[578] - Android原生开发基础 - 宋马
图片[579] - Android原生开发基础 - 宋马
图片[580] - Android原生开发基础 - 宋马
图片[581] - Android原生开发基础 - 宋马
图片[582] - Android原生开发基础 - 宋马
图片[583] - Android原生开发基础 - 宋马
图片[584] - Android原生开发基础 - 宋马
图片[585] - Android原生开发基础 - 宋马

P63 第63课 BroadcastReceiver广播组件之动态注册

图片[586] - Android原生开发基础 - 宋马
图片[587] - Android原生开发基础 - 宋马
图片[588] - Android原生开发基础 - 宋马
图片[589] - Android原生开发基础 - 宋马
图片[590] - Android原生开发基础 - 宋马
图片[591] - Android原生开发基础 - 宋马
图片[592] - Android原生开发基础 - 宋马
图片[593] - Android原生开发基础 - 宋马
图片[594] - Android原生开发基础 - 宋马
图片[595] - Android原生开发基础 - 宋马
图片[596] - Android原生开发基础 - 宋马
图片[597] - Android原生开发基础 - 宋马
图片[598] - Android原生开发基础 - 宋马
图片[599] - Android原生开发基础 - 宋马
图片[600] - Android原生开发基础 - 宋马
图片[601] - Android原生开发基础 - 宋马
图片[602] - Android原生开发基础 - 宋马
图片[603] - Android原生开发基础 - 宋马

P64 第64课 BroadcastReceiver广播组件之静态注册

图片[604] - Android原生开发基础 - 宋马
图片[605] - Android原生开发基础 - 宋马

注册 接收

图片[606] - Android原生开发基础 - 宋马

显式 发送广播

图片[607] - Android原生开发基础 - 宋马
图片[608] - Android原生开发基础 - 宋马

P65 第65课 通过ContentProvider组件访问系统应用数据

图片[609] - Android原生开发基础 - 宋马
图片[610] - Android原生开发基础 - 宋马
图片[611] - Android原生开发基础 - 宋马
图片[612] - Android原生开发基础 - 宋马
图片[613] - Android原生开发基础 - 宋马
图片[614] - Android原生开发基础 - 宋马
图片[615] - Android原生开发基础 - 宋马
图片[616] - Android原生开发基础 - 宋马
图片[617] - Android原生开发基础 - 宋马
图片[618] - Android原生开发基础 - 宋马
图片[619] - Android原生开发基础 - 宋马
图片[620] - Android原生开发基础 - 宋马
图片[621] - Android原生开发基础 - 宋马

动态获取 权限

图片[622] - Android原生开发基础 - 宋马
图片[623] - Android原生开发基础 - 宋马
图片[624] - Android原生开发基础 - 宋马
图片[625] - Android原生开发基础 - 宋马

暴露URI

P66 第66课 通过ContentProvider组件暴露应用内部数据给第三方

图片[626] - Android原生开发基础 - 宋马

往 表里 写数据

图片[627] - Android原生开发基础 - 宋马
图片[628] - Android原生开发基础 - 宋马

图片[629] - Android原生开发基础 - 宋马
图片[630] - Android原生开发基础 - 宋马
图片[631] - Android原生开发基础 - 宋马

图片[632] - Android原生开发基础 - 宋马
图片[633] - Android原生开发基础 - 宋马
图片[634] - Android原生开发基础 - 宋马
图片[635] - Android原生开发基础 - 宋马
图片[636] - Android原生开发基础 - 宋马
图片[637] - Android原生开发基础 - 宋马
图片[638] - Android原生开发基础 - 宋马
图片[639] - Android原生开发基础 - 宋马
图片[640] - Android原生开发基础 - 宋马
图片[641] - Android原生开发基础 - 宋马

图片[642] - Android原生开发基础 - 宋马
图片[643] - Android原生开发基础 - 宋马
图片[644] - Android原生开发基础 - 宋马
图片[645] - Android原生开发基础 - 宋马
图片[646] - Android原生开发基础 - 宋马
图片[647] - Android原生开发基础 - 宋马
图片[648] - Android原生开发基础 - 宋马
图片[649] - Android原生开发基础 - 宋马
图片[650] - Android原生开发基础 - 宋马
图片[651] - Android原生开发基础 - 宋马
图片[652] - Android原生开发基础 - 宋马
图片[653] - Android原生开发基础 - 宋马

跨进程

P67 第67课 Fragment两种创建方式

一变多 运行在 一个 界面里 寄宿在 Activity 里

图片[654] - Android原生开发基础 - 宋马

静态标签 加载

图片[655] - Android原生开发基础 - 宋马

自定义的 fragment

加载 布局

动态加载

 https://www.bilibili.com/video/BV1PE411u7ox?from=search&seid=1701600622306119124

android实战-视频类app-3 项目UI主框架搭建

图片[656] - Android原生开发基础 - 宋马

3 项目UI主框架搭建

5滑动视图

图片[657] - Android原生开发基础 - 宋马
图片[658] - Android原生开发基础 - 宋马
viewpage fragment 嵌套 做调整
图片[659] - Android原生开发基础 - 宋马
新建一个 fragment
图片[660] - Android原生开发基础 - 宋马
看这个 initContentView

图片[661] - Android原生开发基础 - 宋马
图片[662] - Android原生开发基础 - 宋马
还有一个 布局文件 图片[663] - Android原生开发基础 - 宋马
图片[664] - Android原生开发基础 - 宋马
图片[665] - Android原生开发基础 - 宋马
准备数据 tabbar
图片[666] - Android原生开发基础 - 宋马
图片[667] - Android原生开发基础 - 宋马
初始化数据 写个方法 图片[668] - Android原生开发基础 - 宋马
图片[669] - Android原生开发基础 - 宋马
重写 加在 Base 裏的 initdata數據初始化 图片[670] - Android原生开发基础 - 宋马
图片[671] - Android原生开发基础 - 宋马
Base 裏 不要 抽象 abstract 讓Fragment 初始化數據 配置 tabbar图片[672] - Android原生开发基础 - 宋马
準備 tabbar 和 viewpager 的 佈局 图片[673] - Android原生开发基础 - 宋马

Tablayout 滑动视图 5.0 新特性 選項卡

V4 包 3.0 新特性

数据初始化 图片[674] - Android原生开发基础 - 宋马
图片[675] - Android原生开发基础 - 宋马
在gradle 里 配置 依赖包 图片[676] - Android原生开发基础 - 宋马
图片[677] - Android原生开发基础 - 宋马
图片[678] - Android原生开发基础 - 宋马
图片[679] - Android原生开发基础 - 宋马
图片[680] - Android原生开发基础 - 宋马
图片[681] - Android原生开发基础 - 宋马
准备 viewpage 的 adapter图片[682] - Android原生开发基础 - 宋马
图片[683] - Android原生开发基础 - 宋马

fragment adapter 用来解析文本

截取 字符串 title 和 类型 图片[684] - Android原生开发基础 - 宋马
传回服务器

准备 一个 video viewpage 暂时不用 图片[685] - Android原生开发基础 - 宋马
图片[686] - Android原生开发基础 - 宋马
其他页面 图片[687] - Android原生开发基础 - 宋马

布局一样

改数据图片[688] - Android原生开发基础 - 宋马
图片[689] - Android原生开发基础 - 宋马
图片[690] - Android原生开发基础 - 宋马
图片[691] - Android原生开发基础 - 宋马
图片[692] - Android原生开发基础 - 宋马
图片[693] - Android原生开发基础 - 宋马
图片[694] - Android原生开发基础 - 宋马
图片[695] - Android原生开发基础 - 宋马
图片[696] - Android原生开发基础 - 宋马
图片[697] - Android原生开发基础 - 宋马
更改布局文件 图片[698] - Android原生开发基础 - 宋马
页面 继续 图片[699] - Android原生开发基础 - 宋马
来一个 Navigation 导航条 图片[700] - Android原生开发基础 - 宋马
图片[701] - Android原生开发基础 - 宋马
图片[702] - Android原生开发基础 - 宋马
图片[703] - Android原生开发基础 - 宋马
图片[704] - Android原生开发基础 - 宋马
Toolbar 放了一个 Tablayout tabbar图片[705] - Android原生开发基础 - 宋马
图片[706] - Android原生开发基础 - 宋马
图片[707] - Android原生开发基础 - 宋马
图片[708] - Android原生开发基础 - 宋马
图片[709] - Android原生开发基础 - 宋马
图片[710] - Android原生开发基础 - 宋马

android实战-视频类app-4 MVP项目架构实现精华

1介绍补充

图片[711] - Android原生开发基础 - 宋马
图片[712] - Android原生开发基础 - 宋马
图片[713] - Android原生开发基础 - 宋马
图片[714] - Android原生开发基础 - 宋马
图片[715] - Android原生开发基础 - 宋马
模拟器 系统版本 getcolor 图片[716] - Android原生开发基础 - 宋马
对 服务器 传参 不一样

2 布局结构分析

图片[717] - Android原生开发基础 - 宋马图片[717] - Android原生开发基础 - 宋马
图片[718] - Android原生开发基础 - 宋马

volley 也是 对 imageview 进行 拓展

图片[719] - Android原生开发基础 - 宋马
textview box 都控制不了 图片 大小

3实现布局

图片[720] - Android原生开发基础 - 宋马
准备资源 图片[721] - Android原生开发基础 - 宋马
图片[722] - Android原生开发基础 - 宋马
图片[723] - Android原生开发基础 - 宋马
图片[724] - Android原生开发基础 - 宋马
图片[725] - Android原生开发基础 - 宋马
图片[726] - Android原生开发基础 - 宋马
图片[727] - Android原生开发基础 - 宋马
一些默认的 图片 图片[728] - Android原生开发基础 - 宋马
新建一个 布局文件 图片[729] - Android原生开发基础 - 宋马
图片[730] - Android原生开发基础 - 宋马
图片[731] - Android原生开发基础 - 宋马
搞个 vo框架 图片[732] - Android原生开发基础 - 宋马
图片[733] - Android原生开发基础 - 宋马
图片[734] - Android原生开发基础 - 宋马
关联 jar包图片[735] - Android原生开发基础 - 宋马
图片[736] - Android原生开发基础 - 宋马
自定义 view 继承 networkimgview 图片[737] - Android原生开发基础 - 宋马
自定义 属性 图片[738] - Android原生开发基础 - 宋马
图片[739] - Android原生开发基础 - 宋马
图片[740] - Android原生开发基础 - 宋马
将 下载下来的 图片 处理成 圆角图片[741] - Android原生开发基础 - 宋马
自定义属性 包名 图片[742] - Android原生开发基础 - 宋马
图片[743] - Android原生开发基础 - 宋马

默认 头像 图片[744] - Android原生开发基础 - 宋马
图片[745] - Android原生开发基础 - 宋马
图片[746] - Android原生开发基础 - 宋马
图片[747] - Android原生开发基础 - 宋马
图片[748] - Android原生开发基础 - 宋马
图片[749] - Android原生开发基础 - 宋马
图片[750] - Android原生开发基础 - 宋马
图片[751] - Android原生开发基础 - 宋马
图片[752] - Android原生开发基础 - 宋马图片[752] - Android原生开发基础 - 宋马
图片[753] - Android原生开发基础 - 宋马
图片[754] - Android原生开发基础 - 宋马
图片[755] - Android原生开发基础 - 宋马
图片[756] - Android原生开发基础 - 宋马图片[756] - Android原生开发基础 - 宋马
图片[757] - Android原生开发基础 - 宋马
剩下 最底下 linear layout图片[758] - Android原生开发基础 - 宋马
图片[759] - Android原生开发基础 - 宋马
图片[760] - Android原生开发基础 - 宋马

4 配置网络请求框架

图片[761] - Android原生开发基础 - 宋马
图片[762] - Android原生开发基础 - 宋马
图片[763] - Android原生开发基础 - 宋马
对 系统 请求 简单 封装 图片[764] - Android原生开发基础 - 宋马
图片[765] - Android原生开发基础 - 宋马
图片[766] - Android原生开发基础 - 宋马
图片[767] - Android原生开发基础 - 宋马
图片[768] - Android原生开发基础 - 宋马
图片[769] - Android原生开发基础 - 宋马
图片[770] - Android原生开发基础 - 宋马
图片[771] - Android原生开发基础 - 宋马
图片[772] - Android原生开发基础 - 宋马
图片[773] - Android原生开发基础 - 宋马
图片[774] - Android原生开发基础 - 宋马
各种 框架 网络 实现 图片[775] - Android原生开发基础 - 宋马
传入命令 执行 异步 图片[776] - Android原生开发基础 - 宋马
执行在回调 图片[777] - Android原生开发基础 - 宋马
图片[778] - Android原生开发基础 - 宋马
用来请求网络 url 参数图片[779] - Android原生开发基础 - 宋马
图片[780] - Android原生开发基础 - 宋马

5实现接口

图片[781] - Android原生开发基础 - 宋马
图片[782] - Android原生开发基础 - 宋马
实现 model 和 presenter图片[783] - Android原生开发基础 - 宋马
图片[784] - Android原生开发基础 - 宋马
图片[785] - Android原生开发基础 - 宋马
图片[786] - Android原生开发基础 - 宋马
图片[787] - Android原生开发基础 - 宋马
图片[788] - Android原生开发基础 - 宋马
图片[789] - Android原生开发基础 - 宋马
图片[790] - Android原生开发基础 - 宋马
图片[791] - Android原生开发基础 - 宋马
图片[792] - Android原生开发基础 - 宋马
图片[793] - Android原生开发基础 - 宋马
图片[794] - Android原生开发基础 - 宋马
图片[795] - Android原生开发基础 - 宋马
图片[796] - Android原生开发基础 - 宋马
图片[797] - Android原生开发基础 - 宋马
图片[798] - Android原生开发基础 - 宋马
图片[799] - Android原生开发基础 - 宋马
图片[800] - Android原生开发基础 - 宋马
图片[801] - Android原生开发基础 - 宋马
上下文 存储 图片[802] - Android原生开发基础 - 宋马
图片[803] - Android原生开发基础 - 宋马
图片[804] - Android原生开发基础 - 宋马
图片[805] - Android原生开发基础 - 宋马
图片[806] - Android原生开发基础 - 宋马
图片[807] - Android原生开发基础 - 宋马
图片[808] - Android原生开发基础 - 宋马
图片[809] - Android原生开发基础 - 宋马
接口的 请求参数 图片[810] - Android原生开发基础 - 宋马
图片[811] - Android原生开发基础 - 宋马
图片[812] - Android原生开发基础 - 宋马
获取 列表 图片[813] - Android原生开发基础 - 宋马
P层 处理逻辑 图片[814] - Android原生开发基础 - 宋马
图片[815] - Android原生开发基础 - 宋马
图片[816] - Android原生开发基础 - 宋马
图片[817] - Android原生开发基础 - 宋马
图片[818] - Android原生开发基础 - 宋马
图片[819] - Android原生开发基础 - 宋马
图片[820] - Android原生开发基础 - 宋马
图片[821] - Android原生开发基础 - 宋马
图片[822] - Android原生开发基础 - 宋马
图片[823] - Android原生开发基础 - 宋马
图片[824] - Android原生开发基础 - 宋马
图片[825] - Android原生开发基础 - 宋马
图片[826] - Android原生开发基础 - 宋马
图片[827] - Android原生开发基础 - 宋马
下拉刷新 逻辑 图片[828] - Android原生开发基础 - 宋马
图片[829] - Android原生开发基础 - 宋马

6接口测试UI实现

图片[830] - Android原生开发基础 - 宋马
下拉刷新 图片[831] - Android原生开发基础 - 宋马
图片[832] - Android原生开发基础 - 宋马
图片[833] - Android原生开发基础 - 宋马
图片[834] - Android原生开发基础 - 宋马
下个断点图片[835] - Android原生开发基础 - 宋马
图片[836] - Android原生开发基础 - 宋马
图片[837] - Android原生开发基础 - 宋马
下一步

进到方法里面

跳出方法 (构造方法)

跳出方法

下一个断点

所有断点

取消断点

图片[838] - Android原生开发基础 - 宋马
图片[839] - Android原生开发基础 - 宋马
图片[840] - Android原生开发基础 - 宋马
图片[841] - Android原生开发基础 - 宋马
图片[842] - Android原生开发基础 - 宋马
把测试 代码 拿到 UI层 替换 图片[843] - Android原生开发基础 - 宋马
图片[844] - Android原生开发基础 - 宋马
图片[845] - Android原生开发基础 - 宋马
图片[846] - Android原生开发基础 - 宋马
图片[847] - Android原生开发基础 - 宋马
图片[848] - Android原生开发基础 - 宋马
将 代码 拿过来 图片[849] - Android原生开发基础 - 宋马
绑定 p图片[850] - Android原生开发基础 - 宋马
图片[851] - Android原生开发基础 - 宋马
封装 数据请求 方法 (刚才 测试 那个 )图片[852] - Android原生开发基础 - 宋马图片[852] - Android原生开发基础 - 宋马
图片[853] - Android原生开发基础 - 宋马
图片[854] - Android原生开发基础 - 宋马

7下拉刷新组件集成

图片[855] - Android原生开发基础 - 宋马
图片[856] - Android原生开发基础 - 宋马
配置 下拉刷新 组件 图片[857] - Android原生开发基础 - 宋马
图片[858] - Android原生开发基础 - 宋马

​ refreshview 5.0

初始化 视图 图片[859] - Android原生开发基础 - 宋马
图片[860] - Android原生开发基础 - 宋马
图片[861] - Android原生开发基础 - 宋马
图片[862] - Android原生开发基础 - 宋马
图片[863] - Android原生开发基础 - 宋马
图片[864] - Android原生开发基础 - 宋马
图片[865] - Android原生开发基础 - 宋马
图片[866] - Android原生开发基础 - 宋马
传数据 图片[867] - Android原生开发基础 - 宋马
配置 viewholder图片[868] - Android原生开发基础 - 宋马
图片[869] - Android原生开发基础 - 宋马
布局 初始化 图片[870] - Android原生开发基础 - 宋马
解析布局

配置 viewholder 图片[871] - Android原生开发基础 - 宋马
图片[872] - Android原生开发基础 - 宋马
和 创建 布局 图片[873] - Android原生开发基础 - 宋马
绑定数据 图片[874] - Android原生开发基础 - 宋马
图片[875] - Android原生开发基础 - 宋马

用到 vo 框架 下载图片

view 在这 为 布局文件 图片[876] - Android原生开发基础 - 宋马

Android是一个完全遵循MVC模式设计的框架,Activity是C,Layout是V,Adapter是M

图片[877] - Android原生开发基础 - 宋马
初始化 下拉刷新 组件 图片[878] - Android原生开发基础 - 宋马
图片[879] - Android原生开发基础 - 宋马
图片[880] - Android原生开发基础 - 宋马
图片[881] - Android原生开发基础 - 宋马
图片[882] - Android原生开发基础 - 宋马
布局管理器 确定视图容器 图片[883] - Android原生开发基础 - 宋马
图片[884] - Android原生开发基础 - 宋马
viewadapter 填充数据

上拉加载 更多 视图 

图片[885] - Android原生开发基础 - 宋马
添加 动作 (上下)图片[886] - Android原生开发基础 - 宋马
图片[887] - Android原生开发基础 - 宋马
刷新 adapter —> 刷新 列表 —>UI图片[888] - Android原生开发基础 - 宋马
图片[889] - Android原生开发基础 - 宋马
图片[890] - Android原生开发基础 - 宋马
图片[891] - Android原生开发基础 - 宋马

Android —— 列表视图 listView

图片[892] - Android原生开发基础 - 宋马图片[892] - Android原生开发基础 - 宋马图片[892] - Android原生开发基础 - 宋马

Android —— Spinner下拉列表

图片[893] - Android原生开发基础 - 宋马
图片[894] - Android原生开发基础 - 宋马
图片[895] - Android原生开发基础 - 宋马

Android——UI主框架搭建-实现主页Tab框架

系统组件 + id (规范)
图片[896] - Android原生开发基础 - 宋马
图片[897] - Android原生开发基础 - 宋马
Tab 属性
图片[898] - Android原生开发基础 - 宋马图片[898] - Android原生开发基础 - 宋马图片[898] - Android原生开发基础 - 宋马
图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马图片[899] - Android原生开发基础 - 宋马
图片[900] - Android原生开发基础 - 宋马图片[900] - Android原生开发基础 - 宋马图片[900] - Android原生开发基础 - 宋马图片[900] - Android原生开发基础 - 宋马图片[900] - Android原生开发基础 - 宋马图片[900] - Android原生开发基础 - 宋马图片[900] - Android原生开发基础 - 宋马图片[900] - Android原生开发基础 - 宋马图片[900] - Android原生开发基础 - 宋马图片[900] - Android原生开发基础 - 宋马图片[900] - Android原生开发基础 - 宋马图片[900] - Android原生开发基础 - 宋马
图片[901] - Android原生开发基础 - 宋马图片[901] - Android原生开发基础 - 宋马图片[901] - Android原生开发基础 - 宋马
图片[902] - Android原生开发基础 - 宋马图片[902] - Android原生开发基础 - 宋马
图片[903] - Android原生开发基础 - 宋马图片[903] - Android原生开发基础 - 宋马图片[903] - Android原生开发基础 - 宋马图片[903] - Android原生开发基础 - 宋马图片[903] - Android原生开发基础 - 宋马图片[903] - Android原生开发基础 - 宋马图片[903] - Android原生开发基础 - 宋马图片[903] - Android原生开发基础 - 宋马
图片[904] - Android原生开发基础 - 宋马图片[904] - Android原生开发基础 - 宋马图片[904] - Android原生开发基础 - 宋马图片[904] - Android原生开发基础 - 宋马 图片[904] - Android原生开发基础 - 宋马 图片[904] - Android原生开发基础 - 宋马图片[904] - Android原生开发基础 - 宋马 图片[904] - Android原生开发基础 - 宋马图片[904] - Android原生开发基础 - 宋马图片[904] - Android原生开发基础 - 宋马图片[904] - Android原生开发基础 - 宋马
图片[905] - Android原生开发基础 - 宋马图片[905] - Android原生开发基础 - 宋马图片[905] - Android原生开发基础 - 宋马图片[905] - Android原生开发基础 - 宋马图片[905] - Android原生开发基础 - 宋马图片[905] - Android原生开发基础 - 宋马图片[905] - Android原生开发基础 - 宋马图片[905] - Android原生开发基础 - 宋马图片[905] - Android原生开发基础 - 宋马图片[905] - Android原生开发基础 - 宋马图片[905] - Android原生开发基础 - 宋马图片[905] - Android原生开发基础 - 宋马图片[905] - Android原生开发基础 - 宋马图片[905] - Android原生开发基础 - 宋马图片[905] - Android原生开发基础 - 宋马
图片[906] - Android原生开发基础 - 宋马图片[906] - Android原生开发基础 - 宋马图片[906] - Android原生开发基础 - 宋马图片[906] - Android原生开发基础 - 宋马图片[906] - Android原生开发基础 - 宋马
图片[907] - Android原生开发基础 - 宋马图片[907] - Android原生开发基础 - 宋马

Android——基于MVP项目架构 配置网络请求框架(五)

图片[908] - Android原生开发基础 - 宋马图片[908] - Android原生开发基础 - 宋马
图片[909] - Android原生开发基础 - 宋马
图片[910] - Android原生开发基础 - 宋马
图片[911] - Android原生开发基础 - 宋马图片[911] - Android原生开发基础 - 宋马
图片[912] - Android原生开发基础 - 宋马图片[912] - Android原生开发基础 - 宋马

Android——欢迎 引导 页

引导页和欢迎页面 增加用户体验

引导页 第一次 安装该APP的时候显示
欢迎页 每次进入应用 时候出现

功能
逻辑方法

引导页是几张不同的图片,下面会有一个表示原点,指明当前是第几页。


#1准备图片素材,和底部原点。

#2新建两个类,GuideActivity,SplashActivity,

第一个类用于实现引导页,
第二个用于判断APP是否为第一次进入,是就启动引导页,不是的话进入主页面
图片[913] - Android原生开发基础 - 宋马

 package com.eduapp;

import android.content.Intent;
import android.os.Handler;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;

import java.util.Timer;
import java.util.TimerTask;


public class splashActivity extends AppCompatActivity  implements View.OnClickListener{
            

    private  int time_back = 5;
    private TextView tv;
    Timer timer = new Timer();
    private  Handler handler;
    private  Runnable runnable;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
            
        super.onCreate(savedInstanceState);
        int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN;
        getWindow().setFlags(flag,flag);
        setContentView(R.layout.activity_splash);
        initView();
        timer.schedule(task,1000,1000);
        handler = new Handler();
        handler.postDelayed(runnable = new Runnable() {
            
            @Override
            public void run() {
            
                Intent intent = new Intent(splashActivity.this,MainActivity.class);
                startActivity(intent);
                finish();
            }
        },5000);
    }
    private  void  initView(){
            
        tv = findViewById(R.id.textView2);
        tv.setOnClickListener(this);
    }

    TimerTask task = new TimerTask() {
            
        @Override
        public void run() {
            
            runOnUiThread(new Runnable() {
            
                @Override
                public void run() {
            
                    time_back--;
                    tv.setText("跳过 "+time_back);
                    if(time_back<0){
            
                        timer.cancel();
                        tv.setVisibility(View.GONE);
                    }
                }
            });
        }
    };

    @Override
    public void onClick(View view){
            
        switch (view.getId()){
            
            case  R.id.textView2:
                Intent intent = new Intent(splashActivity.this,MainActivity.class);
                startActivity(intent);
                finish();
                if(runnable != null){
            
                    handler.removeCallbacks(runnable);
                }
                break;
                default:
                    break;
        }
    }
}

Android——币种转换App

图片[914] - Android原生开发基础 - 宋马
图片[915] - Android原生开发基础 - 宋马
图片[916] - Android原生开发基础 - 宋马


空框架 不需要兼容

布局

图片[917] - Android原生开发基础 - 宋马
spinner 下拉列表
图片[918] - Android原生开发基础 - 宋马
图片[919] - Android原生开发基础 - 宋马图片[919] - Android原生开发基础 - 宋马图片[919] - Android原生开发基础 - 宋马

版本管理
图片[920] - Android原生开发基础 - 宋马图片[920] - Android原生开发基础 - 宋马图片[920] - Android原生开发基础 - 宋马图片[920] - Android原生开发基础 - 宋马图片[920] - Android原生开发基础 - 宋马
图片[921] - Android原生开发基础 - 宋马

Json 数据解析

splash 欢迎页面
图片[922] - Android原生开发基础 - 宋马图片[922] - Android原生开发基础 - 宋马图片[922] - Android原生开发基础 - 宋马


splash 期间获取数据

图片[923] - Android原生开发基础 - 宋马图片[923] - Android原生开发基础 - 宋马图片[923] - Android原生开发基础 - 宋马
图片[924] - Android原生开发基础 - 宋马
图片[925] - Android原生开发基础 - 宋马

Android——上传截图相似度对比

引荐

相似图片搜索的原理

阮一峰 2011年7月21日发布的博客
Google “相似图片搜索”
根据Neal Krawetz博士的解释,原理非常简单易懂。
我们可以用一个快速算法,就达到基本的效果
“感知哈希算法”(Perceptual hash algorithm)
它的作用是对每张图片生成一个”指纹”(fingerprint)字符串,
然后比较不同图片的指纹。
结果越接近,就说明图片越相似。


最简单的实现:
第一步,缩小尺寸。
将图片缩小到8×8的尺寸,总共64个像素。
这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,
摒弃不同尺寸、比例带来的图片差异。

第二步,简化色彩。

将缩小后的图片,转为64级灰度。
也就是说,所有像素点总共只有64种颜色。

第三步,计算平均值。

计算所有64个像素的灰度平均值。

第四步,比较像素的灰度。

将每个像素的灰度,与平均值进行比较。
大于或等于平均值,记为1;小于平均值,记为0。

第五步,计算哈希值。

将上一步的比较结果,组合在一起,就构成了一个64位的整数,
这就是这张图片的指纹。
组合的次序并不重要,只要保证所有图片都采用同样次序就行了。

得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。


在理论上,这等同于计算”汉明距离”(Hamming distance)。
如果不相同的数据位不超过5,就说明两张图片很相似;
如果大于10,就说明这是两张不同的图片。

这种算法的优点是简单快速,不受图片大小缩放的影响,
缺点是图片的内容不能变更。
如果在图片上加几个文字,它就认不出来了。
所以,它的最佳用途是根据缩略图,找出原图。

实际应用中,往往采用更强大的pHash算法和SIFT算法,
它们能够识别图片的变形。
只要变形程度不超过25%,它们就能匹配原图。
这些算法虽然更复杂,但是原理与上面的简便算法是一样的,
就是先将图片转化成Hash字符串,然后再进行比较。

UPDATE(2013.03.31)


一、颜色分布法

每张图片都可以生成颜色分布的直方图(color histogram)。
如果两张图片的直方图很接近,就可以认为它们很相似。
图片[926] - Android原生开发基础 - 宋马
任何一种颜色都是由红绿蓝三原色(RGB)构成的,
所以上图共有4张直方图(三原色直方图 + 最后合成的直方图)。

如果每种原色都可以取256个值,那么整个颜色空间共有1600万种颜色(256的三次方)。

针对这1600万种颜色比较直方图,计算量实在太大了,因此需要采用简化方法。
可以将0~255分成四个区:
0~63为第0区,64~127为第1区,128~191为第2区,192~255为第3区。
这意味着红绿蓝分别有4个区,总共可以构成64种组合(4的3次方)。

任何一种颜色必然属于这64种组合中的一种,这样就可以统计每一种组合包含的像素数量。
图片[927] - Android原生开发基础 - 宋马
上图是某张图片的颜色分布表,将表中最后一栏提取出来,
组成一个64维向量(7414, 230, 0, 0, 8, …, 109, 0, 0, 3415, 53929)。
这个向量就是这张图片的特征值或者叫”指纹”。

于是,寻找相似图片就变成了找出与其最相似的向量。
这可以用皮尔逊相关系数或者余弦相似度算出。

二、内容特征法
除了颜色构成,还可以从比较图片内容的相似性入手。
首先,将原图转成一张较小的灰度图片,假定为50×50像素。
然后,确定一个阈值,将灰度图片转成黑白图片。
图片[928] - Android原生开发基础 - 宋马图片[928] - Android原生开发基础 - 宋马图片[928] - Android原生开发基础 - 宋马
如果两张图片很相似,它们的黑白轮廓应该是相近的。
于是,问题就变成了,第一步如何确定一个合理的阈值,正确呈现照片中的轮廓?

显然,前景色与背景色反差越大,轮廓就越明显。
这意味着,如果我们找到一个值,可以使得前景色和背景色各自的”类内差异最小”(minimizing the intra-class variance),或者”类间差异最大”(maximizing the inter-class variance),那么这个值就是理想的阈值。


1979年,日本学者大津展之证明了,“类内差异最小”与”类间差异最大”是同一件事,即对应同一个阈值。
他提出一种简单的算法,可以求出这个阈值,这被称为”大津法”(Otsu’s method)。

下面就是他的计算方法。

假定一张图片共有n个像素,其中灰度值小于阈值的像素为 n1 个,大于等于阈值的像素为 n2 个( n1 + n2 = n )。
w1 和 w2 表示这两种像素各自的比重。

w1 = n1 / n
w2 = n2 / n

再假定,所有灰度值小于阈值的像素的平均值和方差分别为 μ1 和 σ1,所有灰度值大于等于阈值的像素的平均值和方差分别为 μ2 和 σ2。于是,可以得到

类内差异 = w1(σ1的平方) + w2(σ2的平方)
类间差异 = w1w2(μ1-μ2)^2

可以证明,这两个式子是等价的:
得到”类内差异”的最小值,等同于得到”类间差异”的最大值。
不过,从计算难度看,后者的计算要容易一些。

下一步用”穷举法”,
将阈值从灰度的最低值到最高值,依次取一遍,分别代入上面的算式。
使得”类内差异最小”或”类间差异最大”的那个值,就是最终的阈值。
图片[929] - Android原生开发基础 - 宋马
有了50×50像素的黑白缩略图,就等于有了一个50×50的0-1矩阵。
矩阵的每个值对应原图的一个像素,0表示黑色,1表示白色。
这个矩阵就是一张图片的特征矩阵。
两个特征矩阵的不同之处越少,就代表两张图片越相似。
这可以用”异或运算”实现(即两个值之中只有一个为1,则运算结果为1,否则运算结果为0)。
对不同图片的特征矩阵进行”异或运算”,结果中的1越少,就是越相似的图片。


Android里的方法来实现

第一步,缩小尺寸。

 Bitmap bitmap8 = ThumbnailUtils.extractThumbnail(bitmapOriginal, 8, 8);

第二步,简化色彩。

  public static Bitmap convertGreyImg(Bitmap img) {
            
        int width = img.getWidth();         //获取位图的宽
        int height = img.getHeight();       //获取位图的高

        int[] pixels = new int[width * height]; //通过位图的大小创建像素点数组

        img.getPixels(pixels, 0, width, 0, 0, width, height);
        int alpha = 0xFF << 24;
        for (int i = 0; i < height; i++) {
            
            for (int j = 0; j < width; j++) {
            
                int original = pixels[width * i + j];
                int red = ((original & 0x00FF0000) >> 16);
                int green = ((original & 0x0000FF00) >> 8);
                int blue = (original & 0x000000FF);

                int grey = (int) ((float) red * 0.3 + (float) green * 0.59 + (float) blue * 0.11);
                grey = alpha | (grey << 16) | (grey << 8) | grey;
                pixels[width * i + j] = grey;
            }
        }
        Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        result.setPixels(pixels, 0, width, 0, 0, width, height);
        return result;
    }

第三步,计算平均值。

     public static int getAvg(Bitmap img) {
            
        int width = img.getWidth();
        int height = img.getHeight();
        int[] pixels = new int[width * height];
        img.getPixels(pixels, 0, width, 0, 0, width, height);

        int avgPixel = 0;
        for (int pixel : pixels) {
            
            avgPixel += pixel;
        }
        return avgPixel / pixels.length;
    }

第四步,比较像素的灰度。

 public static String getBinary(Bitmap img, int average) {
            
        StringBuilder sb = new StringBuilder();

        int width = img.getWidth();
        int height = img.getHeight();
        int[] pixels = new int[width * height];

        img.getPixels(pixels, 0, width, 0, 0, width, height);
        for (int i = 0; i < height; i++) {
            
            for (int j = 0; j < width; j++) {
            
                int original = pixels[width * i + j];
                if (original >= average) {
            
                    pixels[width * i + j] = 1;
                } else {
            
                    pixels[width * i + j] = 0;
                }
                sb.append(pixels[width * i + j]);
            }
        }
        return sb.toString();
    }

第五步,计算哈希值。
下面是得到16位16进制的字符串,作为该图片的消息指纹

  public static String binaryString2hexString(String bString) {
            
        if (bString == null || bString.equals("") || bString.length() % 8 != 0)
            return null;
        StringBuilder sb = new StringBuilder();
        int iTmp;
        for (int i = 0; i < bString.length(); i += 4) {
            
            iTmp = 0;
            for (int j = 0; j < 4; j++) {
            
                iTmp += Integer.parseInt(bString.substring(i + j, i + j + 1)) << (4 - j - 1);
            }
            sb.append(Integer.toHexString(iTmp));
        }
        return sb.toString
下面是两张图片的消息指纹比较的方法
  static void diff(String s1, String s2) {
            
        char[] s1s = s1.toCharArray();
        char[] s2s = s2.toCharArray();
        int diffNum = 0;
        for (int i = 0; i<s1s.length; i++) {
            
            if (s1s[i] != s2s[i]) {
            
                diffNum++;
            }
        }
        System.out.println("diffNum="+diffNum);
    }
 Str64->16=81000081e9ff0000  
Str64->16=01800049e1ff0000  
Str64->16=10000d41ebff8000  
Str64->16=fdff47e80020231b  
Str64->16=ffffcfb80028031b  
Str64->16=ffff4fee0408031b  
Str64->16=040c7104000e7fff  
Str64->16=0b1b999f0300052f  
Str64->16=0b1b99c101400527  

1、2、3行,4、5、6行,8、9行是大致同一个位置
(手持手机,尽量保持同一个位置),
第7行是其他位置,说明结果还是比较靠谱的,
个人认为diff(s1, s2)方法
结果在1 ~ 5说明两张照片极其相似,6 ~ 10说明较为相似,10以上说明不相似


可能的需求:

截自己的屏
截所有的屏
带导航栏截屏
不带导航栏截屏
截屏并编辑选取一部分
自动截取某个空间或者布局
截取长图
在后台去截屏

1.只截取自己应用内部界面

1.1 截取除了导航栏之外的屏幕

 View dView = getWindow().getDecorView();
dView.setDrawingCacheEnabled(true);
dView.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(dView.getDrawingCache());
if (bitmap != null) {
            
  try {
            
    // 获取内置SD卡路径
    String sdCardPath = Environment.getExternalStorageDirectory().getPath();
    // 图片文件路径
    String filePath = sdCardPath + File.separator + "screenshot.png";
    File file = new File(filePath);
    FileOutputStream os = new FileOutputStream(file);
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
    os.flush();
    os.close();
    DebugLog.d("a7888", "存储完成");
  } catch (Exception e) {
            
  }
}

1.2 截取某个控件或者区域

两种方案:

跟上面差不多,只不过view不适用根view,而是使用某个某个控件。

 View dView = title;
dView.setDrawingCacheEnabled(true);
dView.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(dView.getDrawingCache());

手动draw

View dView = titleTv;
Bitmap bitmap = Bitmap.createBitmap(dView.getWidth(), dView.getHeight(), Bitmap.Config.ARGB_8888);
//使用Canvas,调用自定义view控件的onDraw方法,绘制图片
Canvas canvas = new Canvas(bitmap);
dView.draw(canvas); 

1.3 截取带导航栏的整个屏幕

​ 这一小节会将一些理论上可以,但是实践会特别复杂,不太推荐使用。
可以学习了解。

adb 命令

这里指的不是连接电脑进行adb操控,而是在App内部实现adb命令的操控

在APK中调用“adb shell screencap -pfilepath” 命令

该命令读取系统的framebuffer,需要获得系统权限:

(1). 在AndroidManifest.xml文件中添加

 <uses-permissionandroid:name="android.permission.READ_FRAME_BUFFER"/>

2). 修改APK为系统权限,将APK放到源码中编译, 修改Android.mk

 LOCAL_CERTIFICATE := platform
publicvoid takeScreenShot(){
             
  String mSavedPath = Environment.getExternalStorageDirectory()+File. separator + "screenshot.png" ; 
try {
                       
      Runtime. getRuntime().exec("screencap -p " + mSavedPath); 
  } catch (Exception e) {
             
      e.printStackTrace(); 
  }

利用系统的隐藏API,实现Screenshot,这部分代码是系统隐藏的,需要在源码下编译。

1).修改Android.mk, 添加系统权限

 LOCAL_CERTIFICATE := platform

2).修改AndroidManifest.xml 文件,添加权限

 <uses-permissionandroid:name="android.permission.READ_FRAME_BUFFER"/>
 public boolean takeScreenShot(String imagePath){
            
       if(imagePath.equals("" )){
            
           imagePath = Environment.getExternalStorageDirectory()+File. separator+"Screenshot.png" ;
       }
            
     Bitmap mScreenBitmap;
     WindowManager mWindowManager;
     DisplayMetrics mDisplayMetrics;
     Display mDisplay;
          
     mWindowManager = (WindowManager) mcontext.getSystemService(Context.WINDOW_SERVICE);
     mDisplay = mWindowManager.getDefaultDisplay();
     mDisplayMetrics = new DisplayMetrics();
     mDisplay.getRealMetrics(mDisplayMetrics);
                  
     float[] dims = {
            mDisplayMetrics.widthPixels , mDisplayMetrics.heightPixels };
     mScreenBitmap = Surface. screenshot((int) dims[0], ( int) dims[1]);
            
     if (mScreenBitmap == null) {
             
         return false ;
     }
          
    try {
            
     FileOutputStream out = new FileOutputStream(imagePath);
     mScreenBitmap.compress(Bitmap.CompressFormat. PNG, 100, out);
        
    } catch (Exception e) {
            
         
         
     return false ;
    }    
               
    return true ;
}

Android本地编程(Native Programming)读取framebuffer

命令行,框架的截屏功能是通过framebuffer来实现的,
所以我们先来介绍一下framebuffer。

framebuffer介绍

帧缓冲(framebuffer)是Linux为显示设备提供的一个接口,
把显存抽象后的一种设备,
他允许上层应用程序在图形模式下直接对显示缓冲区进行 读写操作。
这种操作是抽象的,统一的。
用户不必关心物理显存的位置、换页机制等等具体细节。
这些都是由Framebuffer设备驱动来完成的。

linux FrameBuffer 本质上只是提供了对图形设备的硬件抽象,
在开发者看来,
FrameBuffer 是一块显示缓存,
往显示缓存中写入特定格式的数据就意味着向屏幕输出内容。
所以说FrameBuffer就是一块白板。
例如对于初始化为16 位色的FrameBuffer 来说,
FrameBuffer中的两个字节代表屏幕上一个点,从上到下,从左至右,
屏幕位置与内存地址是顺序的线性关系。

帧缓存有个地址,是在内存里。
我们通过不停的向frame buffer中写入数据,
显示控制器就自动的从frame buffer中取数据并显示出来。
全部的图形都共享内存中同一个帧缓存。

android截屏实现思路

Android系统是基于Linux内核的,所以也存在framebuffer这个设备,
我们要实现截屏的话只要能获取到framebuffer中的数据,
然后把数据转换成图片就可以了,
android中的framebuffer数据是存放在 /dev/graphics/fb0 文件中的,
所以我们只需要来获取这个文件的数据就可以得到当前屏幕的内容。

现在我们的测试代码运行时候是通过RC(remote controller)方式来运行被测应用的,
那就需要在PC机上来访问模拟器或者真机上的framebuffer数据,
这个的话可以通过android的ADB命令来实现。

各大手机自带的按键组合进行截屏

Android源码中对按键的捕获位于文件PhoneWindowManager.java(alpsframeworksasepolicysrccomandroidinternalpolicyimpl)中,
这个类处理所有的键盘输入事件,
其中函数interceptKeyBeforeQueueing()会对常用的按键做特殊处理。

截取非含当前应用的屏幕部分(最佳官方方案)

​ Android 在5.0 之后支持了实时录屏的功能。
通过实时录屏我们可以拿到截屏的图像。
同时可以通过在Service中处理实现后台的录屏。
具体的类讲解大家自行网上查阅。

大体步骤:

1.初始化一个MediaProjectionManager。

 MediaProjectionManager mMediaProjectionManager = 
 (MediaProjectionManager)getApplication().getSystemService(Context.MEDIA_PROJECTION_SERVICE);

2.创建intent,并启动Intent。注意这里是startActivityForResult

 
startActivityForResult(mMediaProjectionManager.createScreenCaptureIntent(), 
REQUEST_MEDIA_PROJECTION);

3.在onActivityResult中拿到Mediaprojection。

 mResultCode = resultCode;
mResultData = data;
mMediaProjection = mMediaProjectionManager.getMediaProjection(mResultCode, mResultData);

4.设置VirtualDisplay 将图像和展示的View关联起来。
一般来说我们会将图像展示到SurfaceView,
这里为了为了便于拿到截图,我们使用ImageReader,他内置有SurfaceView。

 mImageReader = ImageReader.newInstance(windowWidth, windowHeight, 0x1, 2); //ImageFormat.RGB_565
mVirtualDisplay = mMediaProjection.createVirtualDisplay("screen-mirror",
        windowWidth, windowHeight, mScreenDensity,       DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
        mImageReader.getSurface(), null, null);

5.通过ImageReader拿到截图

 strDate = dateFormat.format(new java.util.Date());
nameImage = pathImage+strDate+".png";
 
Image image = mImageReader.acquireLatestImage();
int width = image.getWidth();
int height = image.getHeight();
final Image.Plane[] planes = image.getPlanes();
final ByteBuffer buffer = planes[0].getBuffer();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * width;
Bitmap bitmap = Bitmap.createBitmap(width+rowPadding/pixelStride, height, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
bitmap = Bitmap.createBitmap(bitmap, 0, 0,width, height);
image.close();

6.注意截屏之后要及时关闭VirtualDisplay ,
因为VirtualDisplay 是十分消耗内存和电量的。

if (mVirtualDisplay == null) {
            
      return;
}
mVirtualDisplay.release();
mVirtualDisplay = null;

ps: 具体可以参考Google官方给的demo以及其他开发者写的Demo

https://github.com/googlesamples/android-ScreenCapture
https://github.com/VincentWYJ/CaptureScreen


截取长屏

​ 截取长屏其实原理就是截取整个ScrollView或者ListView的视图,
因此实现原理跟上面中提到的截取某个控件的View基本一致。

ScrollView 实现截屏

 /**
 * 截取scrollview的屏幕
 * **/
public static Bitmap getScrollViewBitmap(ScrollView scrollView) {
            
  int h = 0;
  Bitmap bitmap;
  for (int i = 0; i < scrollView.getChildCount(); i++) {
            
    h += scrollView.getChildAt(i).getHeight();
  }
  // 创建对应大小的bitmap
  bitmap = Bitmap.createBitmap(scrollView.getWidth(), h,
      Bitmap.Config.ARGB_8888);
  final Canvas canvas = new Canvas(bitmap);
  scrollView.draw(canvas);
  return bitmap;
}

ListView实现截屏

 /**
  * 截图listview
  * **/
 public static Bitmap getListViewBitmap(ListView listView,String picpath) {
            
   int h = 0;
   Bitmap bitmap;
   // 获取listView实际高度
   for (int i = 0; i < listView.getChildCount(); i++) {
            
     h += listView.getChildAt(i).getHeight();
   }
   Log.d(TAG, "实际高度:" + h);
   Log.d(TAG, "list 高度:" + listView.getHeight());
   // 创建对应大小的bitmap
   bitmap = Bitmap.createBitmap(listView.getWidth(), h,
       Bitmap.Config.ARGB_8888);
   final Canvas canvas = new Canvas(bitmap);
   listView.draw(canvas);
   return bitmap;
 }

WebView实现截屏

 //这是webview的,利用了webview的api
private static Bitmap captureWebView(WebView webView) {
            
    Picture snapShot = webView.capturePicture();
    Bitmap bmp = Bitmap.createBitmap(snapShot.getWidth(),
        snapShot.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bmp);
    snapShot.draw(canvas);
    return bmp;
  }

有时候我们可能需要去滚动屏幕,然后再滚动到某一个地方时停止截屏,
这样就会去截取从开始到滚动结束位置的view,而不是整个ScrollView,
这个时候就需要进行一些控制,具体原理跟上面讲的差不多,
可以参考一下下面的实现:

https://androidnotes.github.io/2016/12/03/android%E9%95%BF%E6%88%AA%E5%B1%8F%E5%8E%9F%E7%90%86/

实时截屏

​ 可参考2中Android 在5.0的做法,进行实时录制。

Android——登陆逻辑实现

MD5算法 Message-Digest Algorithm 5(信息–摘要算法)
Message
Digest
MessageDigest
MessageDigest.getInstance( );
由于注册登录涉及密码,我们需要对用户的密码进行 MD5 算法加密,
MD5 算法是把任意长度的字符串变成固定长度(通常是128位)的16进制字符串,
且此算法不可逆。
具体代码如下:

当点击登录按钮时,需判断用户名和密码是否为空。

若为空,则提示请输入用户名或密码,
若不为空,则获取用户输入的用户名,
由于用的是本地数据,需要根据用户名在 SharedPreferences 中查询是否有对应的密码,
若有对应的密码且与用户输入的密码(需通过 MD5 加密)比对一致情况,则登录成功

点击登录,查询服务器数据库,匹配则登录,
进入一个新页面显示登录信息,不匹配则显示登录失败。

结构设计

Android 用于与用户交互,信息的输入与显示。
阿里云服务器,Tomcat Web应用服务器
使用原生Servlet完成APP与服务器的交互。
MySql数据库 用于数据的存储与匹配。
图片[930] - Android原生开发基础 - 宋马
数据库的操作,使用的是DBUtils框架

1、 给app分配网络访问的权限
2、 启动页面(LoginActivity)为登录页面
3、 Helloword页面(MainActivity)为登录成功的跳转页面
4、 输入的账号密码正确则跳转,否则不跳转
5、 使用Intent实现页面的跳转
6、 使用httpclient发送登录的异步请求
7、 AndroidManifest配置文件里面添加登录页面的activity
8、 开发登录接口,对app客户端发送的登录请求进行处理

添加httpclient框架和fastjson框架的依赖


SQLite 是一个开源的嵌入式关系数据库,它可以减少应用程序管理数据的开销 ,
SQLite 可移植性好 、 很容易使用 、 很小 、 高效而且可靠 。
目前在Android 系统中集成的是 SQLite3 版本 ,
SQLite 不支持静态数据类型 , 而是使用列关系 。
这意味着它的数据类型不具有表列属性 , 而具有数据本身的属性 。
当某个值插入数据库时, SQLite 将检查它的类型。
如果该类型与关联的列不匹配,则 SQLite 会尝试将该值转换成列类型。
如果不能转换,则该值将作为其本身具有的类型存储。
SQLite 支持 NULL 、INTEGER 、 REAL 、 TEXT 和 BLOB 数据类型。例如:可以在 Integer 字段中存放字符串,
或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值。但是有一种例外,
如果你的主键是 INTEGER ,那么只能存储 6 4位整数 ,
当向这种字段中保存除整数以外的数据时, 将会产生错误 。
另外 ,
SQLite 在解 析REATE TABLE语句时,
会忽略 CREATE TABLE 语句中跟在字段名后面的数据类型信息。


SQLite 的特点

SQlite数据库总结起来有五大特点:

零配置

SQlite3不用安装、不用配置、不用启动、关闭或者配置数据库实例。
当系统崩溃后不用做任何恢复操作,在下次使用数据库的时候自动恢复。

可移植

它是运行在 Windows 、 Linux 、BSD 、 Mac OS X 和一些商用 Unix 系统, 比如 Sun 的 Solaris 、IBM 的 AIX ,同样,它也可以工作在许多嵌入式操作系统下,比如 Android 、 QNX 、VxWorks、 Palm OS 、 Symbin 和 Windows CE 。

紧凑

SQLite是被设计成轻量级、自包含的。一个头文件、一个 lib 库,你就可以使用关系数据库了,不用任何启动任何系统进程。

简单

SQLite有着简单易用的 API 接口。

可靠

SQLite的源码达到 100% 分支测试覆盖率。


Android 提供的 SQLiteOpenHelper.java 是一个抽象类。
那么我们要使用它,必须自己写一个类来继承它

 public class DatabaseHelper extends SQLiteOpenHelper{
            

接下来需要写一个
带全部参数的DatabaseHelper类的构造函数,
以后生成数据库对象的时候要用到:

 static String name="user.db";  
    static int dbVersion=1;
 //带全部参数的构造函数,此构造函数必不可少
    public DatabaseHelper(Context context, String name, CursorFactory factory, int version) {
            
        super(context, name, factory, version);
    } 

为了实现对数据库版本进行管理, SQLiteOpenHelper 类提供了两个重要的方法
分别onCreate(SQLiteDatabasedb) 和
onUpgrade(SQLiteDatabase db, int oldVersion, intnewVersion)
用于初次使用软件时生成数据库表,
后者用于升级软件时更新数据库表结构。


 //只在创建的时候用一次   
    public void onCreate(SQLiteDatabase db) {
              
        String sql="create table user(id integer primary key autoincrement,username varchar(20),password varchar(20),age integer,sex varchar(2))";  
        db.execSQL(sql);  
    }  
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
              
  
    }  

SQLiteDatabase.execSQL(String sql) 可以用来执行非查询 SQL 指令,这些指令没有结果
包括: CREATE TABLE / DROP TABLE / INSERT 等等
图片[931] - Android原生开发基础 - 宋马

Android——登陆后台数据接口交互IDEA

客户端与服务器端的通信

图片[932] - Android原生开发基础 - 宋马
数据库 mysql,
新建一个数据库
创建一个表
里面的字段就4个

接下来我们开发WebService 服务工程

打开eclipse
新建一个web工程
图片[933] - Android原生开发基础 - 宋马图片[933] - Android原生开发基础 - 宋马
图片[934] - Android原生开发基础 - 宋马

 A82DEE284F-eyJsaWNlbnNlSWQiOiJBODJERUUyODRGIiwibGljZW5zZWVOYW1lIjoiaHR0cHM6Ly96aGlsZS5pbyIsImFzc2lnbmVlTmFtZSI6IiIsImFzc2lnbmVlRW1haWwiOiIiLCJsaWNlbnNlUmVzdHJpY3Rpb24iOiJVbmxpbWl0ZWQgbGljZW5zZSB0aWxsIGVuZCBvZiB0aGUgY2VudHVyeS4iLCJjaGVja0NvbmN1cnJlbnRVc2UiOmZhbHNlLCJwcm9kdWN0cyI6W3siY29kZSI6IklJIiwicGFpZFVwVG8iOiIyMDg5LTA3LTA3In0seyJjb2RlIjoiUlMwIiwicGFpZFVwVG8iOiIyMDg5LTA3LTA3In0seyJjb2RlIjoiV1MiLCJwYWlkVXBUbyI6IjIwODktMDctMDcifSx7ImNvZGUiOiJSRCIsInBhaWRVcFRvIjoiMjA4OS0wNy0wNyJ9LHsiY29kZSI6IlJDIiwicGFpZFVwVG8iOiIyMDg5LTA3LTA3In0seyJjb2RlIjoiREMiLCJwYWlkVXBUbyI6IjIwODktMDctMDcifSx7ImNvZGUiOiJEQiIsInBhaWRVcFRvIjoiMjA4OS0wNy0wNyJ9LHsiY29kZSI6IlJNIiwicGFpZFVwVG8iOiIyMDg5LTA3LTA3In0seyJjb2RlIjoiRE0iLCJwYWlkVXBUbyI6IjIwODktMDctMDcifSx7ImNvZGUiOiJBQyIsInBhaWRVcFRvIjoiMjA4OS0wNy0wNyJ9LHsiY29kZSI6IkRQTiIsInBhaWRVcFRvIjoiMjA4OS0wNy0wNyJ9LHsiY29kZSI6IkdPIiwicGFpZFVwVG8iOiIyMDg5LTA3LTA3In0seyJjb2RlIjoiUFMiLCJwYWlkVXBUbyI6IjIwODktMDctMDcifSx7ImNvZGUiOiJDTCIsInBhaWRVcFRvIjoiMjA4OS0wNy0wNyJ9LHsiY29kZSI6IlBDIiwicGFpZFVwVG8iOiIyMDg5LTA3LTA3In0seyJjb2RlIjoiUlNVIiwicGFpZFVwVG8iOiIyMDg5LTA3LTA3In1dLCJoYXNoIjoiODkwNzA3MC8wIiwiZ3JhY2VQZXJpb2REYXlzIjowLCJhdXRvUHJvbG9uZ2F0ZWQiOmZhbHNlLCJpc0F1dG9Qcm9sb25nYXRlZCI6ZmFsc2V9-5epo90Xs7KIIBb8ckoxnB/AZQ8Ev7rFrNqwFhBAsQYsQyhvqf1FcYdmlecFWJBHSWZU9b41kvsN4bwAHT5PiznOTmfvGv1MuOzMO0VOXZlc+edepemgpt+t3GUHvfGtzWFYeKeyCk+CLA9BqUzHRTgl2uBoIMNqh5izlDmejIwUHLl39QOyzHiTYNehnVN7GW5+QUeimTr/koVUgK8xofu59Tv8rcdiwIXwTo71LcU2z2P+T3R81fwKkt34evy7kRch4NIQUQUno//Pl3V0rInm3B2oFq9YBygPUdBUbdH/KHROyohZRD8SaZJO6kUT0BNvtDPKF4mCT1saWM38jkw==-MIIElTCCAn2gAwIBAgIBCTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTE4MTEwMTEyMjk0NloXDTIwMTEwMjEyMjk0NlowaDELMAkGA1UEBhMCQ1oxDjAMBgNVBAgMBU51c2xlMQ8wDQYDVQQHDAZQcmFndWUxGTAXBgNVBAoMEEpldEJyYWlucyBzLnIuby4xHTAbBgNVBAMMFHByb2QzeS1mcm9tLTIwMTgxMTAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5ndaik1GD0nyTdqkZgURQZGW+RGxCdBITPXIwpjhhaD0SXGa4XSZBEBoiPdY6XV6pOfUJeyfi9dXsY4MmT0D+sKoST3rSw96xaf9FXPvOjn4prMTdj3Ji3CyQrGWeQU2nzYqFrp1QYNLAbaViHRKuJrYHI6GCvqCbJe0LQ8qqUiVMA9wG/PQwScpNmTF9Kp2Iej+Z5OUxF33zzm+vg/nYV31HLF7fJUAplI/1nM+ZG8K+AXWgYKChtknl3sW9PCQa3a3imPL9GVToUNxc0wcuTil8mqveWcSQCHYxsIaUajWLpFzoO2AhK4mfYBSStAqEjoXRTuj17mo8Q6M2SHOcwIDAQABo4GZMIGWMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGEpG9oZGcfLMGNBkY7SgHiMGgTcMEgGA1UdIwRBMD+AFKOetkhnQhI2Qb1t4Lm0oFKLl/GzoRykGjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBggkA0myxg7KDeeEwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQBonMu8oa3vmNAa4RQP8gPGlX3SQaA3WCRUAj6Zrlk8AesKV1YSkh5D2l+yUk6njysgzfr1bIR5xF8eup5xXc4/G7NtVYRSMvrd6rfQcHOyK5UFJLm+8utmyMIDrZOzLQuTsT8NxFpbCVCfV5wNRu4rChrCuArYVGaKbmp9ymkw1PU6+HoO5i2wU3ikTmRv8IRjrlSStyNzXpnPTwt7bja19ousk56r40SmlmC04GdDHErr0ei2UbjUua5kw71Qn9g02tL9fERI2sSRjQrvPbn9INwRWl5+k05mlKekbtbu2ev2woJFZK4WEXAd/GaAdeZZdumv8T2idDFL7cAirJwcrbfpawPeXr52oKTPnXfi0l5+g9Gnt/wfiXCrPElX6ycTR6iL3GC2VR4jTz6YatT4Ntz59/THOT7NJQhr6AyLkhhJCdkzE2cob/KouVp4ivV7Q3Fc6HX7eepHAAF/DpxwgOrg9smX6coXLgfp0b1RU2u/tUNID04rpNxTMueTtrT8WSskqvaJd3RH8r7cnRj6Y2hltkja82HlpDURDxDTRvv+krbwMr26SB/40BjpMUrDRCeKuiBahC0DCoU/4+ze1l94wVUhdkCfL0GpJrMSCDEK+XEurU18Hb7WT+ThXbkdl6VpFdHsRvqAnhR2g4b+Qzgidmuky5NUZVfEaZqV/g==

链接: https://pan.baidu.com/s/10ZmKSNQUbaRRIocCzPYwyA

提取码: ykdt

解决 一个 恶心人的难题

检查配置Maven

下载Maven
官方地址:http://maven.apache.org/download.cgi
图片[935] - Android原生开发基础 - 宋马

2.配置本地仓库路径

图片[936] - Android原生开发基础 - 宋马
图片[937] - Android原生开发基础 - 宋马
图片[938] - Android原生开发基础 - 宋马

新建maven WEB项目

maven web模板项目结构

新建

图片[939] - Android原生开发基础 - 宋马图片[939] - Android原生开发基础 - 宋马图片[939] - Android原生开发基础 - 宋马
图片[940] - Android原生开发基础 - 宋马
jar包配置搜索
官方地址:http://mvnrepository.com/
图片[941] - Android原生开发基础 - 宋马

创建Servlet工程
图片[942] - Android原生开发基础 - 宋马
图片[943] - Android原生开发基础 - 宋马
图片[944] - Android原生开发基础 - 宋马
图片[945] - Android原生开发基础 - 宋马
图片[946] - Android原生开发基础 - 宋马
图片[947] - Android原生开发基础 - 宋马

Android——登陆界面xml实现

布局文件—xml实现用户登录界面

注:
所建工程均为Android 6.0 所以只要是Android 6.0(包括6.0)
以上的真机,模拟机都可以使用

Step1:Android Studio 开发环境的搭建:
1.安装JDK (1.8);
图片[948] - Android原生开发基础 - 宋马
2.安装Android studio (3.3.1) 包含 gradle、sdk manage 、avd manage ;
3.使用sdk manage 下载安装 sdk;
4.使用avd manages 创建虚拟机

Step2: 新建工程项目

1.在res/layout/activity_main.xml中编写布局内容:

在drawable中添加shape.xml实现美化效果
shape.xml代码

 
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#800066ff" />
    <corners android:radius="10dp" />
</shape> 

背景图保存到drawable中

添加 背景和button
图片[949] - Android原生开发基础 - 宋马
更改 button 初始样式

 <Button
        android:id="@+id/button4"
        android:layout_width="280dp"
        android:layout_height="32dp"
        android:layout_marginEnd="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="248dp"
        android:background="@drawable/shape"
        android:text="登陆"
        android:textColor="#ffffff"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" /> 

自己调整 和搭配好设计布局
添加两个 edittext

<EditText
        android:id="@+id/editText"
        android:layout_width="280dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="16dp"
        android:ems="10"
        android:hint="xxxx"
        android:textColorHint="#ffffff"
        android:inputType="textPassword"
        android:textColor="#ffffff"
        android:selectAllOnFocus="false"
        android:singleLine="false"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editText3" />
 
    <EditText
        android:id="@+id/editText3"
        android:layout_width="280dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="130dp"
        android:ems="10"
        android:hint="xxxx"
        android:textColorHint="#ffffff"
        android:textColor="#ffffff"
        android:inputType="textPersonName"
        android:textSize="18sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.503"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
 

简单说明 自己搭配即可

去掉项目中页面顶部的项目名

处理方法:
将styls.xml里的

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容