目前先使用預設建立的畫面,一個FrameLayout跟TextView,將目前的畫面印出來而已。
class PreviewFragment : Fragment() {
private val mTag = "PreviewFragment"
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_preview, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// ...
tmp.text = PttClient.getInstance().getScreen()
}
}
目前流程的預覽如下
接著先回到搜尋頁面,為文章列表加上點擊事件。
class SearchArticleResultAdapter : RecyclerView.Adapter<SearchArticleResultAdapter.ViewHolder>() {
private val articleList = mutableListOf<Article>()
var onArticleClickListener: ((article: Article) -> Unit)? = null
// ...
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
init {
itemView.setOnClickListener {
onArticleClickListener?.invoke(articleList[adapterPosition])
}
}
// ...
}
}
宣告一個onArticleClickListener callback,並在ViewHolder創建時為itemView加上click事件的呼叫。
articleAdapter.onArticleClickListener = { article ->
(requireActivity() as MainActivity).showLoading("")
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
val ret = withContext(Dispatchers.IO) {
PttClient.getInstance().send("${article.number}\r\nr")
delay(200L)
PttClient.getInstance()
.expect(arrayOf("瀏覽[\\s\\S]*第[\\s\\S]*頁[\\s\\S]*目前顯示[\\s\\S]*第[\\s\\S]*行[\\s\\S]*離開"))
}
if (ret == 0) {
NavHostFragment.findNavController(this@SearchArticleFragment)
.navigate(R.id.action_searchArticleFragment_to_previewFragment)
}
(requireActivity() as MainActivity).dismissLoading()
}
}
Ptt進入文章的除了一般操作的上下左右外,也可以直接輸入文章編號+(enter or r),也就是我此處send的內容。接著就是判斷是否有成功進入文章內了,使用的Pattern也就是我們在閱讀文章時最下面會顯示的內容:
確認進入文章後就使用Navigation導到下一頁並顯示內容來做確認了,接下來幾天會再來做解析推文的部分。
因為我PreviewFragment的畫面還沒設定,因此目前是先處理點擊back鍵的退出流程。
在Fragment內取得Activity的onBackPressedDispatcher並addCallback。
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
(requireActivity() as MainActivity).showLoading("")
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
val ret = withContext(Dispatchers.IO) {
PttClient.getInstance().send("q")
delay(200L)
PttClient.getInstance().expect(arrayOf("文章選讀"))
}
(requireActivity() as MainActivity).dismissLoading()
if (ret == 0) {
PttClient.getInstance().printScreen()
NavHostFragment.findNavController(this@PreviewFragment).popBackStack()
} else {
AlertDialog.Builder(requireContext())
.setTitle("Error")
.setMessage("Something wrong.")
.setPositiveButton(android.R.string.ok) { _, _ ->
requireActivity().finish()
}
.setCancelable(false)
.show()
}
}
}
})
離開文章基本上就是用"q",並判斷是否有正確回到文章列表,有的話就可以呼叫NavController的popBackStack回到上一頁了。
做完退出功能後開心的測試,突然發現有點不對勁...我剛剛的搜尋條件Chip消失了。
應該是因為我的Chip是動態加入的關係,使用Navigation切換到下一頁&回來會經歷DestroyView和CreateView的過程,動態加入的元件不在layout中自然也就消失了。解決的方法也很簡單,因為Fragment本身沒被銷毀,全域變數的值還保留著,在onViewCreated中判斷searchTitleSet和searchAuthorSet是否有內容,有的話就重新加回來:
//...
if ((searchAuthorSet.isNotEmpty() || searchTitleSet.isNotEmpty())) {
searchAuthorSet.forEach { addAuthorChip(it) }
searchTitleSet.forEach { addTitleChip(it) }
}
//...
addAuthorChip及addTitleChip都是Day13的內容,就不重複貼了。