接续Day04,在确认连上Ptt後,会将页面跳转至Login页,原本Day04应该要把这些都写进去的,结果前几天家人来找急着发文就忘了Orz
这篇预计先把Parsing的部分补充完,并加入Loading Layout供接下来登入流程使用。
需先补充之前遗漏的部分。在透过PipedOutputStream、PipedInputStream、Reader将Ptt Server回传的byte array转成二维的CharArray及字串後,我们需要一个方法来判断目前的页面到哪边了。实作上是以Pattern和Matcher来判断目前的页面是否有符合我们需要的特徵。
fun <T> expect(patterns: Array<T>): Int {
val list = ArrayList<Pattern>()
patterns.forEach {
when(it){
is String ->{
list.add(Pattern.compile(it))
}
is Pattern->{
list.add(it)
}
else -> {
list.add(Pattern.compile(Pattern.quote(it.toString())));
}
}
}
return expect(list)
}
private fun expect(list: List<Pattern>): Int {
val endTime = System.currentTimeMillis() + defaultTimeout
while (true) {
val currentScreen: String = getScreen()
for (i in list.indices) {
val m: Matcher = list[i].matcher(currentScreen)
if (m.find()) {
return i
}
}
Log.d(tag, "expect: no pattern match.")
val waitTime = endTime - System.currentTimeMillis()
if (waitTime <= 0) {
return EXPECT_TIMEOUT
}
try {
Thread.sleep(100)
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
}
expect方法会在设定的timeout到达前,每100毫秒检查一次目前的页面是否有符合我们需要的特徵,若有符合的话就回传该特徵的index值,反之回传EXPECT_TIMEOUT告知timeout。
以最初的Welcome跳转至Login页面为例,使用上方法如下:
PttClient.getInstance().start()
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
if (PttClient.getInstance()
.expect(arrayOf("请输入代号,或以 guest 参观,或以 new 注册:")) == 0) {
withContext(Dispatchers.Main) {
NavHostFragment.findNavController(this@WelcomeFragment)
.navigate(R.id.action_welcomeFragment_to_loginFragment)
}
}
}
也就是当画面内容有显示"请输入代号,或以 guest 参观,或以 new 注册:"这个字串时,代表可以进行登入了,於是跳转到下一页的Login页面让使用者输入帐密来做接续的登入。
因为预期登入会是比较花时间的流程,所以决定先在MainActivity这边加上一个Loading的Layout,在开始登入时显示。
xml加入:
<!-- ... -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/loadingLayout"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#66888888"
android:clickable="true"
android:focusable="true"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:indeterminateTint="@color/white"
app:layout_constraintBottom_toTopOf="@id/loadingMsg"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/loadingMsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:textColor="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/progress"
tools:text="Loading..." />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- ... -->
MainActivity加入:
public fun showLoading(msg: String) {
loadingLayout.visibility = View.VISIBLE
loadingMsg.text = msg
}
public fun showLoading(@StringRes msgId: Int) {
loadingLayout.visibility = View.VISIBLE
loadingMsg.setText(msgId)
}
public fun dismissLoading() {
loadingLayout.visibility = View.GONE
loadingMsg.text = ""
}
实际显示如下:
明天就是完成登入的部分了,也在这边祝大家中秋节快乐~!
在这一篇主要讲了Node 在终机端和脚本文件this不同的指向,那麽今天要来简单介绍Nodejs作用...
团队目标的建立 提供对应的元素,催化IT团队与事业体相呼应的目标 身为产品经理,需要清楚知道公司目标...
前言 JS 30 是由加拿大的全端工程师 Wes Bos 免费提供的 JavaScript 简单应用...
一天的开始 还记得吗?你是负责 Imager 的前端工程师,上次做了 Lazy Loading 改...
您的订阅是我制作影片的动力 订阅点这里~ 若内容有误,还请留言指正,谢谢您的指教 ...