addView() не поддерживается в AdapterView с вложенными фрагментами

После того, как вы попробовали решения, упомянутые в уже существующих ответах на заголовок, та же ошибка, похоже, сохраняется. Я пытаюсь раздуть фрагмент из пользовательского ArrayAdapter, используемого в NavigationBar. Фрагмент, который я пытаюсь раздуть, имеет 2 вложенных фрагмента. Я предполагаю, что это как-то связано с попыткой раздуть LinearLayout, но я не могу заставить эти фрагменты раздуваться. Помощь будет принята с благодарностью.

Вот журнал ошибок

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)

Вот код, начиная с объекта-нарушителя:

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);
            } 
        } 



}

АдаптерВью. Обратите внимание, что при раздувании макета я установил для родительского аргумента View значение null:

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;

     }

}

Активность:

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);
        }
     }

}

Наконец, XML-файлы:

<?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>

И 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>

person Josh Ribeiro    schedule 15.10.2014    source источник
comment
Если вы собираетесь использовать null для корневого представления, не используйте третий параметр. Это не имеет значения. inflater.inflate(layoutResID, null);   -  person Pedro Oliveira    schedule 15.10.2014


Ответы (1)


Я предполагаю, что это как-то связано с попыткой раздуть LinearLayout, но я не могу заставить эти фрагменты раздуваться.

Это не то, что происходит, вы получаете исключение, потому что вы делаете (в основном) две вещи неправильно. Прежде всего, в действии, где вы добавляете фрагмент ContainerFragmentCriteria (через selectItem()), вы используете транзакцию, которая помещает фрагмент в контейнер с R.id.ace_drawer_list. Этот идентификатор соответствует вашей навигации ListView. Это не удастся, потому что вы не можете просто добавить фрагмент в ListView, вам нужен удерживающий контейнер (например, ace_frame FrameLayout (вы, вероятно, хотите добавить туда свой фрагмент вместо списка?!)).

Во-вторых, когда вы используете идентификатор ListView в транзакции фрагмента, платформа (позже) добавит представление фрагмента с addView() в этот контейнер. Непосредственное добавление дочерних элементов через addView() не поддерживается для ListView (и любых подклассов AdapterView). В onCreateView() фрагмента вы раздуваете макет фрагмента, а также добавляете его в параметр контейнера (который является ListView), вместо этого вы не должны этого делать:

View v = inflater.inflate(R.layout.frag_container_criteria, container, false);// false to not add the inflated layout to container
person user    schedule 15.10.2014
comment
Отметив это как ответ. Старая ошибка устранена. Однако теперь я получаю, что указанный ребенок уже имеет родительскую ошибку. Спасибо за понимание по поводу раздувания представления - person Josh Ribeiro; 16.10.2014
comment
@JoshRibeiro Опубликуйте новый вопрос. Трудно сказать, что не так, не видя, как вы изменили код и в какой строке вы фактически получили новое исключение. - person user; 16.10.2014