Kotlin - 在另一个片段中单击 CardView 打开另一个片段
Kotlin - Open other fragment on click CardView in another fragment
我是 Android Studio 的新手,在单击其他片段中的 CardView 时无法打开片段。我在布局中有导航视图并导航到其他片段(fragment_home、fragment_gallery、fragment_slideshow 和其他片段布局。)。但我必须在 fragment_home 中创建 CardView 才能单击以打开一些片段布局(画廊和幻灯片)。
我有布局:
1. fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment">
<androidx.cardview.widget.CardView
android:id="@+id/cardOpenGallery"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_margin="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="#ccc">
<TextView
android:id="@+id/textOpenGallery"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:textAlignment="center"
android:textSize="30sp"
android:textColor="#000"
android:text="Open Gallery"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
2。 fragment_gallery.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.gallery.GalleryFragment">
<!-- other layout element here -->
</FrameLayout>
3。 fragment_slideshow.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.gallery.SlideshowFragment">
<!-- other layout element here -->
</FrameLayout>
和 Kotlin 代码,
1. MainActivity.kt
import ...
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val fab: FloatingActionButton = findViewById(R.id.fab)
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(setOf(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow), drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.main, menu)
return true
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
2。 HomeFragment.kt
import ...
class HomeFragment : Fragment() {
private lateinit var homeViewModel: HomeViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
homeViewModel =
ViewModelProviders.of(this).get(HomeViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_home, container, false)
//I have problem here-----
val myCard1 = root.findViewById(R.id.cardOpenGallery) as CardView
myCard1.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
inflater.inflate(R.layout.fragment_gallery, container, false)
}
})
return root
}
}
3。 GalleryFragment.kt
import ...
class GalleryFragment : Fragment() {
private lateinit var galleryViewModel: GalleryViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
galleryViewModel =
ViewModelProviders.of(this).get(GalleryViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_gallery, container, false)
val textView: TextView = root.findViewById(R.id.text_gallery)
galleryViewModel.text.observe(viewLifecycleOwner, Observer {
textView.text = it
})
return root
}
}
4. SlideshowFragment.kt
import ...
class SlideshowFragment : Fragment() {
private lateinit var slideshowViewModel: SlideshowViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
slideshowViewModel =
ViewModelProviders.of(this).get(SlideshowViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_slideshow, container, false)
val textView: TextView = root.findViewById(R.id.text_slideshow)
slideshowViewModel.text.observe(viewLifecycleOwner, Observer {
textView.text = it
})
return root
}
}
如何实现CardView点击打开其他片段的动作?请帮忙,谢谢你的任何解决方案。谢谢。
您需要在此处打开另一个片段。为此,您需要用所需的片段替换 MainActivity 中的片段容器。
替换这个
myCard1.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
inflater.inflate(R.layout.fragment_gallery, container, false)
}
})
有了这个
myCard1.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
((Activity) getContext).supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, GalleryFragment())
.commit()
}
})
我希望这对你有用。
快乐编码:)
您只是想给 homeFragment 中的 fragment_gallery 充气。我认为这不是正确的做法。不过,我会建议我使用的方法。
在您的 activity_main.xml 中添加 FrameLayout。这将有助于 add/replace 将所需的片段放入其中。
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
现在在您的 Activity 中,创建以下函数。它将帮助您替换所需的片段。
private fun replaceFragment(fragmentInstance: Fragment) {
supportFragmentManager
.beginTransaction()
.addToBackStack(fragmentInstance.javaClass.canonicalName)//optional
.replace(R.id.container, fragmentInstance)
.commit()
}
现在,在 onCreate 中加载 homeFragment(因为这是您要显示的第一个片段)
override fun onCreate(savedInstanceState: Bundle?) {
val fragment = HomeFragment()
replaceFragment(fragment)
}
在此阶段,您将能够成功加载 homeFragment。现在下一步是创建一个回调接口。每次单击 homeFragment 中的任何卡片时,您只需将所需信息提供回 mainActivity。将加载片段的责任留在 activity.
上是一种很好的做法
interface OnCardClickListener {
fun onCardClick(fragment: Fragment)
}
在 MainActivity 中实现此侦听器。
class MainActivity: OnCardClickListener{
它将覆盖 onCardClick。现在在 onCardClick 中调用 replace 方法。
override onCardClick(fragment: Fragment){
replaceFragment(fragment)
}
在 HomeFragment 中,创建 OnCardClickListener 实例
var listener: OnCardClickListener? = null
然后在 onAttach 中。
override fun onAttach(context: Context) {
super.onAttach(context)
listener = context as OnCardClickListener
}
至此,我们已经实现了加载片段所需的机制。现在只有最后一步未决,即打开 cardView 的 onClick 所需片段。为此,请执行以下操作:
myCard1.setOnClickListener{
listener.onCardClick(GalleryFragment())
}
//If there's one more card available.
myCard2.setOnClickListener{
listener.onCardClick(SlideshowFragment())
}
我是 Android Studio 的新手,在单击其他片段中的 CardView 时无法打开片段。我在布局中有导航视图并导航到其他片段(fragment_home、fragment_gallery、fragment_slideshow 和其他片段布局。)。但我必须在 fragment_home 中创建 CardView 才能单击以打开一些片段布局(画廊和幻灯片)。
我有布局:
1. fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment">
<androidx.cardview.widget.CardView
android:id="@+id/cardOpenGallery"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_margin="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="#ccc">
<TextView
android:id="@+id/textOpenGallery"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:textAlignment="center"
android:textSize="30sp"
android:textColor="#000"
android:text="Open Gallery"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
2。 fragment_gallery.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.gallery.GalleryFragment">
<!-- other layout element here -->
</FrameLayout>
3。 fragment_slideshow.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.gallery.SlideshowFragment">
<!-- other layout element here -->
</FrameLayout>
和 Kotlin 代码,
1. MainActivity.kt
import ...
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val fab: FloatingActionButton = findViewById(R.id.fab)
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(setOf(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow), drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.main, menu)
return true
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
2。 HomeFragment.kt
import ...
class HomeFragment : Fragment() {
private lateinit var homeViewModel: HomeViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
homeViewModel =
ViewModelProviders.of(this).get(HomeViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_home, container, false)
//I have problem here-----
val myCard1 = root.findViewById(R.id.cardOpenGallery) as CardView
myCard1.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
inflater.inflate(R.layout.fragment_gallery, container, false)
}
})
return root
}
}
3。 GalleryFragment.kt
import ...
class GalleryFragment : Fragment() {
private lateinit var galleryViewModel: GalleryViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
galleryViewModel =
ViewModelProviders.of(this).get(GalleryViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_gallery, container, false)
val textView: TextView = root.findViewById(R.id.text_gallery)
galleryViewModel.text.observe(viewLifecycleOwner, Observer {
textView.text = it
})
return root
}
}
4. SlideshowFragment.kt
import ...
class SlideshowFragment : Fragment() {
private lateinit var slideshowViewModel: SlideshowViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
slideshowViewModel =
ViewModelProviders.of(this).get(SlideshowViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_slideshow, container, false)
val textView: TextView = root.findViewById(R.id.text_slideshow)
slideshowViewModel.text.observe(viewLifecycleOwner, Observer {
textView.text = it
})
return root
}
}
如何实现CardView点击打开其他片段的动作?请帮忙,谢谢你的任何解决方案。谢谢。
您需要在此处打开另一个片段。为此,您需要用所需的片段替换 MainActivity 中的片段容器。
替换这个
myCard1.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
inflater.inflate(R.layout.fragment_gallery, container, false)
}
})
有了这个
myCard1.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
((Activity) getContext).supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, GalleryFragment())
.commit()
}
})
我希望这对你有用。
快乐编码:)
您只是想给 homeFragment 中的 fragment_gallery 充气。我认为这不是正确的做法。不过,我会建议我使用的方法。
在您的 activity_main.xml 中添加 FrameLayout。这将有助于 add/replace 将所需的片段放入其中。
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
现在在您的 Activity 中,创建以下函数。它将帮助您替换所需的片段。
private fun replaceFragment(fragmentInstance: Fragment) {
supportFragmentManager
.beginTransaction()
.addToBackStack(fragmentInstance.javaClass.canonicalName)//optional
.replace(R.id.container, fragmentInstance)
.commit()
}
现在,在 onCreate 中加载 homeFragment(因为这是您要显示的第一个片段)
override fun onCreate(savedInstanceState: Bundle?) {
val fragment = HomeFragment()
replaceFragment(fragment)
}
在此阶段,您将能够成功加载 homeFragment。现在下一步是创建一个回调接口。每次单击 homeFragment 中的任何卡片时,您只需将所需信息提供回 mainActivity。将加载片段的责任留在 activity.
上是一种很好的做法interface OnCardClickListener {
fun onCardClick(fragment: Fragment)
}
在 MainActivity 中实现此侦听器。
class MainActivity: OnCardClickListener{
它将覆盖 onCardClick。现在在 onCardClick 中调用 replace 方法。
override onCardClick(fragment: Fragment){
replaceFragment(fragment)
}
在 HomeFragment 中,创建 OnCardClickListener 实例
var listener: OnCardClickListener? = null
然后在 onAttach 中。
override fun onAttach(context: Context) {
super.onAttach(context)
listener = context as OnCardClickListener
}
至此,我们已经实现了加载片段所需的机制。现在只有最后一步未决,即打开 cardView 的 onClick 所需片段。为此,请执行以下操作:
myCard1.setOnClickListener{
listener.onCardClick(GalleryFragment())
}
//If there's one more card available.
myCard2.setOnClickListener{
listener.onCardClick(SlideshowFragment())
}