Kotlin – 在另一个片段中点击 CardView 时打开其他片段

huangapple go评论82阅读模式
英文:

Kotlin - Open other fragment on click CardView in another fragment

问题

Sure, here's the translated version of the code:

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)

        val myCard1 = root.findViewById(R.id.cardOpenGallery) as CardView
        myCard1.setOnClickListener(object : View.OnClickListener {
            override fun onClick(v: View?) {
                val fragment = GalleryFragment()
                val transaction = requireActivity().supportFragmentManager.beginTransaction()
                transaction.replace(R.id.nav_host_fragment, fragment)
                transaction.addToBackStack(null)
                transaction.commit()
            }
        })

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

This code will allow you to open the GalleryFragment when the CardView in HomeFragment is clicked.

英文:

I'm new in Android Studio and having trouble opening fragment on click CardView in other fragment. I have Navigation View in layout and navigate to other fragment (fragment_home, fragment_gallery, fragment_slideshow, and other fragment layout.). But I have to create CardView in fragment_home to click for open some fragment layout (Gallery and Slideshow).

I have layout:

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>

And Kotlin code,

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

How to implement action for CardView click to open other fragment?, Please help and Thank for your any solution. Thanks.

答案1

得分: 0

你需要在这里打开另一个片段。为此,您需要用所需的片段替换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()
        }
    }) 

我希望这对您有所帮助。

祝您编码愉快 Kotlin – 在另一个片段中点击 CardView 时打开其他片段

英文:

You need to open another fragment here. For this you need to replace the fragment container in MainActivity with the desired fragment.

Replace this

 myCard1.setOnClickListener(object : View.OnClickListener {
        override fun onClick(v: View?) {
            inflater.inflate(R.layout.fragment_gallery, container, false)
        }
    })

with this

myCard1.setOnClickListener(object : View.OnClickListener {
        override fun onClick(v: View?) {
        ((Activity) getContext).supportFragmentManager.beginTransaction()
        .replace(R.id.fragment_container, GalleryFragment())       
        .commit()
        }
    }) 

I hope this will work for you.

Happy Coding Kotlin – 在另一个片段中点击 CardView 时打开其他片段

答案2

得分: 0

你只是试图在你的HomeFragment中添加fragment_gallery。我不认为这是正确的做法。尽管如此,我会提供我使用的方法。

在你的 activity_main.xml 文件中添加一个 FrameLayout,它将用于添加/替换所需的fragment。

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

现在在你的 Activity 中创建以下函数。它将帮助你替换所需的 fragment。

private fun replaceFragment(fragmentInstance: Fragment) {
    supportFragmentManager
        .beginTransaction()
        .addToBackStack(fragmentInstance.javaClass.canonicalName) // 可选
        .replace(R.id.container, fragmentInstance)
        .commit()
}

现在,在 onCreate 中加载 homeFragment(因为它是你要显示的第一个 fragment)。

override fun onCreate(savedInstanceState: Bundle?) {
    val fragment = HomeFragment()
    replaceFragment(fragment)
}

此阶段,你将能够成功加载 homeFragment。现在下一步是创建一个回调接口。每次你点击 homeFragment 中的任何卡片,你只需要将所需的信息传递回 MainActivity。将加载 fragment 的责任留给 Activity 是一个很好的做法。

interface OnCardClickListener {
    fun onCardClick(fragment: Fragment)
}

在 MainActivity 中实现此监听器。

class MainActivity : OnCardClickListener {

这将覆盖 onCardClick。在 onCardClick 内部调用 replace 方法。

override fun onCardClick(fragment: Fragment) {
    replaceFragment(fragment)
}

在 HomeFragment 中,创建 OnCardClickListener 的实例。

var listener: OnCardClickListener? = null

然后在 onAttach 中。

override fun onAttach(context: Context) {
    super.onAttach(context)
    listener = context as OnCardClickListener
}

到目前为止,我们已经实现了加载 fragment 所需的机制。现在只剩下一个最后的步骤,即在点击 cardView 时打开所需的 fragment。为此,请按照以下步骤操作:

myCard1.setOnClickListener {
    listener?.onCardClick(GalleryFragment())
}

// 如果还有另一个可用的卡片。
myCard2.setOnClickListener {
    listener?.onCardClick(SlideshowFragment())
}
英文:

You're just trying to inflate the fragment_gallery inside your homeFragment. I don't think it's the right way to do it. Although, I'll suggest the approach I use.

Inside your activity_main.xml add the FrameLayout. which will be useful to add/replace the desired fragment into it.

&lt;FrameLayout
        android:id=&quot;@+id/container&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        /&gt;

Now in your Activity, create the following function. It will help you to replace the desired fragment.

private fun replaceFragment(fragmentInstance: Fragment) {
supportFragmentManager
               .beginTransaction()
               .addToBackStack(fragmentInstance.javaClass.canonicalName)//optional
               .replace(R.id.container, fragmentInstance)
               .commit()
}

Now, inside onCreate load the homeFragment (as it is your first fragment to show)

override fun onCreate(savedInstanceState: Bundle?) {
val fragment = HomeFragment()
replaceFragment(fragment)
}

At this stage, you'll be able to load homeFragment successfully. Now next step is to create a callback interface. Every time you click on any card from the homeFragment you just have to provide the required information back to the mainActivity. It is good practice to leaving the responsibility of loading fragments on the activity.

interface OnCardClickListener {
    fun onCardClick(fragment: Fragment)
}

implement this listener in MainActivity.

class MainActivity: OnCardClickListener{

It will override the onCardClick. now inside onCardClick call the replace method.

override onCardClick(fragment: Fragment){
replaceFragment(fragment)
}

Inside HomeFragment, Create an instance of OnCardClickListener

var listener: OnCardClickListener? = null

then in onAttach.

override fun onAttach(context: Context) {
        super.onAttach(context)
        listener = context as OnCardClickListener
    }

Till this point, we have implemented the mechanism required to load fragment. Now only one final step is pending which is opening the desired fragment onClick of cardView. for that do as follow:

myCard1.setOnClickListener{
   listener.onCardClick(GalleryFragment())
}

//If there&#39;s one more card available.
myCard2.setOnClickListener{
   listener.onCardClick(SlideshowFragment())
}

huangapple
  • 本文由 发表于 2020年9月15日 18:22:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/63899846.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定