Android Fragment找不到ID对应的视图。

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

Getting Android Fragment no view found for ID

问题

我已经检查过这个问题,并测试了这个网站上解释的解决方案(尽管我可能在执行它们时犯了错误,因为出现这个错误可能有很多可能的原因)。

我的意思是像这里提供的解决方案一样:

https://stackoverflow.com/questions/7508044/android-fragment-no-view-found-for-id

以及这里:

https://stackoverflow.com/questions/22761814/android-fragment-no-view-found-for-id-0x7f040034

所以,我要解释一下我的特殊情况。

首先,我在我的片段中像这样设置布局:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
    root = inflater.inflate(R.layout.activity_calendario_laboral, container, false);
    return root;
}

该布局总结如下:

<?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"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:id="@+id/principal">
    [...]
    </LinearLayout>
</FrameLayout>

一旦视图创建完毕,我就会调用这个方法:

final Fragment thisFragment=this;
KotlinClass.Companion.setCalendarViewdateListener(calendarView,thisFragment,R.id.principal);

在KotlinClass的这个方法中,我会调用这个函数:

setFragment(FichajesFragment(), fragment,"Fichajes",id);

其中,fragment参数是传递给setCalendarViewdateListener函数的thisFragment

最后,我定义了setFragment如下:

private fun setFragment(fragment: Fragment, fragment2: Fragment, tag: String, id: Int) {
    val fragmentManager: FragmentManager = fragment2.activity!!.supportFragmentManager
    val fragmentTransaction = fragmentManager.beginTransaction()
    for (activeFragment in fragmentManager.fragments) {
        fragmentTransaction.remove(activeFragment)
    }
    fragmentTransaction.add(id, fragment, tag)
    fragmentTransaction.commit()
    fragmentManager.executePendingTransactions()
}

在执行fragmentManager.executePendingTransactions()时,会引发异常,指示找不到id,引用的是LinearLayout的id“principal”。

我漏掉了什么?

英文:

First of, I've checked this question has been done and have tested the solutions that are explained on this site (although I may have committed errors in doing them as there are so many possible causes for the error).

I mean solutions like the ones offered here:

https://stackoverflow.com/questions/7508044/android-fragment-no-view-found-for-id

And here:

https://stackoverflow.com/questions/22761814/android-fragment-no-view-found-for-id-0x7f040034

So, I'm explaining my particular case.

First of, I'm setting the layout like this in my fragment:

 public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        root = inflater.inflate(R.layout.activity_calendario_laboral, container, false);
        return root;
    }

That layout is, summarized, as it follows:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;FrameLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    android:id=&quot;@+id/main_content&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:orientation=&quot;vertical&quot;
    android:id=&quot;@+id/principal&quot;&gt;
[...]
&lt;/LinearLayout&gt;
&lt;/FrameLayout&gt;

Once the view has been created I get to call this method:

final Fragment thisFragment=this;
KotlinClass.Companion.setCalendarViewdateListener(calendarView,thisFragment,R.id.principal);

In that method of KotlinClass I get to call this function:

setFragment(FichajesFragment(), fragment,&quot;Fichajes&quot;,id);

Being the parameter fragment the thisFragment passed to setCalendarViewdateListener function.

I've finally defined setFragment like this:

private fun setFragment(fragment: Fragment, fragment2: Fragment, tag: String, id: Int) {
                    val fragmentManager: FragmentManager = fragment2.activity!!.getSupportFragmentManager();
 val fragmentTransaction = fragmentManager.beginTransaction()
 for (activeFragment in fragmentManager.fragments) {
          fragmentTransaction.remove(activeFragment)
 }
 fragmentTransaction.add(id, fragment, tag)
 fragmentTransaction.commit()
 fragmentManager.executePendingTransactions()
 
}

It raises an exception when executing fragmentManager.executePendingTransactions() telling that no view found for id, refering to the principal id of the linearlayout.

What am I missing?

答案1

得分: 1

如果我理解正确,在您的布局文件中,您必须指定参数:
tools:context=".FragmentName"

英文:

If I understand correctly, I think in your layout file you have to specify parameter:
tools:context=&quot;.FragmentName&quot;

答案2

得分: 0

我注意到了几个问题,但导致你的应用崩溃的主要问题是这部分代码:

val fragmentManager: FragmentManager = fragment2.activity!!.getSupportFragmentManager()
val fragmentTransaction = fragmentManager.beginTransaction()
for (activeFragment in fragmentManager.fragments) {
    fragmentTransaction.remove(activeFragment)
}

fragmentManager中,你存储了属于托管fragment2的活动的fragmentManager,在你的情况下,布局包含@+id/principal id 的fragment2。然后在你的for循环中,你删除了由该fragmentManager管理的所有片段,这意味着你也从中删除了fragment2。所以当你后来调用:

fragmentTransaction.add(id, fragment, tag)

它找不到任何具有@+id/principal id 的视图,因为包含该LinearLayout(fragment2)的片段刚刚被删除。

所以为了使你的代码工作,移除for循环,应用程序就不会再崩溃了。但从你的代码示例来看,我猜你想将FichajesFragment 添加为fragment2 的一部分,在这种情况下,你使用了错误的fragmentManager;而不是活动的fragmentManager,你应该使用属于fragment2 的那个,即:

val fragmentManager: FragmentManager = fragment2.childFragmentManager

还有一点需要注意的是,我对R.layout.activity_calendario_laboral 感到困惑,但布局实际上是为片段的,如果我理解正确的话,所以只是为了让你知道。

英文:

I noticed several issues, but the main problem why your app is crashing is because of this part:

 val fragmentManager: FragmentManager = fragment2.activity!!.getSupportFragmentManager();
 val fragmentTransaction = fragmentManager.beginTransaction()
 for (activeFragment in fragmentManager.fragments) {
          fragmentTransaction.remove(activeFragment)
 }

Into fragmentManager you stored the fragmentManager that belongs to the activity that hosts the fragment2, in your case the fragment with the layout including the Linearlayout with @+id/principal id. Then in your for loop, you remove all the fragments that are managed by that fragmentManager, which means you removed the fragment2 from it too. So when you later call:

fragmentTransaction.add(id, fragment, tag)

it can't find any view with the id @+id/principal, because the fragment containing that Linearlayout (fragment2) was just removed.

So for your code to work, remove the for loop and the app should not crash anymore. But the way your code samples look, I assume you want to add FichajesFragment as part of the fragment2, in which case you are using wrong fragmentManager; instead of the activity one, you should use the one that belongs to fragment2, i.e.:

val fragmentManager: FragmentManager = fragment2.childFragmentManager

One more note: I got confused by the R.layout.activity_calendario_laboral, but the layout is actually for the fragment, if I understood it correctly, so just so you know.

huangapple
  • 本文由 发表于 2020年8月11日 16:27:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/63354355.html
匿名

发表评论

匿名网友

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

确定