【问题标题】:Creating a simple Android fragment with Navigation Drawer使用导航抽屉创建一个简单的 Android 片段
【发布时间】:2020-05-16 00:59:14
【问题描述】:

我是一位经验丰富的开发人员,但对 Android 编程很陌生,我有点难过。我从 Android Studio Navigation Drawer 标准项目模板开始。我设法在其中一个片段(Gallery Fragment)中实现了一个简单的项目列表,并在按下按钮时执行某些操作。因此,当按下按钮时,我希望它向下钻取到一个新屏幕。应该很简单,但我已经阅读了十几个 Android 片段教程,但我什么也没有发生。

所以我创建了要激活的新片段:

package tech.iconultra.ui.gallery

import android.content.Context
import android.net.Uri
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import tech.iconultra.R

private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
class IconPackGalleryFragment : Fragment() {
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null
    private var listener: OnFragmentInteractionListener? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val root = inflater.inflate(R.layout.icon_pack_gallery, container, false)
        return root
    }

    // TODO: Rename method, update argument and hook method into UI event
    fun onButtonPressed(uri: Uri) {
        listener?.onFragmentInteraction(uri)
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
    }

    override fun onDetach() {
        super.onDetach()
        listener = null
    }

    interface OnFragmentInteractionListener {
        fun onFragmentInteraction(uri: Uri)
    }

    companion object {
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            IconPackGalleryFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}

还有一个简单的布局:

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

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

        <EditText
                android:id="@+id/editText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ems="10"
                android:inputType="textPersonName"
                android:text="Name" />

        <ScrollView
                android:layout_width="match_parent"
                android:layout_height="match_parent">

            <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">

                <TableLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent">

                    <TableRow
                            android:layout_width="match_parent"
                            android:layout_height="match_parent" />

                    <TableRow
                            android:layout_width="match_parent"
                            android:layout_height="match_parent" />

                    <TableRow
                            android:layout_width="match_parent"
                            android:layout_height="match_parent" />

                    <TableRow
                            android:layout_width="match_parent"
                            android:layout_height="match_parent" />
                </TableLayout>
            </LinearLayout>
        </ScrollView>
    </LinearLayout>

</LinearLayout>

但我不知道什么化身可以激活它们。 我试过这个:

                                val fragmentManager: FragmentManager = activity!!.supportFragmentManager
                                fragmentManager?.beginTransaction()?.apply {
                                    add(0, IconPackGalleryFragment(), "aaaaa")
                                    commit()
                                }

然后什么也没有发生。我试过了:

                                val fragmentManager: FragmentManager = activity!!.supportFragmentManager
                                fragmentManager?.beginTransaction()?.apply {
                                    replace(R.id.installed_app_list, IconPackGalleryFragment(), "aaaaa")
                                    commit()
                                }

(R.id.installed_app_list 是我调用它的片段)。 我尝试用各种其他布局替换 R.id.installed_app_list,但对于标准导航抽屉模板项目,我应该在这里传递什么感到困惑。此代码使应用程序崩溃并出现错误:

java.lang.UnsupportedOperationException: addView(View) is not supported in AdapterView

-- 编辑 ------ 我发现这会使片段出现:

  fragmentManager?.beginTransaction()?.apply {
      add(android.R.id.content, IconPackGalleryFragment(), "aaaaa")
      addToBackStack("aaaaa")
      commit()
  }

但是有一些问题:1) 片段似乎有一个不可见的背景,尽管片段本身说它的背景应该是具有 100% alpha 的白色。 2) 按返回不会将您带到上一个屏幕。相反,第一次按下会将您带到主导航屏幕(不是启动该片段的导航屏幕)并且该片段仍然出现在它的前面(!)。第二次按下后退按钮,然后删除片段。'

我猜这是进步,但仍然感到困惑。

【问题讨论】:

    标签: android user-interface android-fragments kotlin


    【解决方案1】:

    试试这个:

    val fragmentManager = (activity as MainActivity).supportFragmentManager
    val fragmentTransaction = fragmentManager.beginTransaction()
    val fragment = IconPackGalleryFragment()
    fragmentTransaction.add(R.id.fragment_iconpackgallery, fragment)
    fragmentTransaction.commit()
    

    并在xml文件中添加:

       <FrameLayout
            android:id="@+id/fragment_iconpackgallery"
            android:layout_width="0dp"
            android:layout_height="0dp"/>
    

    你在哪里需要它。

    【讨论】:

    • 根据transaction.add的文档,第一个参数是你想要放入片段的容器。你是在要求我把片段放入它自己。这会导致程序因“未找到视图”而崩溃。直观地说,API 传递片段 id 和片段对象是没有意义的,因为片段对象已经知道如何使用其 id 创建(膨胀)片段布局,唯一的问题是如何将其附加到现有程序.
    • @xpusostomos 感谢您的回复。您是否为res/layout 中的Fragment IconPackGalleryFragment() 创建了视图?在res/layout 中,您需要创建片段视图res/layout/fragment_iconpackgallery.xml,在此片段所在的Activity 中,您需要在活动xml 文件中添加FrameLayout。我猜您的应用程序崩溃是因为您的应用程序缺少视图 res/layout/fragment_iconpackgallery.xml
    • 布局在 res/layout. IconPackGalleryFragment() 的构造函数成功地膨胀了它。所以我认为问题不存在。
    【解决方案2】:

    要回答我自己的问题,显然 android 抽屉式导航模板使用导航组件,这意味着我必须学习如何在 mobile_navigation.xml 上使用导航设计器,在其中添加一个新屏幕,在我的前一个屏幕和我的新屏幕,然后当我想激活它时,我调用以下内容,并在我的屏幕之间传递链接的 ID。

    findNavController().navigate(R.id.action_nav_gallery_to_iconPackGalleryFragment)

    这样做之后,它就可以工作了。我仍然需要学习和理解何时使用片段管理器,何时使用导航控制器,但似乎在这种情况下,使用导航控制器,而不是片段管理器。

    【讨论】:

      猜你喜欢
      • 2016-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多