函数Navigation.findNavController()
在代码A中需要一个Activity
参数,但是我只能通过context
获得一个itemView.context
。
如何在Android Studio中从Activity
获得RecyclerView.ViewHolder(itemView)
?
目前,我必须将private val mActivity: Activity
从代码B传递到代码A,它可以工作,但是我认为这不是一个好方法。
添加的内容:
致Miriana Itani:谢谢!
您的代码运行良好。我粘贴了FrameLayout xml文件,可以看到代码C
我很奇怪,代码Navigation.findNavController(temView)...
是如何找到NavController控件的? 你能告诉我吗?
您知道使用代码Navigation.findNavController(mActivity, R.id.fragment_container)
很容易理解,因为NavController的ID是fragment_container
,而且是唯一的。
代码A
class VideoListAdapter (private val videoList: List<File>, private val mActivity: Activity) : RecyclerView.Adapter<VideoListAdapter.MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VideoListAdapter.MyViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.layout_fragment_video_list_recycleview, parent, false)
return MyViewHolder(v)
}
override fun onBindViewHolder(holder: VideoListAdapter.MyViewHolder, position: Int) {
holder.bindItems(videoList[position])
}
override fun getItemCount(): Int {
return videoList.size
}
inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(aFile: File) {
itemView.tvVideoFileName.text=aFile.name
itemView.btnPlay.setOnClickListener {
Navigation.findNavController(mActivity, R.id.fragment_container).navigate(
UIFragmentVideoListDirections.aVideoList2Video((aFile.absolutePath)) )
}
}
}
}
代码B
class UIFragmentVideoList : Fragment() {
private lateinit var listFile: MutableList<File>
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? = inflater.inflate(R.layout.layout_fragment_video_list, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val outputDirectoryOfVideo = getVideoOutputDirectory(requireContext())
listFile =outputDirectoryOfVideo.listFiles{file -> VIDEO_EXTENSION_WHITELIST.contains(file.extension.toUpperCase())}
.sorted().reversed().toMutableList()
videoRecyclerView.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false)
val aVideoListAdapter=VideoListAdapter(listFile,requireActivity())
videoRecyclerView.adapter=aVideoListAdapter
}
}
代码C
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<fragment
android:id="@+id/fragment_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</FrameLayout>
答案 0 :(得分:2)
事实上,我认为您无需通过该活动即可使NavController工作:
我认为更好的方法是:
Navigation.findNavController(temView).navigate(
UIFragmentVideoListDirections.aVideoList2Video((aFile.absolutePath))
)
请尝试让我知道。
添加的答案:
NavHostFragment -用于创建片段目标的NavHost的实现。它具有自己的NavController和导航图。通常,每个活动将有一个NavHostFragment。
导航-帮助程序类,用于获取NavController实例,并将导航连接到UI事件,例如单击按钮。
NavigationUI —用于将应用导航模式(如抽屉,底部导航或操作栏)与NavController连接的类。
答案 1 :(得分:0)
您可以像这样从视图的上下文中检索活动:
tailrec fun Context.findActivity(): Activity {
if (this is Activity) {
@Suppress("UNCHECKED_CAST")
return this
} else {
if (this is ContextWrapper) {
return this.baseContext.findActivity()
}
throw IllegalStateException("The context chain does not contain Activity!")
}
}
现在您可以做
val activity = view.context.findActivity()
答案 2 :(得分:0)
您可以将函数传递给片段中的适配器。这样您就不必通过活动
class VideoListAdapter (private val videoList: List<File>, val btnPlayClick: (File) -> Unit) : RecyclerView.Adapter<VideoListAdapter.MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VideoListAdapter.MyViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.layout_fragment_video_list_recycleview, parent, false)
return MyViewHolder(v)
}
override fun onBindViewHolder(holder: VideoListAdapter.MyViewHolder, position: Int) {
holder.bindItems(videoList[position], btnPlayClicked )
}
override fun getItemCount(): Int {
return videoList.size
}
inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(aFile: File, click -> (File) -> Unit) {
itemView.tvVideoFileName.text=aFile.name
itemView.btnPlay.setOnClickListener {
click(aFile)
}
}
}
}
并在片段中构建这样的适配器
val aVideoListAdapter = VideoListAdapter(listFile) { myFile ->
Navigation.findNavController(activity!!, R.id.fragment_container).navigate(
UIFragmentVideoListDirections.aVideoList2Video((myFile.absolutePath))
)
}