0

After trying the solutions mentioned in the already existing answers for the title, the same error seems to persist. I'm trying to inflate a Fragment from a custom ArrayAdapter being used in a NavigationBar. The fragment I'm trying to inflate has 2 nested fragments itself. My hunch is that it has something to do with trying to inflate in a LinearLayout, but I can't seem to get these Fragments to inflate. Help would be greatly appreciated.

Here is the error log

10-14 21:22:57.209: E/AndroidRuntime(30555): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.inviscidlabs.schooled/com.inviscidlabs.schooled.ActivityClassEdit}: java.lang.UnsupportedOperationException: addView(View, LayoutParams) is not supported in AdapterView
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.app.ActivityThread.access$800(ActivityThread.java)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.os.Handler.dispatchMessage(Handler.java)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.os.Looper.loop(Looper.java)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.app.ActivityThread.main(ActivityThread.java)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at java.lang.reflect.Method.invokeNative(Native Method)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at java.lang.reflect.Method.invoke(Method.java:515)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at dalvik.system.NativeStart.main(Native Method)
10-14 21:22:57.209: E/AndroidRuntime(30555): Caused by: java.lang.UnsupportedOperationException: addView(View, LayoutParams) is not supported in AdapterView
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.widget.AdapterView.addView(AdapterView.java)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.view.LayoutInflater.inflate(LayoutInflater.java)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.view.LayoutInflater.inflate(LayoutInflater.java)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.view.LayoutInflater.inflate(LayoutInflater.java)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at com.inviscidlabs.schooled.ContainerFragmentCriteria.onCreateView(ContainerFragmentCriteria.java:28)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1504)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:942)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1484)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:571)
10-14 21:22:57.209: E/AndroidRuntime(30555):    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java)

Here is the code, starting with the offending entity:

public class ContainerFragmentCriteria extends Fragment{



    private FragmentManager fm;

    private boolean insertMode;

    //=====================ACTIVITY LIFECYCLE==============================
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
                View v = inflater.inflate(R.layout.frag_container_criteria, container);
                return v;   
            }


        @Override
        public void onCreate(Bundle savedInstanceState){
            super.onCreate(savedInstanceState);

            //Instantiate Fragments, set Arguments
            FragmentCriteriaEdit fCrE= new FragmentCriteriaEdit();
            FragmentCriteriaList fCrL = new FragmentCriteriaList();

            Bundle fCritListArguments = new Bundle();
            fCritListArguments.putBoolean(CM.BKEY_INSERTMODE, insertMode);
            //Begin the Transaction
            fm=getChildFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            ft.add(R.id.fccr_rootLayout, fCrE, FragmentCriteriaEdit.sTag);
            ft.add(R.id.fccr_rootLayout, fCrL, FragmentCriteriaList.sTag);
            ft.commit();

        }

        @Override
        public void onStart() {
            super.onStart();
        //Get our arguments
            Bundle args = getArguments();
            if(args!=null){
                insertMode=args.getBoolean(CM.BKEY_INSERTMODE);
            }
        }

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

            try { 
                Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
                childFragmentManager.setAccessible(true);
                childFragmentManager.set(this, null);

            } catch (NoSuchFieldException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } 
        } 



}

The AdapterView. Notice I set the parent View argument to null when inflating the layout:

public class ClassEditDrawerAdapter extends ArrayAdapter<ClassEditDrawerItem>{

    Context ctx;
    List<ClassEditDrawerItem> itemList;
    int layoutResID;

    public ClassEditDrawerAdapter(Context context, int layoutResourceID, List<ClassEditDrawerItem> items){
        super(context, layoutResourceID, items);
        ctx=context;
        layoutResID=layoutResourceID;
        itemList=items;
    }

    //An Effective ViewHolder, but for this Array!
    private class DrawerItemHolderThing{
        TextView itemName;
    }


     @Override
     public View getView(int position, View convertView, ViewGroup parent) {
         DrawerItemHolderThing bobSagget;
         View v = convertView;

         if(v==null){
             Log.d("adapter", "v was null");
             LayoutInflater inflater = ((Activity) ctx).getLayoutInflater();
             bobSagget= new DrawerItemHolderThing();

             v=inflater.inflate(layoutResID, null, false);

             bobSagget.itemName=((TextView) v.findViewById(R.id.item_basicItem));
             v.setTag(bobSagget);
         } else {
             bobSagget = (DrawerItemHolderThing) v.getTag();
         }


         ClassEditDrawerItem drawerItem = (ClassEditDrawerItem) this.itemList.get(position);
         if(bobSagget.itemName==null){Log.e("Adapter", "no TextView");}
         bobSagget.itemName.setText(drawerItem.getItemName());

         return v;

     }

}

The Activity:

public class ActivityClassEdit extends FragmentActivity{

//Variables
    //Fragments
    private ContainerFragmentCriteria frag_Criteria;


    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;


    //used as the effective ArrayAdapter for the NavigationDrawer
    private ClassEditDrawerAdapter mNavAdapter;
    private CharSequence sDrawerTitle;
    private CharSequence sTitle;

    //Serves as List of Strings to populate Nav Drawer's ListView of options
    List<ClassEditDrawerItem> navOptions;

     @Override
     protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);

           setContentView(R.layout.activity_classedit);

           //Initialize List
           navOptions= new ArrayList<ClassEditDrawerItem>();
           sTitle=sDrawerTitle=getTitle();

           mDrawerLayout = (DrawerLayout) findViewById(R.id.ace_drawer);
           mDrawerList=(ListView) findViewById(R.id.ace_drawer_list);

           navOptions.add(new ClassEditDrawerItem("Criteria", R.drawable.ic_launcher));

           mNavAdapter = new ClassEditDrawerAdapter(this, R.layout.item_basic, navOptions);
           mDrawerList.setAdapter(mNavAdapter);
           //Set ListView onClickListener
           mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

           //Set up the home button to open the nav drawer
           getActionBar().setDisplayHomeAsUpEnabled(true);
           getActionBar().setHomeButtonEnabled(true);

           mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                   R.drawable.ic_launcher, R.string.hello_world,
                   R.string.name);

           mDrawerLayout.setDrawerListener(mDrawerToggle);

           //Select first item by default
           if(savedInstanceState==null){
               SelectItem(0);
           }




     }

     @Override
     public void setTitle(CharSequence title) {
           sTitle = title;
           getActionBar().setTitle(sTitle);
     }

     @Override
     protected void onPostCreate(Bundle savedInstanceState) {
           super.onPostCreate(savedInstanceState);
           // Sync the toggle state after onRestoreInstanceState has occurred.
           mDrawerToggle.syncState();
     }

     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
           // The action bar home/up action should open or close the drawer.
           // ActionBarDrawerToggle will take care of this.
           if (mDrawerToggle.onOptionsItemSelected(item)) {
                 return true;
           }

           return false;
     }

     @Override
     public void onConfigurationChanged(Configuration newConfig) {
           super.onConfigurationChanged(newConfig);
           // Pass any configuration change to the drawer toggles
           mDrawerToggle.onConfigurationChanged(newConfig);
     }

     //What to do when Item is Selected
     public void SelectItem(int position){
         FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

         switch(position){
         //Class Edit
         case 0: 
             if(frag_Criteria==null){
                 frag_Criteria = new ContainerFragmentCriteria();
             }
             transaction.replace(R.id.ace_drawer_list, frag_Criteria);
             transaction.commit();
             break;


         }

      Toast.makeText(this, String.valueOf(position), Toast.LENGTH_LONG).show();
     }


     private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                   long id) {
                SelectItem(position);
        }
     }

}

Finally, the XMLs:

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


</LinearLayout>
</RelativeLayout>

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

    <LinearLayout android:id="@+id/item_ace_itemlayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:orientation="vertical"
        android:background="?android:attr/activatedBackgroundIndicator"
        >
        <LinearLayout

                  android:layout_width="fill_parent"
                  android:layout_height="wrap_content"
                  android:minHeight="55dp"
                 >

                  <ImageView
                      android:id="@+id/drawer_icon"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      />

                  <TextView
                      android:id="@+id/drawer_itemName"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:textAppearance="?android:attr/textAppearanceLarge"

                       />
              </LinearLayout>

        <View
      android:layout_width="match_parent"
      android:layout_height="1dp"
      android:layout_marginBottom="1dp"
      android:layout_marginTop="1dp"
      android:layout_marginLeft="10dp"
      android:layout_marginRight="10dp"
      android:background="#DADADC"

       ></View>

    </LinearLayout>


</RelativeLayout>

And the Activity's XML:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/ace_drawer" >

    <FrameLayout android:id="@+id/ace_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

    <ListView 
        android:id="@+id/ace_drawer_list"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        />


</android.support.v4.widget.DrawerLayout>
user
  • 86,916
  • 18
  • 197
  • 190
Josh Ribeiro
  • 1,349
  • 3
  • 18
  • 28
  • If you are going to use null for the root view don't use the third parameter. It's irrelevant. `inflater.inflate(layoutResID, null);` – Pedro Oliveira Oct 15 '14 at 10:10

1 Answers1

2

My hunch is that it has something to do with trying to inflate in a LinearLayout, but I can't seem to get these Fragments to inflate.

That is not what's happening, you get the exception because you're doing(mainly) two things wrong. First of all, in the activity where you add the ContainerFragmentCriteria fragment(through selectItem()) you use a transaction that would place the fragment in a container with the R.id.ace_drawer_list. That id corresponds to your navigation ListView. This will fail because you can't just add a fragment to a ListView, you need a holding container(like the ace_frame FrameLayout(you probably want to add your fragment there instead of the list?!)).

Secondly, when you use the id of the ListView in the fragment transaction, the framework will(at a later point) add the fragment's view with addView() to that container. Directly adding children through addView() is not supported for a ListView(and any subclasses of AdapterView). In the fragment's onCreateView() you inflate the fragment layout and you also add it to the container parameter(which is the ListView), you shouldn't do this, instead:

View v = inflater.inflate(R.layout.frag_container_criteria, container, false);// false to not add the inflated layout to container
user
  • 86,916
  • 18
  • 197
  • 190
  • Marking this as the answer. The old error is alleviated. However, I am now getting a "Specified child already has a parent error". Thanks for the insight on inflating the view – Josh Ribeiro Oct 16 '14 at 00:43
  • @JoshRibeiro Post a new question. It's hard to tell what's wrong without seeing how you modified the code and at what line you actual get the new exception. – user Oct 16 '14 at 08:36