【问题标题】:getSupportFragmentManager().findFragmentById() returns nullgetSupportFragmentManager().findFragmentById() 返回 null
【发布时间】:2013-03-20 13:35:50
【问题描述】:

我正在尝试在android中实现片段通信,就像android指南http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity中的那样

但由于 getSupportFragmentManager().findFragmentById() 返回 null,我的应用程序崩溃了。我的实现有什么问题。

代码如下:

该程序只是通过从第一个fragmnet单击按钮将输入文本从一个片段发送到另一个片段textView区域。我有一个activity_main.xml和两个片段布局(两个单独的xml文件,而不是activity_main中的一部分。 xml)

Frag1.java

public class Frag1 extends Fragment {
public Frag1(){

}

buttonClickListener buttonListener;

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
    buttonListener = (buttonClickListener) getActivity();
} catch (ClassCastException e) {
    throw new ClassCastException(activity.toString() + " must implement OnButtonPressListener");
}
}

View myFragmentView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    myFragmentView = inflater.inflate(R.layout.frag1, container, false);


    //SetValue Button
    Button setValueButton = (Button) myFragmentView.findViewById(R.id.setValueButton);
    setValueButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            buttonListener.onButtonPressed("Message received");
        }
    });


    return myFragmentView;
}

}

Frag2.java

public class Frag2 extends Fragment {

View myFragmentView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
 myFragmentView = inflater.inflate(R.layout.frag2, container, false);
    return myFragmentView;
}

void setMessage(String msg){
    TextView txt=(TextView)myFragmentView.findViewById(R.id.textView1);
    txt.setText(msg);
}
}

buttonClickListener.java

public interface buttonClickListener {
public void onButtonPressed(String msg);
}

MainActivity.java

public class MainActivity extends FragmentActivity implements
    ActionBar.TabListener, buttonClickListener {
SectionsPagerAdapter mSectionsPagerAdapter;
@Override
public void onButtonPressed(String msg) {
    // TODO Auto-generated method stub
    Frag2 fragmentObj=(Frag2) getSupportFragmentManager().findFragmentById(R.layout.frag2);


    fragmentObj.setMessage(msg);
}

请告诉我哪里出错了?

编辑: 我正在使用由 Android Plug-in eclipse IDE 生成的模板创建片段。 所以片段是使用 android.support.v4.app.Fragment

创建的
@Override
    public Fragment getItem(int position) {
        Fragment fragment = null;
        switch(position)
        {
        case 0:
            return new Frag1();
        case 1: 
            return new Frag2();
        }
        return fragment;
    }

代码库保留在这里以供参考 https://skydrive.live.com/redir?resid=D37E0F56FEC9B499!259

【问题讨论】:

  • 您使用的是 ActionBarSherlock、支持库还是什么?
  • findFragmentById(R.layout.frag2)。你确定R.layout.flag2,可能是R.id.frag2
  • @gipi 我已经使用了支持库,并且在我的编辑中也进行了更新。
  • @GabrieleMariotti :我没有将 id 添加到片段元素中,因为它们是布局的一部分并且不存在于 元素中。

标签: android android-fragments


【解决方案1】:

试试这个它对我有用How to put Google Maps V2 on a Fragment Using ViewPager

<fragment
            android:id="@+id/map"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            class="com.google.android.gms.maps.SupportMapFragment" />

GoogleMap mGoogleMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap();

【讨论】:

  • 对我来说使用 getChildFragmentManger() 是解决方法。我试图从片段中检索片段,即片段是我调用 findFragmentById() 的片段的子级
【解决方案2】:

为这个问题找到了正确的解决方案

希望更多人看到这个。

Frag2 fragmentObj=(Frag2) mSectionsPagerAdapter.getItem(2);

您应该使用您的适配器(您填充片段的地方)作为获取片段参考的来源。

【讨论】:

    【解决方案3】:

    您应该通过调用

    添加片段Frag2
    getSupportFragmentManager().beginTransaction().add(R.id.frag2_view, new Frag2(), "tag").commit();
    

    在您的 MainActivity 中,其中 R.id.frag2_view 是您的 main_layout 中定义的布局。

    要获得该片段,您应该调用

    Frag2 obj = (Frag2)getSupportFragmentManager().findFragmentById(R.id.frag2_view);
    

    传递用于在 main_layout 中添加片段的布局 id

    希望对你有帮助。

    编辑:

    由于您使用 ViewPager,您应该使用 R.id.pager 作为 ID。 我刚刚尝试了您的示例,并且成功了。

    Frag2 fragmentObj=(Frag2) getSupportFragmentManager().findFragmentById(R.id.pager);
    

    编辑 2:

    尽管它有效,但我真的不认为这是正确的方法,因为 R.id.pager 它来自 ViewPager 并且你找不到,比如说 frag4 frag5.

    请忽略我的回答。我不知道如何用 ViewPager 做到这一点,抱歉。

    【讨论】:

    • 我正在使用 Fragment getItem 来放置片段。那么我应该如何应用你的方法呢?我是 android 新手(才 3 天):)
    • @Kris 我刚刚根据您的问题更新更新了我的答案。我不知道您使用的是 ViewPager。让我知道它是否有效。
    • 第二次编辑后,我没有标记答案,但我觉得它很有用。我会尝试寻找替代方法/等待正确的方法..
    • 查看这个答案link。他使用Frag2 fragmentObj=(Frag2) mSectionsPagerAdapter.instantiateItem(mViewPager, 1);,这似乎有效
    • 感谢@Eduardo Herzer 的帮助,我已经用您最后的评论更新了答案。(必须经过同行评审.. :))
    【解决方案4】:

    我遇到了类似的问题,这里是解决方案。 要在 viewpager 中获取对正确片段的引用,只需调用:

    getSupportFragmentManager().findFragmentByTag(tag);  
    

    您可以使用以下语法构建它的标记参数:"android:switcher:pager_id:index",其中pager_id 是 XML 布局中 ViewPager 的 id,索引是您的片段在 ViewPager 中的位置,从零开始.在此处查看原始回复:https://stackoverflow.com/a/7393477/2423274

    【讨论】:

      【解决方案5】:

      我用它从片段适配器中获取子片段...

      Fragment parent = MainActivity.this.getSupportFragmentManager().findFragmentById(R.id.main_container);
              if (parent instanceof PagerFragment) {
                  // do something with parent
                  Fragment child = ((PagerFragment) f).adapter.getItem(childPosition);
              }
      

      【讨论】:

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