Android
2022-03-26 21:03:28 1 举报
AI智能生成
安卓开发常用的一些功能
作者其他创作
大纲/内容
控件
TextView 视图控件
阴影
shadowColor="#00000000" 设置字体阴影颜色
shadowRadius="0" 设置阴影模糊度
shadowDx="0" 水平移动
shadowDy="0" 垂直移动
singleLine="true" 内容单行显示
focusable="true" 是否可以获取焦点
focusableInTouchMode="true" 控制在触摸模式下是否可以聚焦
ellipsize="" 控制省略位置
marqueeRepeatLimit="" 字幕动画重复次数
clickable="true" 是否能点击单击
requestFocus 请求焦点
Button 按钮控件
backgroundTint="@" 按钮图片背景颜色选择器
foreground="@" 设置前景色,会把一切背景覆盖
EditText 输入框
textColorHint="" 设置默认文本颜色
drawableTop/Bottom/Left/Right="" 上/下/左/右侧插入图片
drawableStart/End="" 左/右侧插入图片(SDK>=API 17最好使用)
drawablePadding="" 设置图片和内容的间隔
lines="" 最大显示行数
ImageView 图片
scaleType="" 图片显示样式
maxHeight="" 最大高度
maxWidth="" 最大宽度
adjustViewBounds="true" 是否可以改变图片大小
app:tint="" 前景色
ProgressBar 进度条
visibility="gone" 不可见
visibility="visible" 可见
max="" 进度条最大值
progress="" 进度条默认进度
style=""
?android:attr/progressBarStyleHorizontal 进度条样式[水平进度条]
?android:attr/progressBarStyleSmall 小圆圈
?android:attr/progressBarStyleStyleLarge 大圆圈
@android:style/Widget.ProgressBar.Horizontal 粗进度条
@android:style/Widget.ProgressBar.Small 粗小圆圈
@android:style/Widget.ProgressBar.Large 粗大圆圈
indeterminate="true" 不显示精确进度
Toolbar 自定义标题
titleTextColor="" 设置标题文字颜色
subtitleTextColor="" 设置子标题文字颜色
title="" 设置标题内容
subtitle="" 设置子标题内容
logo="" 设置logo
navigationIcon="" 设置按钮图片
titleMarginStart="" 间隔左边多远
RelativeLayout 相对布局
divider="" 分割线
showdivider="" 显示分割线
dividerpadding="" 分割线内边距
layout_weight="" 权重
只有一个设置,占据剩下的全部空间
多个按照n:n的比例来分配
相对父级对齐
layout_centerVertical="true" 垂直居中
layout_centerInParent="" C位
layout_centerHorizontal="true" 水平居中
layout_alignParentTop/Bottom/Left/Right="true" 上下左右对齐
layout_marginTop/Bottom/Left/Right="偏移大小" 上/下/左/右偏移
layout_margin="偏移量" 上下左右同时偏移
相对同级对齐
layout_toLeftOf/Right="同级id" 靠左/右
layout_below="同级id" 靠底部
layout_above="同级id" 靠顶部
layout_alignTop/Bottom/Left/Right="同级id" 上/下/左/右对齐
相对子极对齐
padding="偏移量" 同时偏移上下左右
paddingTop/Bottom/Left/Right="偏移量" 上/下/左/右偏移
FrameLayout 帧布局
foreground="" 设置前景
foregroundGravity="" 设置前景位置
TableLayout 表格布局每个元素独占一行
TableRow标签 让控件在一行
collapseColumns="" 需要隐藏的列序号
stretchColumns="" 需要拉伸列序号
android:shrinkColumns="" 需要收缩的列序号
layout_column="" 控件在第几列显示
layout_span= "" 该列横跨多少列
GridLayout 网格表格布局
row/columnCount="" 最大行/列数
layout_row/column="" 位于第几行/列
layout_row/columnWeight="" 行/列权重
layout_row/columnSpan="" 跨几行/列
需要配合 layout_gravity="fill"
ConstraintLayout 约束布局
直接点击控件拖动即可
ListView 列表视图
entries="list资源"
list资源 在value文件夹中创建
<resources>
<string-array name="资源名">
<item>标题</item>
</string-array>
</resources>
<string-array name="资源名">
<item>标题</item>
</string-array>
</resources>
ImageButton 图片按钮
RadioButton 单选按钮
checked="true" 默认选中
RadioGroup 分组标签
CheckBox 复选按钮
DatePicker 日期选择器
TimePicker 时间选择器
Chronometer 计时器
format="%s" 时间显示格式
SeekBar 拖动条
thumb="" 设置拖动点图片
RatingBar 星星选择器
numStart="" 星星的数量
rating="" 点亮的星星个数
stepSize="" 点亮的大小
isIndicator="true" 星星数量是否能改变
GridView
android:numColumns="4" 一行显示几列
Spinner 下拉列表
entries 设置列表内容
HorizontalScrollView 水平滚动窗口
ScrollView 垂直滚动窗口
TabHost 选项卡
TabWidget 选项卡部件
android:id="@android:id/tabs" 标签id
android:id="@android:id/tabcontent" 内容id
打开方式
<action android:name="android.intent.action.VIEW"/> 视图
<category android:name="android.intent.category.DEFAULT"/> 默认打开
include 导入其他布局
layout="布局文件位置"
布局标签
<style name="布局名" parent="继承于">
<item name="类型"></item>
</style>
<item name="类型"></item>
</style>
样式布局
<style name="样式名" parent="继承于">
<item name="类型"></item>
</style>
<item name="类型"></item>
</style>
使用样式 style="@style/样式名"
菜单资源文件
在menu目录下创建
<item id="id" title="标题"></item>
Java控制
getLayoutInflater().inflate(R.layout.test_view, null); 获得视图对象
TextView继承这个方法的类
重写isFocused()返回true则获取焦点
Toolbar事件
toolbar.setNavigationOnClickListener(new View.OnClickListener()); 点击事件
toolbar.setOnTouchListener(new View.OnTouchListener()); 移动事件
PopupWindow 窗口
new PopupWindow(view1, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
创建PopupWindow对象
创建PopupWindow对象
true 可关闭
false 不可关闭
popupWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.qhsn)); 设置窗口图片
popupWindow.showAsDropDown(view); 显示窗口
popupWindow.dismiss(); 关闭窗口
ListView 列表视图
setOnItemClickListener(new AdapterView.OnItemClickListener()) 单击事件
setOnItemLongListener(new AdapterView.OnItemClickListener()) 长按事件
Toast.makeText(this, "单击", Toast.LENGTH_LONG); 弹出提示文字
单选按钮
getChildAt(index); 获取单选按钮组中的单选按钮
isChecked(void); 判断单选按钮是否被选中
setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()); 选中事件
日期选择器
datePicker.init(year, month, day, OnDateChangedListener); 初始化
new OnDateChangedListener(); 选中事件
时间选择器
tp.setIs24HourView(true); 是否设置为24小时制
计时器
chronometer.setBase() 设置时间的起始位置
SystemClock.elapsedRealtime() 返回自启动软件以来的毫秒数
chronometer.start(); 开始计时
chronometer.stop(); 停止计时
chronometer.setOnChronometerTickListener() 计时器监听
getBase() 获取基准后的时间
进度条
Message消息对象
message.what = 0x111; 设置消息变量
handler.sendMessage(message); 加入消息处理
Handler handler = new Handler(){} 消息处理对象
handleMessage(msg) 重写这个方法[开始处理消息]
拖动条
seekBar.setOnSeekBarChangeListener(); 设置监听事件
ImageSwitcher
imageSwitcher.setFactory() 生成视图工厂
imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(MainActivity.this, android.R.anim.fade_out)); 弹出动画
imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(MainActivity.this, android.R.anim.fade_in)); 进入动画
imageSwitcher.setImageResource() 设置新图片
event.getAction() 获取触摸类型
设置下拉列表
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 设置下拉列表视图资源
getItemAtPosition(position)/getSelectedItem() 获取下拉列表选中项
setOnItemSelectedListener() 选择监听器
适配器
SimpleAdapter(上下文对象, list, 资源地址,Key, Value); 简单适配器
BaseAdapter继承此类实现|直接new 基本适配器
ArrayAdapter 数组适配器
setAdapter() 设置适配器
选项卡
LayoutInflater inflater = LayoutInflater.from(this); 获取对象
tabHost.setup(); 设置TabHost
inflater.inflate(R.layout.t1, tabHost.getTabContentView()); 展开新的视图
tabHost.addTab(tabHost.newTabSpec("t1").setIndicator("精选图片").setContent(R.id.t1)); 添加选项卡
Activity之间跳转
setContentView(R.layout.test); 设置关联布局
startActivityForResult(intent, requestCode); 开始跳转,携带请求值,可返回值
setResult(123, intent); 返回结果给请求的Activity
返回的结果在onActivityResult重写方法中
Bundle
bundle.get("key") 获得与key对应的value
bundle.put("key", value); 将数据以键值对的方式存储
Intent
new Intent(MainActivity.this,TestActivity.class); 指定从A跳转到B
this.getIntent() 获得传递过来的Intent对象
intent.getExtras() 获得Intent对象中的Bundle对象
intent.putExtras(bundle); 将Bundle对象放入Intent对象
intent.setComponent(componentName); 设置Component
intent.setAction(Intent常量); 跳转到XX界面
ACTION_SENDTO 跳转到信息界面
ACTION_DIAL 跳转到拨号界面
ACTION_MAIN 设置为主页面
ACTION_VIEW 显示视图
intent.setData(Uri.parse("目标")); 设置XX目标
smsto:目标邮箱 设置发送目标
tel:目标号码 拨打目标
http://目标网站 访问网站
intent.putExtra("sms_body", "内容"); 设置发送消息内容
intent.addCategory(Intent常量); 添加类别
CATEGORY_HOME 返回主界面
intent.setFlags(Intent常量); 设置标志
FLAG_ACTIVITY_NO_HISTORY 离开界面销毁栈数据
ComponentName
new ComponentName("当前包名", 目标完整类名); 从当前类跳转到目标类
物理按键常量
音量键
KEYCODE_VOLUME_UP 声音增大
KEYCODE_VOLUME_DWON 声音减小
电源键
KEYCODE_POWER
返回键
KEYCODE_BACK
主页键
KEYCODE_HOME
菜单键
KEYCODE_MENU
Service
startService(new Intent(MainActivity.this, MyService.class)); 启动service
stopService(new Intent(MainActivity.this, MyService.class)); 停止service
生命周期
onCreate 创建
onStartCommand/onBind 启动/绑定
onUnbind 解绑
onDestroy 销毁
外部框架
Glide 图片处理
new DrawableCrossFadeFactory.Builder(毫秒).setCrossFadeEnabled(true).build(); 动画结束,删除占位图
Grlide.with(this) 图片设置
.asBitmap() 设置为位图,默认Drawable
.load(url) 图片地址
.transition(BitmapTransitionOptions.withCrossFade(3000/factory)) 淡入时间
.transform() 图片样式
new CircleCrop() 圆形图片
new RoundedCorners(50) 圆角图片
new GranularRoundedCorners(300, 400, 500, 600) 自定义形状
new Rotate(90) 旋转角度
.apply(option) 使用配置对象
.into(imageView); 加载到该控件
new RequestOptions(). 请求配置
placeholder(R.drawable.place) 请求时
error(R.drawable.error) 请求错误时
fallback(R.drawable.fallback) 请求参数未null时
override(1000, 1000); 图片大小
Glide外部依赖
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
OKHttp
配置
依赖
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
因特网权限
<uses-permission android:name="android.permission.INTERNET"/>
需要在网络环境下才能正常运行
请求
Get同步
1)new Thread(()->{}).start(); 需要再子线程中操作
2) request = new Request 请求设置
2.1) .Builder() 建立请求对象
2.2).url("https://www.httpbin.org/get?name=zs&age=18") 设置要访问的地址/访问方式/参数
2.3).build(); 生成请求对象
3)call =okHttpClient.newCall(request); 获取Call对象
4)response = call.execute(); 获取响应对象
Get异步
1)请求设置 和同步一致
2) 获取Call对象 和同步一致
3)call.enqueue(() -> Unit); 产生异步
onFailure 通信失败
onResponse 通信成功
Post同步
1)需要在子线程中操作 和Get同步一样
2)formBody = new FormBody 表单设置
2.1).Builder() 建立表单
2.2).add(name, value) 添加元素
2.3).build(); 生成请求对象
3)request = new Request 请求设置
3.1).Builder() 建立请求对象
3.2).url("https://www.httpbin.org/post") post请求地址
3.3).post(formBody) 将请求改为post请求
3.4).build(); 生成请求对象
4)剩下和Get同步一样
Post异步
1)表单设置 请求设置 和POST同步一样
3)获取Call对象 产生异步 和Get同步一样
4) 和Get异步一样
Post提交文件
1)File file1 = new File("D:\\Desktop\\依赖.txt"); 选择要提交的文件
2)RequestBody file1Option = RequestBody.create(file1, MediaType.parse("text/plain")); 设置提交类型
3)MultipartBody body = new MultipartBody
3.1).Builder() 建立多部分体
3.2).addFormDataPart("file1", file1.getName(), file1Option) 添加文件
3.3).build(); 生成多部分体对象
4)剩下的和Post异步或同步一样
拦截器
new OkHttpClient.Builder().addInterceptor(chain->{}); 前置拦截器
.addNetworkInterceptor(chain -> {}); 后置拦截器
Request request = chain.request().newBuilder() 请求设置
.addHeader("os", "Android") 添加请求头元素
.build() 生成请求设置
Response response = chain.proceed(request); 进行拦截
Cookie
new OkHttpClient.Builder().cookieJar(new CookieJar(){}); 获取Cookie
saveFromResponse 服务器响应的Cookie
loadForRequest 向服务器发起请求的Cookie
Retrofit okHttp的封装版
注解
方法注解 决定方法的请求方式
@GET
@POST
@PUT
@DELETE
@PATH
@HEAD
@OPTIONS
@HTTP(method="GET" path="get") 自定义方式
标记注解
@FormUrlEncoded 以Form表单的方式提交POST请求的参数
@Multipart 上传文件时对方法的注解
@Streaming 以流的方式获取文件
参数注解
@Query 针对GET请求
@QueryMap 针对GET请求,可将参数定义为Map对象
@Field 针对POST请求
@FieldMap 针对POST请求,可将参数定义为Map对象
@Part 上传单个文件对参数的注解
@PartMap 允许文件上传为一个Map对象
@Body 可将参数指定为Body对象
其他注解
@Path 传递的值能修改方法注解中的值,如:
@POST("{id}")
Call<ResponseBody> post(@Path("id") String path);
@POST("{id}")
Call<ResponseBody> post(@Path("id") String path);
@Header 设置请求头
@Headers 写死多个请求头
@Url 指定一个完整的Http请求地址
接口定义
@GET
Call<RequestBody> get(@Query("user") String , @Query("pwd") String);
Call<RequestBody> get(@Query("user") String , @Query("pwd") String);
@POST
@FormUrlEncoded
Call<RequestBody> post(@Field("user") String, @Field("pwd") String);
@FormUrlEncoded
Call<RequestBody> post(@Field("user") String, @Field("pwd") String);
方法
retrofit.create(RetrofitService.class); 创建某个类
.baseUrl("https://www.httpbin.org/") 要访问的网址
.callFactory(new OkHttpClient()) 自定义一个OkHttp规则
Gson
序列化
@SerializedName("name") 序列化变量名采用该名
Json的key与Java的关键冲突时使用
Json的key与Java的关键冲突时使用
new Gson().toJson(class); 将Java对象序列化为Json对象
@Expose(serialize = false) 不参与序列化
反序列化
new Gson().fromJson(Json, 对应的Java对象/type); 将Json反序列化为Java对象
new TypeToken<List<User>>(){}.getType(); 识别集合中存储的对象
@Expose(deserialize = false) 不参与反序列化
序列化与反序列化
Java修饰符transient 不参加序列化与反序列化
@Expose(deserialize = false, serialize = false)
@Expose(deserialize = false, serialize = false)
new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create() 使@Expose注解生效
数据存储
SP
getSharedPreferences("name", Context.MODE_APPEND); 追加
getSharedPreferences("name", Context.MODE_PRIVATE); 默认
修改资源布局 setTheme(R.Style.样式名) 必须在初始化布局之前调用
菜单
选项菜单
在xml中创建菜单资源文件
重写onCreateOptionsMenu方法 指定资源文件MenuInflater(this).inflate(R.menu.menu, menu)
重写onOptionsItemSelected方法 在这里进行选中动作
上下文菜单
在xml中创建菜单资源文件
为控件注册上下文菜单 registerForContextMenu(findViewById())
重写onCreateContextMenu方法 指定资源文件MenuInflater(this).inflate(R.menu.menu, menu)
重写onContextItemSelected方法 在这里进行选中动作
ActionBar
添加和隐藏ActionBar
通过Java实现
getSupportActionBar().hide() 隐藏
getSupportActionBar().show() 显示
设置theme属性, 可以隐藏或显示ActionBar
getSupportActionBar.setDisplayShowTitleEnabled(false) 隐藏ActionBar的标题
ActionItem
在xml创建菜单资源文件的基础上加一个app:showAsAction属性
always 始终显示在ActionBar上
ifRoom 空间足够显示在ActionBar上
never 永远不显示在ActionBar上
withText 显示在ActionBar上,并显示文本
当app:showAsAction不管用时 在onCreateOptionsMenu之上额外加上
MenuItemCompat.setShowAsAction(menu?.findItem(需要展示的item的id),MenuItemCompat.SHOW_AS_ACTION_ALWAYS)
MenuItemCompat.setShowAsAction(menu?.findItem(需要展示的item的id),MenuItemCompat.SHOW_AS_ACTION_ALWAYS)
重写onCreateOptionsMenu方法
指定资源文件MenuInflater(this).inflate(R.menu.menu, menu)
指定资源文件MenuInflater(this).inflate(R.menu.menu, menu)
重写onOptionsItemSelected方法 在这里进行选中动作
Alertdialog 弹窗
new AlertDialog.Builder(this).create() 创建弹窗对象
.setButton(按钮类型, "按钮文字", (dialog, which) -> Unit) 设置按钮
Dialog.BUTTON_NEUTRAL 左边按钮
Dialog.BUTTON_NEGATIVE 中间按钮
Dialog.BUTTON_POSITIVE 右边按钮
new AlertDialog.Builder(this) 链式调用
.setNeutralButton("按钮文字", (dialog, which) -> Unit) 左边按钮
.setNegativeButton(...) 中间按钮
.setPositiveButton(...) 右边按钮
.setItems(资源数组, (dialog, which) -> Unit) 设置列表弹窗
.setSingleChoiceItems(资源数组, 默认选中, (dialog, which) -> Unit) 设置单选列表弹窗
.setMultiChoiceItems(资源数组, 布尔数组, (dialog, which, isChecked) -> Unit) 设置多选列表弹窗
.setIcon(图片地址) 弹窗图片
.setMessage("") 弹窗内容
.setView(inflate) 自定义布局
inflate = getLayoutInflater().inflate(R.layout.test_view, null); 布局的链接
.create() 构建
.show() 展示
发起通知
manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE) 获得系统服务
notification = new Notification.Builder(this) 创建通知对象 链式调用
.setSmallIcon(图片资源) 设置通知的小图标,必选
.setContentTitle("标题") 设置标题
.setContentText("内容") 设置内容
.setDefaults(Notification.DEFAULT_SOUND) 设置默认动作,如默认通知声音
.setContentIntent(pendingIntent) 点击消息跳转
intent = Intent(A.this, B.class) 从A跳跃到B
pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, intent, 0) 点击消息后获得目标Activity
.setWhen(long) 设置发送时间
.setAutoCancel(true) 点击通知,自动消失
.build() 链式调用结束最后调用这个方法, 构建Notification
manager.notify(标识id, notification) 发送消息
广播
静态广播
Main
sendBroadcast(Intent().setAction("Hello")) 发送广播
Br extends BroadcastReceiver
重写onReceive方法 该方法会收到广播
AndroidManifest.XML
receiver
android:name="。Br" 要注册的类
exported="true" 是否能接收其他软件的广播
enabled="true" 是否能被实例化
intent-filter
action
name="Hello" 要绑定的广播
动态广播
1.创建并继承,和重写
public class CustomReceiverStatic extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {}
}
public class CustomReceiverStatic extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {}
}
2.CustomReceiver receiver = new CustomReceiver(); 创建需要接收广播的类实例
3.IntentFilter intentFilter = new IntentFilter(); 创建IntentFilter标签对象
4.intentFilter.addAction(Custom.CUSTOMRECEIVER); 添加Action属性
5.registerReceiver(receiver, intentFilter); 注册该类,以IntentFilter方式注册
6.sendBroadcast(new Intent().setAction(name)); 发送广播
闹钟 TimePicker
time = findViewById() 获得TimePocker对象
.setIs24HourView(false) 设置12小时制
time.currentHour 获得当前设置的时
time.currentMinute 获得当前设置的分
intent = Intent(A.this, B.class) 规定跳转
pendingIntent = PendingIntent.getActivity(context, 0, intent, 0) 获得PendingIntent对象
service = (AlarmManager)getSystemService(Context.ALARM_SERVICE) 获得AlarmManager对象
.set(唤醒方式, calendar.timeInMillis, pendingIntent) 设置闹钟
AlarmManager.RTC_WAKEUP 到指定时间提醒,唤醒
AlarmManager.RTC 到指定时间提醒,不唤醒
ELAPSED_REALTIME_WAKEUP 到指定时间延时提醒 唤醒
ELAPSED_REALTIME 到指定时间延时提醒 不唤醒
calendar = Calendar.getInstance() 获得日历对象
.set(时间类型, 时间位置)
Calendar.HOUR_OF_DAY 时类型
Calendar.MINUTE 分类型
Calendar.SECOND 秒类型
画笔和画布
new Paint()
.setStyle(样式) 修改画笔样式
Paint.Style.FILL 填充
Paint.Style.STROKE 描边
Paint.Style.FILL_AND_STROKE 填充和描边
.setStrokeWidth(0f) 线的宽度
.setColor(ContextCompat.getColor(context, 颜色资源))
.setTextSize(0f) 字体大小
.setTypeface(Typeface.常量) 画笔类型
.setAntiAlias(true) 是否启动抗锯齿画笔
.setPathEffect(DashPathEffect(new float{10f, 10f}, 10f)) 画笔路径效果
canvas
.drawRect(↖x, ↖y, ↘x, ↘y, paint) 绘制矩形
.drawLine(起始x, 起始y, 目标x, 目标y, paint) 绘制线
.drawText(文字, x, y, paint) 绘制文字
.drawCircle(x, y, r, paint) 绘制圆
.drawPah(path, paint) 绘制路径
.drawTextOnPath("str", path, x偏移量, y偏移量, paint) 绕路径的文本
.withTranslation(x, y){} 拖动画布到(x,y)
.withRotation(angle){} 旋转画布angle度
共用
EditText
onTextChanged 文本框变动监听器
onTouchEvent 文本框触碰监听器
方法
setCompoundDrawablesRelativeWithIntrinsicBounds(⬅, ⬆, ➡, ⬇) 向控件中添加有初始值的资源
ContextCompat.getDrawable(context, 资源地址) 获取Dawable布局
e.getAction() 当前触碰方式
e.getX() 当前触碰的X轴
e.getY() 当前触碰的Y轴
getWidth() 获取当前控件宽度
getHeight() 获取当前控件高度
it.getIntrinsicWidth() 获得固有宽度
it.getIntrinsicHeight() 获得固有高度
常量
MotionEvent.ACTION_UP 弹起事件
路径new Path()
.addCircle(x, y, r, 方向) 绘制圆形路径
.addRect(bx by, ex, ey 方向) 绘制矩形路径
Path
Path.Direction.CCW 逆时针
Path.Direction.CW 顺时针
计算机绘图
1.不要直接用画笔在画布上画, 这和现实绘画有点不同
现实绘画,画布基本不动, 画笔频繁活动.
而计算机绘画恰恰相反, 画布频繁移动, 画笔基本不动
2.计算机绘画首先将画布的(x,y)坐标移动到笔下, 由此作为起点进行绘画,
如果要绘画一条旋转中的线, 不是画笔不断改变角度画线然后刷新得到,
而是画布以圆心飞快旋转, 画笔角度不变得到的
现实绘画,画布基本不动, 画笔频繁活动.
而计算机绘画恰恰相反, 画布频繁移动, 画笔基本不动
2.计算机绘画首先将画布的(x,y)坐标移动到笔下, 由此作为起点进行绘画,
如果要绘画一条旋转中的线, 不是画笔不断改变角度画线然后刷新得到,
而是画布以圆心飞快旋转, 画笔角度不变得到的
lifecycle-runtime-ktx-2.4.0 需要这个外部依赖
LifecycleObserver 继承这个类
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME) 注解标记一个启动方法
rotatingJob = CoroutineScope(Dispatchers.Main).launch {
while (true){
delay(1)
mAngle += 0.08f
invalidate()
}
}
while (true){
delay(1)
mAngle += 0.08f
invalidate()
}
}
lifecycle.addObserver(findViewById<MyView>(R.id.myView)) 主函数中调用
动画
逐帧动画
1.配置xml
1.在res中创建anim文件夹
2.在xml中设置
<animation-list>
<animation-list>
3.在<animation-list>标签中设置
<item drawable="资源路径" duration="停留毫秒">
<item drawable="资源路径" duration="停留毫秒">
4.将配置的xml使用到布局的背景上
2.启动动画
1.animationDrawable = 控件.getBackground() 获取动画
2.animationDrawable.start() 启动动画
3.animationDrawable.stop() 停止
补间动画
1.渐变动画
1.配置xml
1.在res中创建anim文件夹
2.在xml中设置<set>标签
3.在<set>标签中设置
<alpha forAlpha="0~1" toAlpha="0~1" duration="动画持续毫秒">
<alpha forAlpha="0~1" toAlpha="0~1" duration="动画持续毫秒">
4.将配置的xml使用到布局的背景上
2.为控件绑定补间动画
1.animation = AnimationUtils.loadAnimation(上下文, 补间动画资源)
2.控件.startAnimation(animation) 启动补间动画
2.旋转动画
1.配置xml
1.在res中创建anim文件夹
2.在xml中设置<set>标签
3.在<set>标签中设置
<rotate forDegress="0~360" toDegress="0~360" pivotX="中心X点" pivotY="中心Y点" duration="动画持续毫秒">
<rotate forDegress="0~360" toDegress="0~360" pivotX="中心X点" pivotY="中心Y点" duration="动画持续毫秒">
4.将配置的xml使用到布局的背景上
2.为控件绑定补间动画
1.animation = AnimationUtils.loadAnimation(上下文, 补间动画资源)
2.控件.startAnimation(animation) 启动补间动画
3.缩放动画
1.配置xml
1.在res中创建anim文件夹
2.在xml中设置<set>标签
3.在<set>标签中设置
<scale forXScale="缩放前X" forYScale="缩放前Y" toXScale="缩放比例X" toYScale="缩放比例Y" pivotX="中心X点" pivotY="中心Y点" duration="动画持续毫秒">
<scale forXScale="缩放前X" forYScale="缩放前Y" toXScale="缩放比例X" toYScale="缩放比例Y" pivotX="中心X点" pivotY="中心Y点" duration="动画持续毫秒">
3.在<set>标签中设置
<scale forXScale="缩放前X" forYScale="缩放前Y" toXScale="缩放比例X" toYScale="缩放比例Y" pivotX="中心X点" pivotY="中心Y点" duration="动画持续毫秒">
<scale forXScale="缩放前X" forYScale="缩放前Y" toXScale="缩放比例X" toYScale="缩放比例Y" pivotX="中心X点" pivotY="中心Y点" duration="动画持续毫秒">
4.将配置的xml使用到布局的背景上
2.为控件绑定补间动画
1.animation = AnimationUtils.loadAnimation(上下文, 补间动画资源)
2.控件.startAnimation(animation) 启动补间动画
4.平移动画
1.配置xml
1.在res中创建anim文件夹
2.在xml中设置<set>标签
3.在<set>标签中设置
<translate fromXDelta="起始x" fromYDelta="起始y" toXDelta="结束x" toYDelta="结束y" duration="动画持续毫秒">
<translate fromXDelta="起始x" fromYDelta="起始y" toXDelta="结束x" toYDelta="结束y" duration="动画持续毫秒">
4.将配置的xml使用到布局的背景上
2.为控件绑定补间动画
1.animation = AnimationUtils.loadAnimation(上下文, 补间动画资源)
2.控件.startAnimation(animation) 启动补间动画
多媒体
播放音频的两种方法
1.MediaPlay
1.MediaPlay静态方法
.create(context, 音频资源) 通过create方法指定需要播放的音乐
2.MediaPlay非静态方法
.start() 开始播放
.stop() 停止播放
.pause() 暂停播放
.reset() 重置
.setOnCompletionListener(() -> {}) 完成事件监听器
.setDataSource() 通过setDataSource方法指定需要播放的音乐
.isPlaying() 音乐是否处于播放状态
.release() 释放资源
2.SoundPool
Drawable控制
item标签
drawable="@" 引用位图/颜色
state_pressed="true" 控件是否被按下
state_focused="true" 控件是否获得焦点
state_enable="true" 控件是否可用
state_selected="true" 控件是否被选中,针对滚轮
state_checked="true" 控件是否被勾选
state_checkable="true" 控件可否被勾选
异常处理
Unknown Service Exception 未知服务异常
解决方案 android:usesCleartextTraffic="true"
android:screenOrientation="landscape" 设置横屏显示
0 条评论
下一页