今天来把昨天的搜寻结果给显示出来,并让使用者选择要去哪个看板。显示的部分我想使用PopupWindow,单纯觉得适合且过去比较少用到,顺便练习看看。
在看完相关资料後,其实就是把它当作一个用来显示View的框架。在使用上先自行创建View後利用建构子设进PopupWindow即可。
layout(layout_search_board_result.xml)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/one_grid_unit"
android:background="@color/transparent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/one_grid_unit"
android:background="@color/black" />
<TextView
android:id="@+id/noResultLabel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/one_grid_unit"
android:background="@color/black"
android:gravity="center"
android:text="查无看板"
android:textColor="@color/text_normal"
android:textSize="20sp"
android:textStyle="bold"
android:typeface="monospace"
android:visibility="gone" />
</FrameLayout>
基本上就是一个RecyclerView来显示解析出来的看板列表,若列表为空的话就改显示"查无看板"的TextView。
inflate view
@SuppressLint("InflateParams")
private fun showSearchResult(boardList: List<String>) {
val view =
LayoutInflater.from(requireContext())
.inflate(R.layout.layout_search_board_result, null)
// ...
}
接着根据传入的boardList是否为空来决定要显示RecyclerView或是TextView
val height = if (boardList.isEmpty()) {
view.noResultLabel.visibility = View.VISIBLE
view.recyclerView.visibility = View.GONE
120f.dpToPx(requireContext())
} else {
val adapter = SearchBoardResultAdapter(boardList)
adapter.onBoardClickListener = { board ->
popupWindow?.dismiss()
searchBoardInput.setText(board)
}
view.recyclerView.setHasFixedSize(true)
view.recyclerView.layoutManager = LinearLayoutManager(requireContext())
view.recyclerView.adapter = adapter
360f.dpToPx(requireContext())
}
RecyclerView的创建跟内容没啥特别的就不多贴了,这段if/else除了确定要显示哪个View以外也同时给定的height值,这是在接下来创建popupWindow时会需要带入的参数。
而在计算height时我是使用扩展函数,将预期的DP值转为PX:
fun Float.dpToPx(context: Context): Int {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
this,
context.resources.displayMetrics
).toInt()
}
onBoardClickListener是我在SearchBoardResultAdapter内宣告的函数变数,用来回传itemView点击时所点的看板名称,点击回传後就直接把所选的看板放回EditText(searchBoardInput)。
最後就是创建PopupWindow并显示,整体的function内容如下
@SuppressLint("InflateParams")
private fun showSearchResult(boardList: List<String>) {
val view =
LayoutInflater.from(requireContext())
.inflate(R.layout.layout_search_board_result, null)
val height = if (boardList.isEmpty()) {
view.noResultLabel.visibility = View.VISIBLE
view.recyclerView.visibility = View.GONE
120f.dpToPx(requireContext())
} else {
val adapter = SearchBoardResultAdapter(boardList)
adapter.onBoardClickListener = { board ->
popupWindow?.dismiss()
searchBoardInput.setText(board)
}
view.recyclerView.setHasFixedSize(true)
view.recyclerView.layoutManager =
LinearLayoutManager(requireContext())
view.recyclerView.adapter = adapter
360f.dpToPx(requireContext())
}
popupWindow = PopupWindow(
view, // view
ViewGroup.LayoutParams.MATCH_PARENT, // width
height, // height
true // focusable
)
popupWindow?.showAsDropDown(searchBoardInput)
}
值得一提的是建构函数最後需带入focusable的布林值,以我的View来说若focusable为false的话影响只在点击Window外的其他区域或按back时无法自动关闭Window。
最终操作画面会像这样:
<<: Day 9 - Container With Most Water
>>: [重构倒数第07天] - 不用靠後端的 client 端上传图片预览图
ES6:Promise Promise:代表一个即将成功或失败的非同步操作 会有这几状态: 搁置 (...
完结,撒花~~~~~~~~~~· 谢谢这三十天以来看这三十篇废文的各位, 其实很多细节没有能够提及,...
接下来为您介绍 10 款不错的第三方 YouTube 下载软件!让我们来看看哪个软件才是 2022 ...
依据方法作用的对象不同,有分实体方法(instance method)及类别方法(class met...
那今天不说废话了直接开始 延续昨天的 我们已经建立出一个 main function 和 新增的 f...