【问题标题】:How to make a fragment?如何制作片段?
【发布时间】:2016-04-16 13:23:23
【问题描述】:

我以前从未制作过片段,并且一直在努力让它发挥作用。我遵循了一些在线教程,但收效甚微。

我的问题是方法被乱序调用。当 MyActivity 的 XML 文件被加载时,它也会加载片段并调用其 onCreate() 方法。这是在我调用片段的 newInstance() 方法之前完成的,因此 onCreate() 没有它工作所需的参数。

将参数传递给片段的正确方法是什么?因为显然这是行不通的。我已尝试将代码简化为完全相关的内容。

如果你想要它,这是我得到的具体错误:

android.view.InflateException: Binary XML file line #18: Binary XML file line #18: Error inflating class fragment

第 18 行指向片段标签的第一行。

MyFragment.java

public class MyFragment extends Fragment {
        private static final String ARG_PARAM1 = "param";
        private int param

        public static MyFragment newInstance(int param) {
             MyFragment fragment = new MyFragment();
             Bundle args = new Bundle();
             args.putInt(ARG_PARAM1, param);
             fragment.setArguments(args);
             return fragment;
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             this.param = getArguments().getInt(ARG_PARAM1);
             // do stuff with param, but obviously param is not set
             // since constructor is called.
       }

       public interface OnFragmentInteractionListener {
            void onFragmentInteraction(String username);
       }

}

MyActivity.java

public class MyActivity extends AppCompatActivity implements MyFragment.OnFragmentInteractionListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_follower_list); // crashes at this line

        Fragment newFragment = ListOfUsersFragment.newInstance(TypeOfUserList.FOLLOWING, "TestingUsername");
        FragmentTransaction transaction = getFragmentManager().beginTransaction();
        transaction.replace(R.id.my_fragment, newFragment);
        transaction.addToBackStack(null);
        transaction.commit();
    }

    @Override
    public void onFragmentInteraction(String username) {
        // TODO (I'm just trying to get it to run first....
    }
}

activity_my.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activities.MyActivity">

    <!-- The following fragment's onCreate() method is called before newInstance() is called, causing issues. -->
    <fragment
        class ="xyz.mydomain.myproject.fragments.MyFragment"
        android:id="@+id/my_fragment"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:layout_alignParentStart="true"
        android:layout_marginTop="10dp"/>

</RelativeLayout>

【问题讨论】:

  • newInstance 是您的工厂方法,如果您将片段直接放在活动布局中,则永远不会调用它。

标签: java android android-layout android-fragments android-studio


【解决方案1】:

使用 getSupportFragmentManager() 代替 getFragmentManager():

@Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_follower_list); // crashes at this line

    Fragment newFragment = ListOfUsersFragment.newInstance(TypeOfUserList.FOLLOWING, "TestingUsername");
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.fragment_container, newFragment);
    transaction.addToBackStack(null);
    transaction.commit();
}

还要确保在您的 Fragment 类中它继承自 Android 框架支持片段:

import android.support.v4.app.Fragment;

public class MyFragment extents Fragment {
    private static final String ARG_PARAM1 = "param";
    private int param

    public static MyFragment newInstance(int param) {
         MyFragment fragment = new MyFragment();
         Bundle args = new Bundle();
         args.putInt(ARG_PARAM1, param);
         fragment.setArguments(args);
         return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         this.param = getArguments().getInt(ARG_PARAM1);
         // do stuff with param, but obviously param is not set
         // since constructor is called.
   }

   public interface OnFragmentInteractionListener {
        void onFragmentInteraction(String username);
   }

}

也使用这种布局:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activities.MyActivity">
</RelativeLayout>

【讨论】:

  • 仍然抛出同样的错误。一定还有另一个错误,因为那行代码甚至没有运行,它在 setContentView(stuff); 上崩溃了两行。
  • 是的,MyFragment 扩展片段。抱歉,不小心把那部分从代码中遗漏了。
  • 好的,我刚刚编辑了我的答案,尝试使用布局而不将片段放入其中...确保根布局元素的 ID 与您在片段事务中使用的 ID 相同
【解决方案2】:

在 res 文件夹中创建 xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.androiddeveloper.demoapp.MyFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>

这里是java代码。

import android.support.v4.app.Fragment;

public class MyFragment extents Fragment {
    private static final String ARG_PARAM1 = "param";
    private int param

    public static MyFragment newInstance(int param) {
         MyFragment fragment = new MyFragment();
         Bundle args = new Bundle();
         args.putInt(ARG_PARAM1, param);
         fragment.setArguments(args);
         return fragment;
    }
 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_my, container, false);
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         this.param = getArguments().getInt(ARG_PARAM1);
         // do stuff with param, but obviously param is not set
         // since constructor is called.
   }

   public interface OnFragmentInteractionListener {
        void onFragmentInteraction(String username);
   }

}

你的活动的xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activities.MyActivity">
</RelativeLayout>

调用 YourActivity

public class MyActivity extends AppCompatActivity implements MyFragment.OnFragmentInteractionListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_follower_list); // crashes at this line

        Fragment newFragment = ListOfUsersFragment.newInstance(TypeOfUserList.FOLLOWING, "TestingUsername");
        FragmentTransaction transaction = getFragmentManager().beginTransaction();
        transaction.replace(R.id.my_fragment, newFragment);
        transaction.addToBackStack(null);
        transaction.commit();
    }

    @Override
    public void onFragmentInteraction(String username) {
        // TODO (I'm just trying to get it to run first....
    }
}

【讨论】:

    【解决方案3】:

    可能是分号,你没有加分号。

    而不是private int param 应该是private int param;

    【讨论】:

      【解决方案4】:

      使用

      getSupportFragmentManager().beginTransaction(); 
      

      而不是

      getFragmentManager().beginTransaction();
      

      【讨论】:

        猜你喜欢
        • 2018-05-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多