Ramprasad
Ramprasad

Reputation: 8071

Error inflating class fragment error

I have a Main activity with two master detail Fragments.I am trying to implement like "Multiple fragments, multiple activities" method.

layout folder activity_main.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=".MoneyActivity"
    android:id="@+id/fragment_container" >
 <fragment class="com.mysite.money.AFragment"
              android:id="@+id/AFragment"
              android:layout_width="match_parent"
              android:layout_height="match_parent"/>
 </FrameLayout>

layout-large folder activity_main.xml

<LinearLayout 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=".MoneyActivity"
    android:id="@+id/fragment_container"
    android:orientation="horizontal" >


   <fragment class="com.mysite.money.AFragment"
              android:id="@+id/AFragment"
              android:layout_width="@dimen/action_bar_title_text_size"
              android:layout_height="match_parent"/>

   <fragment class="com.mysite.money.BFragment"
              android:id="@+id/BFragment"
              android:layout_width="match_parent"
              android:layout_height="match_parent"/>


 </LinearLayout>

I got error like below(when run on tablet-layout-large):

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mysite.money/com.mysite.money.MoneyActivity}: android.view.InflateException: Binary XML file line #15: Error inflating class fragment

I checked class names of fragments properly.

I think i got error BFragment

BFragment: public class BFragment extends SherlockFragment {

    String selectedItem="";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        int size = getArguments().size();
        if(size>0)
        {
            selectedItem = getArguments().getString("position").toString();
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        TextView textView=new TextView(inflater.getContext());
        textView.setText("Selected Item->"+selectedItem);
        return textView;
    }

}

OnItemSelected in my mainActivity(Associated with fragment A)

**@Override
    public void onItemSelected(String id) {
          BFragment displayFrag = (BFragment) getSupportFragmentManager().findFragmentById(new BFragment().getId());
        if (displayFrag == null) {
            // DisplayFragment (Fragment B) is not in the layout (handset layout),
            // so start DisplayActivity (Activity B)
            // and pass it the info about the selected item
            Intent intent = new Intent(this, BActivity.class);
            intent.putExtra("position", id);
            Log.i("innodea", "position->"+id);
            startActivity(intent);

        } else {
            // DisplayFragment (Fragment B) is in the layout (tablet layout),
            // so tell the fragment to update
            //displayFrag.updateContent(id);
        }
    }**

AFragment:

public class AFragment extends SherlockListFragment {

    private View inflate;
    private Callbacks mCallbacks = sDummyCallbacks;
    private int mActivatedPosition= ListView.INVALID_POSITION;
    private static final String STATE_ACTIVATED_POSITION = "activated_position";

    public interface Callbacks {
        public void onItemSelected(String id);
    }

    /**
     * A dummy implementation of the {@link Callbacks} interface that does
     * nothing. Used only when this fragment is not attached to an activity.
     */
    private static Callbacks sDummyCallbacks = new Callbacks() {
        public void onItemSelected(String id) {
        }
    };

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        // Activities containing this fragment must implement its callbacks.
        if (!(activity instanceof Callbacks)) {
            throw new IllegalStateException(
                    "Activity must implement fragment's callbacks.");
        }

        mCallbacks = (Callbacks) activity;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setListAdapter(new ArrayAdapter<DummyContent.DummyItem>(getActivity(),android.R.layout.simple_list_item_activated_1,android.R.id.text1, DummyContent.ITEMS));
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        // Restore the previously serialized activated item position.
        if (savedInstanceState != null
                && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
            setActivatedPosition(savedInstanceState
                    .getInt(STATE_ACTIVATED_POSITION));
        }
    }



    @Override
    public void onDetach() {
        super.onDetach();

        // Reset the active callbacks interface to the dummy implementation.
        mCallbacks = sDummyCallbacks;
    }

    @Override
    public void onListItemClick(ListView listView, View view, int position,long id) {
        super.onListItemClick(listView, view, position, id);

        // Notify the active callbacks interface (the activity, if the
        // fragment is attached to one) that an item has been selected.
        mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (mActivatedPosition != ListView.INVALID_POSITION) {
            // Serialize and persist the activated item position.
            outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
        }
    }

    /**
     * Turns on activate-on-click mode. When this mode is on, list items will be
     * given the 'activated' state when touched.
     */
    public void setActivateOnItemClick(boolean activateOnItemClick) {
        // When setting CHOICE_MODE_SINGLE, ListView will automatically
        // give items the 'activated' state when touched.
        getListView().setChoiceMode(
                activateOnItemClick ? ListView.CHOICE_MODE_SINGLE
                        : ListView.CHOICE_MODE_NONE);
    }

    private void setActivatedPosition(int position) {
        if (position == ListView.INVALID_POSITION) {
            getListView().setItemChecked(mActivatedPosition, false);
        } else {
            getListView().setItemChecked(position, true);
        }

        mActivatedPosition = position;
    }

}

Upvotes: 4

Views: 3595

Answers (4)

Vaibhav Aggarwal
Vaibhav Aggarwal

Reputation: 61

Adding Unique ID for the Static Fragment is required. I found it after carefully looking in Logs for error. CLick on below link to see error details:

Error Inspection in logs

No need for FragmentActivity as suggested in many posts. AppCompatActivity is fine. So, code like below works just fine.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:text="Customize your Android: " />

    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.example.android.android_me.ui.MasterListFragment"
        android:id="@+id/StaticFragment"/>

</LinearLayout>

Upvotes: 1

Yash Ojha
Yash Ojha

Reputation: 818

You need to import the Fragment class from android.support.v4.app.Fragment instead of android.app.Fragment.

import android.support.v4.app.Fragment;

And in the XML file of the activity where you intend to use this fragment, you need to use:

        <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/map_fragment"
        name="yourpackagname.yourfragmentclass"/>
        //package name here, is the name of folder which is in java directory.

Upvotes: 0

Grigori A.
Grigori A.

Reputation: 2608

The exception android.view.InflateException: Binary XML file line: #... Error inflating class fragment might happen if you manipulate with getActivity() inside your fragment before onActivityCreated() get called. In such case you receive a wrong activity reference and can't rely on that.

For instance the next pattern is wrong:

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

    Button button = getActivity().findViewById(R.id...);
    button.setOnClickListener(...); - another problem: button is null

    return view;
}

Upvotes: 2

Marcin Orlowski
Marcin Orlowski

Reputation: 75619

Your fragment code is most likely broken and simply crashes on creation which ends in failure of inflation. Plant breakpoints on each fragment onCreateView() and related methods called in during fragment creation or try to instantiate the fragment by hand (new AFragment()) and attaching it to The Layout to see where exactly if fails.

Upvotes: 0

Related Questions