【问题标题】:How to pass Arguments to Fragment from Activity如何将参数从 Activity 传递给 Fragment
【发布时间】:2015-03-03 10:32:15
【问题描述】:

我有一个通过采用者类实例化和填充片段的活动。我想将值/对象传递给这个 Fragment 采用者类,以便我可以指定布局等。

我曾尝试使用 setArgument 方法传递捆绑包,但我的代码失败了,不知道为什么。据我了解,我可以在采用者类的 onCreate 方法中收集捆绑包。我看到在注释代码之后立即正确设置了参数,但可惜在那之后它崩溃了,我不明白为什么。如果我删除捆绑代码,它不会崩溃。 :(

下面是我的代码,有人知道我应该把捆绑代码放在哪里,注释掉吗?

public class LoginScreen extends ActionBarActivity {
    private final String ARG_SELECTED_LAYOUT_ID = "selectedLayoutId";
private final int DEFAULT_LAYOUT = R.layout.layout_list;

private int mSelectedLayoutId;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);

    ActionBar actionBar = getSupportActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setDisplayShowHomeEnabled(false);

    mSelectedLayoutId = DEFAULT_LAYOUT;
    if (savedInstanceState != null) {
        mSelectedLayoutId = savedInstanceState.getInt(ARG_SELECTED_LAYOUT_ID);
    }

    addLayoutTab(
            actionBar, R.layout.layout_list, R.drawable.ic_list, "list");
    addLayoutTab(
            actionBar, R.layout.layout_grid, R.drawable.ic_grid, "grid");
    addLayoutTab(
            actionBar, R.layout.layout_staggered_grid, R.drawable.ic_staggered, "staggered");
    addLayoutTab(
            actionBar, R.layout.layout_spannable_grid, R.drawable.ic_spannable, "spannable");
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt(ARG_SELECTED_LAYOUT_ID, mSelectedLayoutId);
}

private void addLayoutTab(ActionBar actionBar, int layoutId, int iconId, String tag) {
    ActionBar.Tab tab = actionBar.newTab()
            .setText("")
            .setIcon(iconId)
            .setTabListener(new TabListener(layoutId, tag));
    actionBar.addTab(tab, layoutId == mSelectedLayoutId);
}

public class TabListener implements ActionBar.TabListener {
    private LayoutFragment mFragment;
    private final int mLayoutId;
    private final String mTag;


    public TabListener(int layoutId, String tag) {
        mLayoutId = layoutId;
        mTag = tag;
    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
        mFragment = (LayoutFragment) getSupportFragmentManager().findFragmentByTag(mTag);



        if (mFragment == null) {
            mFragment = (LayoutFragment) LayoutFragment.newInstance(mLayoutId);
            ft.add(R.id.content, mFragment, mTag);

        } else {
            ft.attach(mFragment);
        }


        /*
            Bundle bundle = new Bundle();
            bundle.putInt("noTiles", 4);
            mFragment.setArguments(bundle);           
        */

        mSelectedLayoutId = mFragment.getLayoutId();
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
        if (mFragment != null) {
            ft.detach(mFragment);
        }
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
    }
}

}

Logcat

03-03 11:56:53.675  32507-32507/weebuns.predictionking E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: weebuns.predictionking, PID: 32507
    java.lang.RuntimeException: Unable to start activity ComponentInfo{weebuns.predictionking/weebuns.predictionking.LoginScreen}: java.lang.NullPointerException: Attempt to invoke virtual method 'void weebuns.predictionking.LayoutFragment.setArguments(android.os.Bundle)' on a null object reference
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void weebuns.predictionking.LayoutFragment.setArguments(android.os.Bundle)' on a null object reference

【问题讨论】:

  • 未注释代码出现的 logcat 错误是什么?
  • 创建实例时发送包:mFragment = (LayoutFragment) LayoutFragment.newInstance(mLayoutId,YourBundle);
  • i get Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void weebuns.predictionking.LayoutFragment.setArguments(android.os.Bundle)' on an null object reference error

标签: android android-fragments fragment bundle


【解决方案1】:

要将参数传递给您的片段,建议创建一个公共静态方法来实例化您的片段,例如:

public static MyFragment newInstance(String firstArg) {
        MyFragment f = new MyFragment ();
        Bundle args = new Bundle();
        args.putString("ARG1", firstArg);
        f.setArguments(args);
        return f;
    }

然后在onCreateView() 方法中检索您的参数,例如:

String arg = getArguments().getString("ARG1");

使用静态方法在其他片段或活动中使用您的参数实例化一个新片段,例如:

MyFragment f = MyFragment.newInstance(myArg);

【讨论】:

    【解决方案2】:

    没有看到logcat很难说,但你肯定错过了在FragmentTransaction上调用commit()方法。还记得在调用ft.commit()之前为片段设置参数。

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
        mFragment = (LayoutFragment) getSupportFragmentManager().findFragmentByTag(mTag);
    
        if (mFragment == null) {
            Bundle bundle = new Bundle();
            bundle.putInt("noTiles", 4);
            mFragment = (LayoutFragment) LayoutFragment.newInstance(mLayoutId);
            mFragment.setArguments(bundle);
            //ft.add(R.id.content, mFragment, mTag).commit();
            ft.add(R.id.content, mFragment, mTag);
    
        } else {
            ft.attach(mFragment);
        }
    
        mSelectedLayoutId = mFragment.getLayoutId();
    }
    

    【讨论】:

    • 我收到错误:原因:java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“void weebuns.predictionking.LayoutFragment.setArguments(android.os.Bundle)”跨度>
    • 取得进展.....新问题:进程:weebuns.predictionking,PID:19902 java.lang.RuntimeException:无法启动活动 ComponentInfo{weebuns.predictionking/weebuns.predictionking.LoginScreen}: java.lang.IllegalStateException:已调用提交。我看不到它在哪里提交 tbh
    • 所以,commit() 似乎确实由 Activity 自动调用,因为它是 onTabSelected() 的参数。试试我发布的新代码。
    • :( 回到原来的问题.... ...AndroidRuntime: 致命异常:主进程:weebuns.predictionking,PID:26186 java.lang.RuntimeException:无法启动活动 ComponentInfo{.. ..LoginScreen}:android.content.res.Resources$NotFoundException:com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 处的资源 ID #0x0 原因:android.content.res.Resources$NotFoundException : 资源 ID #0x0
    • 在这种情况下,问题可能出在片段中。你如何处理传递给它的参数?
    【解决方案3】:

    在你的活动中

    Bundle args = new Bundle();
    args.putString("Menu", "Your String");
    Fragment detail = new FragmeantOne();
    detail.setArguments(args);
    FragmentManager fragmentManager = getFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.content_frame, detail).commit();
    

    在你的 Fragment.. 在 onCreateView()

    String menu = getArguments().getString("Menu");
    someTextView.setText(menu);
    

    【讨论】:

      【解决方案4】:

      您可以使用 Bundle 将数据从 Activity 传输到 Fragment,或者将数据从 Fragment 传输到 Fragment。

      Bundle bundle = new Bundle();
      DisplayDataList fragment = new DisplayDataList();
      bundle.putString("listitem", "Buyer,Seller");
                  fragment.setArguments(bundle);
      
                  getFragmentManager().beginTransaction().replace(
                          R.id.frame_container, fragment).addToBackStack(null).commit();
      

      您想在DisplayDataList Fragment 类中接收该捆绑包 i.w 的位置。你必须使用getArguments() 方法。

      显示数据列表

       Bundle bundle = getArguments();
                  String getdata = bundle.getString("listitem");
                  System.out.println("Data got-->>> " + getdata);
      

      希望这会对你有所帮助。

      【讨论】:

      • Thx 但我有那个代码(或尝试它)在那里并且它破坏了它,这个代码应该去哪里?我的捆绑代码正确吗?有关已注释掉的问题代码,请参阅我发布的代码。你能把你的代码放在我的上下文中吗 - 类名等,这样我就可以更好地看到它的去向,因为我的 afaics 至少应该不会使应用程序崩溃。
      • 在替换或添加新片段之前使用捆绑代码,并确保在替换代码中传递带有片段对象的捆绑。试试这个 LayoutFragment mFragment = new LayoutFragment();捆绑捆绑 = 新捆绑(); bundle.putInt("noTiles", 4); mFragment.setArguments(bundle); if (mFragment == null) { mFragment = (LayoutFragment) LayoutFragment.newInstance(mLayoutId); ft.add(R.id.content, mFragment, mTag); } 其他 { ft.attach(mFragment); }
      • 我收到以下错误:原因:java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法 'void weebuns.predictionking.LayoutFragment.setArguments(android.os.Bundle)'
      【解决方案5】:

      您可以使用 Bundle 在 Activity 和 Fragment/Dialog Fragment 之间传输数据

      将数据从您的 Activity 发送到 Fragment() -> onClickBtn()

      val f = PaymentBottomSheet()
                  val bundle = Bundle()
                  bundle.putString("coins", walletBinding.edCoins.text.toString())
                  bundle.putString("method", getJsonData()[adapter.selected].method)
                  bundle.putString("name", walletBinding.edNickName.text.toString())
                  bundle.putString("acc", walletBinding.edAccountId.text.toString())
                  f.arguments = bundle
                  f.show(supportFragmentManager, f.tag)
      

      从您的活动中检索数据(您的片段代码如下所示)onCreateView()

       val bundle = Bundle(arguments)
          coins = bundle.getString("coins")
          method = bundle.getString("method")
          name = bundle.getString("name")
          id = bundle.getString("acc")
      
          Timber.d("Coins $coins, Method $method, Name $name, ID $id")
      

      谢谢

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多