Day06 - Parsing Ptt(补充)

接续Day04,在确认连上Ptt後,会将页面跳转至Login页,原本Day04应该要把这些都写进去的,结果前几天家人来找急着发文就忘了Orz

这篇预计先把Parsing的部分补充完,并加入Loading Layout供接下来登入流程使用。

Parsing

需先补充之前遗漏的部分。在透过PipedOutputStreamPipedInputStreamReader将Ptt Server回传的byte array转成二维的CharArray及字串後,我们需要一个方法来判断目前的页面到哪边了。实作上是以PatternMatcher来判断目前的页面是否有符合我们需要的特徵。

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页面让使用者输入帐密来做接续的登入。

Loading画面

因为预期登入会是比较花时间的流程,所以决定先在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 = ""
}

实际显示如下:
loading

明天就是完成登入的部分了,也在这边祝大家中秋节快乐~!


<<:  Day06 补充笔记2

>>:  06. DB x tinker x seeder

DAY25: 作用域三种类

在这一篇主要讲了Node 在终机端和脚本文件this不同的指向,那麽今天要来简单介绍Nodejs作用...

[Day11] 团队管理:团队共识与团队思考

团队目标的建立 提供对应的元素,催化IT团队与事业体相呼应的目标 身为产品经理,需要清楚知道公司目标...

Day 12 - Key Sequence Detection (KONAMI CODE)

前言 JS 30 是由加拿大的全端工程师 Wes Bos 免费提供的 JavaScript 简单应用...

React.js 职场实战!图片 Infinite List

一天的开始 还记得吗?你是负责 Imager 的前端工程师,上次做了 Lazy Loading 改...

[Day-6] R语言 - 怎麽选 分群群数 & 距离? ( Clustering Distance & Index )

您的订阅是我制作影片的动力 订阅点这里~ 若内容有误,还请留言指正,谢谢您的指教 ...