桌面小部件-IntentService-Oreo的那些事

简介

之前在《人升》的桌面小部件,实现ListView中的点击事件监听的方式是:

使用fillInIntent发送广播到Widget类中,并在onReceive方法中拦截,处理业务逻辑。

但是,

Widget的本质是个广播接收器,不适宜在里面处理耗时操作。

(完成团队事项的时候需要发送网络请求,普通事项需要更改数据库,都可以视为是耗时操作。)

所以,我决定改用IntentService处理完成事项的业务逻辑。

IntentService的特点是后台运行、自动销毁、异步运行。

首先尝试直接用fillInIntent启动服务失败了。

然后改成了先发送广播,然后在Widget类中,并在onReceive方法拦截再启动IntentService:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent)

if (...) {
...
} else if (intent.action == FINISH_TASK) {
// 将耗时操作交给IntentService完成
val finishIntent = Intent(context, FinishTaskIntentService::class.java)
if (intent.extras != null) {
finishIntent.putExtras(intent.extras!!)
}

try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(finishIntent)
} else {
context.startService(finishIntent)
}
} catch (e: Exception) {
e.printStackTrace()
ToastUtils.showShortToast("完成事项似乎出现了一些问题,请尝试刷新下。", LifeUpApplication.getLifeUpApplication())
}
}
}

然后就遇到了坑。

阅读更多

实现Snackbar弹出时任意View闪躲

简介

Snackbar 是一个底部弹出消息的控件,类似Toast。

基本使用:

1
2
3
Snackbar.make(view, message_text, duration)
.setAction(action_text, click_listener)
.show();

我们知道,在根布局是CoordinatorLayout,并且设置CoordinatorLayout的behavior之后,可以实现Snackbar弹出的时候,fab(浮动按钮)会自动向上移动防止被遮挡。

阅读更多

人升开发日志#15 | 04/02 用Fragment改造设置页面

之前使用Fragment都是配合ViewPager或者配合TabLayout+ViewPager,基本没用过FragmentManager。

实际使用之后才发现,Fragment能实现到和Activity在使用上分辨不出的效果。

布局文件

其实我们要实现的效果很简单,一个主Fragment显示各个设置的大类(比如显示设置、小部件设置等),点击之后切换到不同的Fragment显示,然后那些Fragment只能回退到主Fragment,主Fragment再回退就是结束Activity。

大概这样:

Fragment的布局文件正常就好。

Activity要怎么样呢?我们的Activity本身是不需要任何内容的,只需要充当一个容器的作用就行:

activity_setting.xml

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/background_color"
android:fitsSystemWindows="true"
tools:context=".activities.SettingActivity">

</LinearLayout>
阅读更多

人升开发日志#14 | 03/21 几个小问题的解决

ViewPager + Fragments 导致的选项菜单错乱解决

原先的Toolbar实现

在Fragment中获取Toolbar这个View,然后调用Activity的setSupportActionBar(toolbar)方法。

然后实现Option菜单的方法:在Fragment中设置setHasOptionsMenu(true),然后重写fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater)方法。

出现的问题:似乎是因为ViewPager的缓存机制,导致切换Fragments切换的时候可能出现菜单错乱的情况。

解决:把Toolbar当做控件使用

MainActivity.kt

1
2
3
4
5
6
7
8
9
10
11
12
13
fun initToolBar(toolbar: Toolbar) {
//setSupportActionBar(toolbar) 注释掉这条

currentToolbar = toolbar
val toggle = ActionBarDrawerToggle(
this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
drawer_layout.addDrawerListener(toggle)
nav_view.setNavigationItemSelectedListener(this)
}

fun getCurrentToolbar(): Toolbar? {
return currentToolbar
}

Fragment.kt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private fun initToolbar(view: View) {
//设置toolbar
mToolbar = view.findViewById(R.id.toolbar)
(activity as MainActivity).initToolBar(mToolbar)

// 填充菜单
mToolbar?.inflateMenu(R.menu.main)
mToolbar?.setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.action_sort -> {
// do something
true
}
else -> true
}
}
}
阅读更多

人升开发日志#13 | 03/21 迁移至AndroidX

AndroidX是 Google 发布的对原来的支持库整理后的新一代支持库。并且原来的支持库的最后版本将停留在“28.0.0”,迁移是迟早的事情。

主要动机还是想要用一个框架,结果它只支持AndroidX,就这样决定开始迁移了。

利用Android Studio迁移

需求:Android Studio版本3.2以上

操作:Refactor -> Migrate to Androidx

IDE会询问是否要备份一份当前的项目,并且会告知可能需要你手动解决一些项目Error。

继续操作,IDE会搜索所有的要改变的依赖路径,然后点击DO REFACTOR按钮吧。

阅读更多

VectorDrawable(xml)转换回SVG

Android 用的矢量图是 VectorDrawable(xml格式)。

如果我们想对已经转换成 VectorDrawable 的矢量图进行修改的话,

最好先转换回 SVG 格式再使用 inkscape 之类的矢量图图形编辑工具进行修改。

步骤

  1. 将头部的:

    1
    2
    <?xml version="1.0" encoding="utf-8"?>
    <vector xmlns:android="http://schemas.android.com/apk/res/android"

    替换成

    1
    <svg xmlns="http://www.w3.org/2000/svg"

    闭标签也做相应修改。

  2. android:width替换成width

  3. android:height替换成height

  4. android:pathData替换成d

  5. android:fillColor替换成fill

    如果没有android:fillcolor的话,要加上fill="#ffffff"

  6. android:viewportHeight="24" android:viewportWidth="24"替换成viewBox="0 0 24 24"的形式。

例子

Vector Drawable

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">

<path
android:fillColor="#ffffff"
android:pathData="M12,3L2,12h3v8h2.5v-0.8c0-1.5,3-2.2,4.5-2.2s4.5,0.8,4.5,2.2V20H19v-8h3L12,3zM12,15.2c1.2,0-2.2-1-2.2-2.2 s1-2.2,2.2-2.2s2.2,1,2.2,2.2S13.2,15.2,12,15.2z" />
<path android:pathData="M0,0h24v24H0V0z" />
</vector>

SVG

1
2
3
4
5
6
7
8
9
10
<svg xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24" >

<path
fill="#ffffff"
d="M12,3L2,12h3v8h2.5v-0.8c0-1.5,3-2.2,4.5-2.2s4.5,0.8,4.5,2.2V20H19v8h3L12,3zM12,15.2c1.2,0-2.2-1-2.2-2.2 s1-2.2,2.2-2.2s2.2,1,2.2,2.2S13.2,15.2,12,15.2z" />
<path d="M0,0h24v24H0V0z" fill="none"/>
</svg>

参考

https://stackoverflow.com/questions/44948396/convert-vectordrawable-to-svg

人升开发日志#12 | 01/17 图表

本文讲讲怎么用 MPAndroidChart 框架实现折线图、柱形图、饼图,并且进行样式设置,达到和宣传图差不多的效果。

一开始看到 MPAndroidChart 的各种图表介绍图感觉很好看,但是直接New一个相应图表,仅仅填充数据的话,样式稍微有些丑。经过一番阅览文档才把样式调整得好看些。所以就写了这篇文章记录下。

APP 里实现的最终效果:

引入框架

首先是引入框架:

https://github.com/PhilJay/MPAndroidChart

Gradle设置一下:

1
2
3
4
5
6
7
repositories {
maven { url 'https://jitpack.io' }
}

dependencies {
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0-alpha'
}
阅读更多

「工行星座卡校园版」从下卡到海外在线支付

为什么需要一张信用卡

信用卡对于没有稳定收入的大学生可能显得有些遥远,但对我个人而言感觉很多地方,如果有一张支持visa的信用卡可以方便很多:

  • 美亚、日亚
  • Digital Ocean
  • Google Play以及开发者认证
  • 甚至一些云服务的学生优惠领取都需要信用卡

还有很多信用卡独有的优惠活动。

恰好学校用的银行卡是工行的,就在工行里找可以申办的信用卡,就看中了工行的这款星座卡校园版。

阅读更多

2018 年终总结

第一次写年终总结,也迟到了好几天。

今年真的经历了很多。

一整年没有写日记,也AFK了一整年的DOTA2(年末又玩回来了)。

也不知道要怎么写,就随便写写吧~

阅读更多