「SD编辑」开发记录
本文最后更新于:2019年8月2日 下午
SD - Slam Dump(并不是)
这个App的主要目的是满足广大人民群众对图片编辑的需求。
字体问题
Android默认的字体不太好看,也不一定能很好地匹配背景图。如果内置字体,遇到最大的问题是版权问题。
因此决定增加用户自行导入字体的功能,由用户来决定使用什么字体。
原来的字体文件是放在asset中。Typeface.createFromAsset
直接引入并使用。1
2Typeface tf = Typeface.createFromAsset(mgr, "fonts/fz_grid.ttf");
mContentTv.setTypeface(tf);
设计一个字体管理界面。用户自行选择将字体文件复制到App内部存储路径。
使用字体时,再用Typeface.createFromFile()
获取Typeface。
选择文件
调用系统文件选择器1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32private static final int REQ_CODE_CHOOSE_FILE = 10;
// 启动选择文件...
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivityForResult(intent, REQ_CODE_CHOOSE_FILE);
// ......
// 处理选择的文件
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
switch (requestCode) {
case REQ_CODE_CHOOSE_FILE:
if (data != null) {
Uri uri = data.getData();
Log.d(TAG, "onActivityResult: uri: " + uri);
if (uri != null && !TextUtils.isEmpty(uri.getPath())) {
copyFile(uri);
} else {
Log.e(TAG, "onActivityResult: 选择的文件无效");
}
} else {
showShort(getApplicationContext(), "没选中文件");
Log.e(TAG, "onActivityResult: data is NULL 没选中文件");
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
处理uri
uri形如
content://com.android.externalstorage.documents/document/primary%3ADownload%2Ffz_grid.ttf
uri.getPath获取到的并不是文件的绝对路径。但我们可以利用ContentResolver来获取到InputStream。
也可以获取到uri的文件名。
1 |
|
也可以简单地使用uri.getLastPathSegment来获取文件名1
2
3uri.getLastPathSegment();
String[] t = uriPath.split(File.separator);
String name = t[t.length - 1];
https://stackoverflow.com/questions/4263002/how-to-get-file-name-from-uri
Toolbar问题
使用toolbar时经常会遇到问题。例如设置title的问题。
这里自己创建一个统一的标题栏TitleBar。想要什么控件自己添加。
Google MobileAds
MobileAds.initialize(getApplicationContext(), AdsMgr.GOOGLE_ADS_APP_ID);
的执行会占用很多时间。测试过程中发现小米手机甚至使用了3秒钟来执行这个方法。
https://stackoverflow.com/questions/37418663/what-is-the-proper-way-to-call-mobileads-initialize
给启动页Activity一个纯色的启动背景。1
2
3
4
5<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowBackground">@color/colorPrimary</item>
</style>
启动页中初始化Ads时实在是耗时太长,干脆放到子线程中去操作。
虽然官方文档建议的是越早初始化越好。但也不希望太影响用户体验。
递归查看某个路径下的文件
1 |
|
提供草稿功能
为方便用户使用,提供草稿功能。这就涉及到增删查改的操作。
[2019-7-31] 本来想直接用sqlite,但为了开发方便,选用了greenDAO。
https://github.com/greenrobot/greenDAO
使用2个表,分别为Draft(存档)和DraftContent(图层)。DraftContent中存放着关联的存档ID。
能保存的东西都保存下来。
greendao插入元素
1 |
|
插入元素后就有id了。
greendao删除元素
1 |
|
使用DrawerLayout
报错: IllegalArgumentException: No drawer view found with gravity LEFT
1 |
|
忘记中xml中加上开抽屉方向了 tools:openDrawer=”start”1
2
3
4
5
6
7
8<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_page_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".act.MainActivity"
tools:openDrawer="start">
抽屉加上方向 android:layout_gravity=”start”1
2
3
4
5
6
7<!-- 抽屉 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:layout_marginEnd="100dp"
android:orientation="vertical">
美术设计,App交互设计
设计是一个比较令我头疼的问题。在这个看脸的时代,App一定要好看!对我而言,直接采用material design的风格会比较省事。
经过调整和对比,我选择使用暗色的风格。因为现在主流的图形编辑软件,颜色风格以暗色居多。
参考:
- 看颜色示例 https://material.io/design/color/applying-color-to-ui.html#sheets-surfaces
- 查颜色 https://material-ui.com/customization/color/
文字编辑
文字内容,大小,旋转方向,颜色都可以调整。
需要一个调色盘来调整颜色。找个第三方的,好看能用即可。
删除存档报错
list类的经典异常 ConcurrentModificationException。
1 |
|
list删除元素时报错。这样写是不行的。1
2
3
4
5for (Data d : dataList) {
if (d.selected) {
dataList.remove(d);
}
}
用迭代器来删除元素。1
2
3
4
5
6
7Iterator<Data> iterator = dataList.iterator();
while (iterator.hasNext()) {
Data data = iterator.next();
if (data.selected) {
iterator.remove();
}
}
输出图片
保存View的显示内容
获取一个view的bitmap,然后保存到文件去。
1 |
|
保存图片文件后的处理
用户输出图片文件后,打开微信想发送这张图片。但是用户发现微信的快捷发送功能找不到这张图片。
怎么才能让微信知道这里新增了一张图片呢?
如果要发送广播ACTION_MEDIA_MOUNTED
1 |
|
报错,没有足够的权限
1 |
|
Android KK开始,这个广播开始只能由系统发出。KK及之后的版本需使用Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
1 |
|
参考
移动TextView
编辑页中有一个需求是手指拖动文字。
1.1.x版本
1.1.0版本的做法是,在Activity的onTouch方法里来改变TextView的坐标。从而实现TextView的拖动效果。
父View和子View设同一个OnTouchListener。但是只有父view来处理触摸事件。
如果是子view接收到了触摸事件,则做一个bool标记firstOnTv = true,返回false,把触摸事件交给父view来处理。
父view处理触摸事件时,判断如果刚才点中的是子view(即mContentTv),则在MotionEvent.ACTION_MOVE时更改子view的坐标。
1 |
|
版本更新
- 2019-8-8 v1.1.1 版本更新
- 解决了一些bug
- UI调整,增加了抽屉的头图和欢迎文字
- 2019-8-4 v1.1.0 版本更新