从片段访问content_main.xml上的视图? [英] Access view on content_main.xml from a fragment?

查看:45
本文介绍了从片段访问content_main.xml上的视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我将NavController与Fragments一起使用.在某些片段中,我需要访问MainActivity布局上的视图.我这样做是这样的:

In my app I use NavController with Fragments. In some fragments I need to access views on MainActivity layout. I do that in this way:

val fab: FloatingActionButton = requireActivity().findViewById(R.id.fab)

这可以按预期正常工作.但是,不想调用一个视图,并且findViewById()返回null.

This works properly as expected. However, one view does not want to be called and the findViewById() returns null.

布局结构是这样的.在activity_main.xml

The layout structure is like this. In activity_main.xml

<androidx.drawerlayout.widget.DrawerLayout
    <androidx.coordinatorlayout.widget.CoordinatorLayout
        ....>
        <FrameLayout
            android:id="@+id/frame"
            .... />
        <include
            android:id="@+id/include"
            layout="@layout/app_bar_main" />
    </androidx.constraintlayout.widget.ConstraintLayout>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav"
        .... />
</androidx.drawerlayout.widget.DrawerLayout>

包含

app_bar_main.xml

<androidx.coordinatorlayout.widget.CoordinatorLayout 
    ....>

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar"
        ....>

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing"
            ....>
            <com.google.android.material.appbar.MaterialToolbar
                android:id="@+id/toolbar"
                .... />
        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>

    <include
        android:id="@+id/content"
        layout="@layout/content_main" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        .... />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

其中包括content_main.xml

<androidx.core.widget.NestedScrollView 
    android:id="@+id/nested"
    ....>

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/host"
        .... />
</androidx.core.widget.NestedScrollView>

问题是,我需要访问NestedScrollView,尽管可以访问所有其他视图,但是content_main.xml上的该视图无法访问并返回null:

The problem is, I need to access the NestedScrollView and although all other views can be accessed, this one on the content_main.xml cannot be accessed and returns null:

java.lang.NullPointerException: requireActivity().findViewById(R.id.nested) must not be null

class HomeFragment : Fragment() {
    private lateinit var drawer: DrawerLayout
    private lateinit var nested: NestedScrollView
    private lateinit var fab: FloatingActionBar
    private lateinit var bng: FragmentHomeBinding
    
    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View {
        setHasOptionsMenu(true)
        bng = FragmentHomeBinding.inflate(layoutInflater, container, false)
        return bng.root
    }
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        drawer = requireActivity().findViewById(R.id.drawer)
        fab = requireActivity().findViewById(R.id.fab)
        nested = requireActivity().findViewById(R.id.nested) // This line throws exception

        .........
    }
}

如您所见,我使用viewBinding处理Fragment的Views. 我认为这可能不是问题.

As you can see, I use viewBinding to handle Fragment's Viewss. I do not think that this might be problem.

推荐答案

因此,如果有人要寻找解决方案,那么这里有一个对我有用的解决方案.首先,我发现需要重新排列XML布局,以便将content_main.xmlapp_bar_layout.xml的内容直接放入activity_main.xml中,如下所示:

So, if someone should look for a solution, here is an one that worked for me. First of all, I found out that I needed to reorder my XML layouts so that put the contents of the content_main.xml and the app_bar_layout.xml directly into the activity_main.xml like this:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/drawer"
    ...>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:id="@+id/coordinator"
            ...>

            <com.google.android.material.appbar.AppBarLayout
                ... >

                <com.google.android.material.appbar.CollapsingToolbarLayout
                    android:id="@+id/collapsing"
                    ... >

                    <com.google.android.material.appbar.MaterialToolbar
                        android:id="@+id/toolbar"
                        ... />

                </com.google.android.material.appbar.CollapsingToolbarLayout>
            </com.google.android.material.appbar.AppBarLayout>

            <androidx.core.widget.NestedScrollView
                android:id="@+id/nested"
                ... >

                <androidx.fragment.app.FragmentContainerView
                    android:id="@+id/host"
                    ... />
            </androidx.core.widget.NestedScrollView>

            <com.google.android.material.floatingactionbutton.FloatingActionButton
                android:id="@+id/fab"
                ... />

        </androidx.coordinatorlayout.widget.CoordinatorLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>


    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav"
        ... />
</androidx.drawerlayout.widget.DrawerLayout>

这可能不是最佳方法,但是如果没有此步骤,将无法访问content_main.xml上的View,这确实是胡扯,因为它无法正常工作.其实不知道,但是Google似乎改变了其库中的某些内容或应该更改的内容.

It might be not an optimal way, but without this step, the Views on content_main.xml could not be accessed, which is really a bullshit as before it properly worked. Actually, no idea, but it seems that Google changed something in its libraries or whatever that should be.

下一步,要从某个Fragmentactivity_main.xml上访问的View,必须将其公开:

As a next step, Views you want to access on the activity_main.xml from a certain Fragment, you have to make them public:

MainActivity.kt

class MainActivity : AppCompatActivity() {
    
    ...

    lateinit var fab: FloatingActionButton
    lateinit var nested: NestedScrollView

    ...

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

        ...

        nested = findViewById(R.id.nested)
        fab = findViewById(R.id.fab)
    
        ...
    }
}

现在,它们可以像这样在Fragment中使用:

Now, they can be used in a Fragment like this:

MyFragment.kt

class MyFragment : Fragment() {

    ...

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        ...

        var fab: FloatingActionButton
        var nested: NestedScrollView

        (activity as MainActivity).apply {
            fab = this.fab
            nested = this.nested
        }

        ...
    }
}

就这些!这样,我就可以实现自己的目标.

That's all guys! In this way, I could achieve my goals.

如上所述,这可能不是最佳方法,但对我有用.

As mentioned above, this might not be an optimal way, but it worked for me.

希望这可以帮助某人解决此类问题.

Hopefully, this helps someone to fix this kind of problem.

欢迎并提出任何改进或建议.

Any improvements or suggestions are welcome and appreciated.

这篇关于从片段访问content_main.xml上的视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆