在Day22中当我们启动ObserveService时会把MainActivity给终止掉,因此今天要做的内容事实上就是重启MainActivity後能直接回到PreviewFragment的过程。
启动时会在WelcomeFragment,由於已经是在Ptt内的状态,可以直接跳过LoginFragment到後面。另外为了达到PreviewFramgnet点击返回後能顺利回到SearchArticleFragment的路线,我新加的Navigation Action会是WelcomeFragment到SearchArticleFragment的路线,接着再另外回到PreviewFragment。
<action
android:id="@+id/action_welcomeFragment_to_searchArticleFragment"
app:destination="@id/searchArticleFragment"
app:popUpTo="@id/welcomeFragment"
app:popUpToInclusive="true">
<argument
android:name="toPreview"
android:defaultValue="true"
app:argType="boolean"
app:nullable="false" />
</action>
可以看到我加入的是一个带有argument的Action,这部份请参考Pass data between destinations。
<argument
android:name="toPreview"
android:defaultValue="false"
app:argType="boolean"
app:nullable="false" />
这是与welcomeFragment的argument对应的,但是在这边的defaultValue设为false
,这是为了避免从LoginFragment进来时被这个argument影响到。
<argument
android:name="isInArticle"
android:defaultValue="false"
app:argType="boolean"
app:nullable="false" />
previewFragment中也加入一样的Argument,这是因为从悬浮视窗回来时Ptt本来就已在文章里面,不需要做原本PreviewFragment在Day16~Day17的内容中做的前置动作。
路线规划好後就是处理程序码的判断了。
主要就是在点击back时取消注册updateRunnable并开启新的MainActivity。
binding.back.setOnClickListener {
updateHandler.removeCallbacks(updateRunnable)
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
}
首先需要判断目前ObserviceService是否正在启动中。
在ObserviceService加入:
class ObserveService : Service() {
companion object {
public var isRunning = false
}
override fun onCreate() {
super.onCreate()
isRunning = true
// ...
}
override fun onDestroy() {
super.onDestroy()
isRunning = false
// ...
}
}
接着就能直接判断了:
class WelcomeFragment : Fragment() {
//...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (ObserveService.isRunning) {
requireActivity().stopService(
Intent(requireActivity(), ObserveService::class.java)
)
NavHostFragment.findNavController(this@WelcomeFragment)
.navigate(R.id.action_welcomeFragment_to_searchArticleFragment)
return
}
// ...
}
}
把ObserveService关闭并且使用刚刚新增的Action直接进到SearchArticleFragment,由於这个Action的toPreview argument预设值为true
,这边就不需要做另外的操作了。
判断若toPreview为true
的话直接进入PreviewFragment。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
arguments?.run {
if (SearchArticleFragmentArgs.fromBundle(this).toPreview) {
this.clear()
NavHostFragment.findNavController(this@SearchArticleFragment)
.navigate(
SearchArticleFragmentDirections
.actionSearchArticleFragmentToPreviewFragment(
true
)
)
return@onViewCreated
}
}
// ...
}
进入时记得要把isInArticle argument设为true
。
针对isInArticle做判断即可。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// ...
arguments?.run {
if (PreviewFragmentArgs.fromBundle(this).isInArticle) {
updateHandler.post(updateRunnable)
} else {
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
PttClient.getInstance().send("G")
delay(100L)
parseComments(PttClient.getInstance().getScreen())
updateHandler.postDelayed(updateRunnable, updateInterval)
}
}
}
}
先讲结论就是可能明後天会针对这个Class做修改了,具体要改成什麽样子我还在思考中。这边会提到是因为从PreviewFragment回到SearchArticleFragment时,我需要保留先前的搜寻状态,否则当进入ObserveService、把MainActivity退出後,原本存在SearchArticleFragment内的searchTitleSet、searchAuthorSet、currentBoard都会被清掉。为了保留这些状态我是先把几个变数放到PttClient这个singleton class中了。
public var currentBoard = ""
public val searchTitleSet = mutableSetOf<String>()
public val searchAuthorSet = mutableSetOf<String>()
接着在SearchArticleFragment开启时将值重新放入。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// ...
binding.searchBoardInput.setText(PttClient.getInstance().currentBoard)
// ...
if ((PttClient.getInstance().searchAuthorSet.isNotEmpty()
|| PttClient.getInstance().searchTitleSet.isNotEmpty())
) {
(requireActivity() as MainActivity).showLoading("")
PttClient.getInstance().searchAuthorSet.forEach { addAuthorChip(it) }
PttClient.getInstance().searchTitleSet.forEach { addTitleChip(it) }
refreshSearch()
}
}
最後就是如一开始所说的,PttClient的修改(or 重做)已经是势在必行了,毕竟目前使用上也不少别扭的地方。
到目前为止基本上App的主要画面和流程都已经出来了,接下来的几天应该就是针对现有内容做修改/优化了。
<<: #23-用Canvas做Google恐龙游戏(都市老妹生存记!能击退经痛加班和渣男吗?)
>>: DAY 27『 使用相机拍照 』 ImagePicker - Part1
「干部不强,我身上尽是汗水味; 干部太强,我身旁满是血腥味。」 年轻时候 待过的公司,共有三个部门...
方便後续解释概念,我们在创建一个跟原先single_table一样的表,叫single_table2...
如果您的电商网站,需要有个很多样化的首页,来应付不同档期的活动需求,不只是换换 Banner 而已,...
前言 我们在Object [上]与Object [下]中多次提到[[Prototype]],但是都没...
本篇文章同步发表在 HKT 线上教室 部落格,线上影音教学课程已上架至 Udemy 和 Youtu...