Android 如何从另一个';它是可视寻呼机的一部分吗?

Android 如何从另一个';它是可视寻呼机的一部分吗?,android,android-fragments,kotlin,android-viewpager,Android,Android Fragments,Kotlin,Android Viewpager,我刚刚开始在Kotlin进行Android开发,我不太确定解决这种情况的正确方法是什么 基本上,我想做的是有一个ViewPager,它可以滚动浏览相同类型的项目列表。与每个项目关联的视图都有一个按钮。当我按下按钮时,我想启动一个新片段,我们称之为iteminfo。iteminfo片段应该使用back堆栈,这样您就可以点击back按钮并返回到您在点击按钮之前查看的项目视图 我现在的设置方式是: -My Main Activity将包含片段的我的ViewPager添加到FragmentManager

我刚刚开始在Kotlin进行Android开发,我不太确定解决这种情况的正确方法是什么

基本上,我想做的是有一个
ViewPager
,它可以滚动浏览相同类型的项目列表。与每个项目关联的视图都有一个按钮。当我按下按钮时,我想启动一个新片段,我们称之为
iteminfo
iteminfo
片段应该使用back堆栈,这样您就可以点击back按钮并返回到您在点击按钮之前查看的项目视图

我现在的设置方式是:

-My Main Activity将包含片段的我的ViewPager添加到FragmentManager。(我打算采用单活动架构。)

-My ViewPager fragment包含一个私有内部类,该类带有一个维护项目片段列表的
PagerAdapter
。创建
ViewPager
片段时,将生成项目片段并将其添加到PagerAdapter

-每个项目片段都有自己的按钮。创建片段时,按钮将获得一个
onClickListener

这是我遇到一个死胡同的地方

到目前为止,我已经设法让iteminfo片段显示,让item片段消失,但我的方法非常简单:我执行了一个片段事务,将iteminfo片段()添加到item_fragment.xml的根元素,然后将其中其他元素的可见性设置为“消失”。不过,如果我按下后退按钮,应用程序就会退出。所以这并不能解决问题

我已经了解到,在片段视图之间切换时,使用.xml文件中的单个空FrameLayout作为片段容器,然后使用FragmentManager从中添加/删除片段是一种很好的设计。这对我来说很有意义

但是,我不知道如何删除
ViewPager
中的片段()。好吧,除非您正在执行片段事务,否则无法设置片段的标记。因此,如果要执行replace(),我不知道如何引用要替换的片段

作为一个圣母玛利亚,我尝试替换整个
ViewPager
片段(因为这是通过片段事务添加到MainActivity中的,所以我能够标记它),但出于某种原因,这只会产生一个NPE。子片段不能替换父片段是有道理的,尽管我不能100%确定它为什么是NPE

无论如何,你能给我带来的任何启示都是非常感激的

编辑:在下面添加了相关代码

MainActivity.kt:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val currentFragment = supportFragmentManager
            .findFragmentById(R.id.fragment_container)

        if (currentFragment == null) {
            val fragment = ItemPagerFragment.newInstance()
            supportFragmentManager
                .beginTransaction()
                .add(R.id.fragment_container, fragment, "viewPager")
                .commit()
        }
    }
}
activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</FrameLayout>
fragment_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_frame"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="8dp">

    <Button
        android:id="@+id/info_button"
        android:layout_gravity="center|bottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/some_string"
        />

</FrameLayout>


InfoFragment.kt和fragment_info.xml可以是任何东西,就我的问题而言,它们是什么并不重要。

如果我正确理解了您的问题,这里的解决方案非常简单

您有一个活动,其中有一个FrameLayout,它是片段的容器。实际上,你把你的片段和ViewPager放在了里面。当您单击按钮时,只需使用ViewPager将新片段放在片段顶部

底线是,所有操作都必须通过活动进行。那些您必须有一个活动将实现的接口,并且片段将从上下文接收其实例(例如,在片段的onAttach()方法中)。当您单击按钮时,您只需将事件传递给活动。活动已经在创造一个新的片段,从而保留了倒退


重要的是要理解,当处理片段时,它们不应该知道彼此的存在。所有操作都必须通过抽象进行,并由您的parentView(活动、ParentFragmen等)执行。

包括您所做的代码,然后任何人都可以提供解决方案。
<?xml version="1.0" encoding="utf-8"?>
<androidx.viewpager.widget.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
class ItemFragment(i: Item): Fragment() {

    private var item: Item = i;
    private lateinit var infoButton: Button

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_item, container, false)

        infoButton = view.findViewById(R.id.info_button) as Button

        infoButton.setOnClickListener{
            val fragment: InfoFragment =  InfoFragment.newInstance(item)
            val fragmentManager: FragmentManager = childFragmentManager
            val fragmentTransaction = fragmentManager.beginTransaction()

            // this is where I have been having no success
            // and know my approach is certainly wrong/confused
            fragmentTransaction.replace(R.id.item_frame, fragment)
            fragmentTransaction.addToBackStack(null)
            fragmentTransaction.commit()
        }

        return view
    }

    companion object {
        fun newInstance(i: Item): ItemFragment {
            return ItemFragment(i)
        }
    }

}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_frame"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="8dp">

    <Button
        android:id="@+id/info_button"
        android:layout_gravity="center|bottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/some_string"
        />

</FrameLayout>