Kotlin-在点击CardView的另一个片段中打开其他片段

问题描述

我是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,false)
            }
        })

        return root
    }

}

3。 galleryFragment.kt

import ...

class galleryFragment : Fragment() {

    private lateinit var galleryviewmodel: galleryviewmodel

    override fun onCreateView(
            inflater: LayoutInflater,savedInstanceState: Bundle?
    ): View? {
        galleryviewmodel =
                viewmodelProviders.of(this).get(galleryviewmodel::class.java)
        val root = inflater.inflate(R.layout.fragment_gallery,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,savedInstanceState: Bundle?
    ): View? {
        slideshowviewmodel =
                viewmodelProviders.of(this).get(Slideshowviewmodel::class.java)
        val root = inflater.inflate(R.layout.fragment_slideshow,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。这将有助于在其中添加/替换所需的片段。

<FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

现在在“活动”中,创建以下函数。它将帮助您替换所需的片段。

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。优良作法是将加载碎片的责任留在活动上。

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())
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...