Android ScrollView может содержать только одного прямого ребенка - PullRequest
7 голосов
/ 30 июня 2011

У меня есть прослушиватель onclick из галереи, который должен очистить все строки в табличном представлении, а затем добавить строку / строки в табличное представление в представлении прокрутки. Фрагмент должен меняться при каждом нажатии кнопки.

Однако я получаю: java.lang.IllegalStateException: ScrollView может содержать только одного прямого дочернего элемента.

слушатель кнопки myactivity

            TrackerFragment tf = (TrackerFragment) getFragmentManager().findFragmentById(R.id.tracker1);
            tf = TrackerFragment.newInstance(listOfList.get(id).get(position));

            fragmentTransaction.add(R.id.tracker1, tf);
            fragmentTransaction.commit();
            t1 = true; //being used
            getFragmentManager().executePendingTransactions();

фрагмент трекера

public class TrackerFragment extends Fragment
{
    private Dish dish;

    public static TrackerFragment newInstance(Serializable dish) 
    {
        TrackerFragment tf = new TrackerFragment();

        Bundle args = new Bundle();
        args.putSerializable("dish", dish);
        tf.setArguments(args);

        return tf;
    }

    public static TrackerFragment newInstance(Bundle bundle)
    {
        Dish dish = (Dish) bundle.getSerializable("dish");
        return newInstance(dish);
    }

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

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

        TableLayout tableLayout = (TableLayout) v.findViewById(R.id.tracker_layout);
        tableLayout.removeAllViews();

        if (dish != null)
        {   
            //display others

            //display subsystem stuff
            for (int i = 0; i < dish.getSubsystems().size(); i++)
            {
                TableRow tableRow = new TableRow(v.getContext());
                tableRow.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));

                TextView tv = new TextView(v.getContext());
                tv.setText(dish.getSubsystems().get(i).getConnFuncAddr());

                tableRow.addView(tv);

                tableLayout.addView(tableRow);
            }
        }
        else
        {
            TableRow tableRow = new TableRow(v.getContext());
            tableRow.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));

            TextView tv = new TextView(v.getContext());
            tv.setText("Click on image to view more data");

            tableRow.addView(tv);

            tableLayout.addView(tableRow);
        }

        return v;
    }
}

main.xml

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

    <!-- Trackers -->
    <LinearLayout
        android:layout_height="fill_parent"
        android:layout_width="300dp"
        android:layout_weight="1"
        android:orientation="vertical">

        <fragment 
            android:name="android.gallery.TrackerFragment"
            android:id="@+id/tracker1"
            android:layout_height="500dp"
            android:layout_width="300dp"
            android:layout_weight="1">
        </fragment>

    </LinearLayout>

    <!-- Gallery -->
    <LinearLayout
        android:layout_height="fill_parent"
        android:layout_width="600dp"
        android:layout_weight="1"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="245dp">

            <Gallery 
                android:id="@+id/galleryid0"
                android:layout_width="fill_parent" 
                android:layout_height="match_parent"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="245dp">

            <Gallery 
                android:id="@+id/galleryid1"
                android:layout_width="fill_parent" 
                android:layout_height="match_parent"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="245dp">

            <Gallery 
                android:id="@+id/galleryid2"
                android:layout_width="fill_parent" 
                android:layout_height="match_parent"/>

            </LinearLayout>

        </LinearLayout>

</LinearLayout>

tracker.xml

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

    <TableLayout 
        android:layout_width="match_parent" 
        android:layout_height="match_parent"
        android:id="@+id/tracker_layout">

    </TableLayout>

</ScrollView>

Кто-нибудь знает, что не так? Я предполагаю, что я добавляю строку таблицы в представление прокрутки, а не в таблицу, однако я не вижу, где я делаю это неправильно в моем коде.

Ответы [ 8 ]

5 голосов
/ 11 января 2012

На самом деле, вы не можете иметь такие вещи, как:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
android:id="@+id/widget27"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffffff"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<TableLayout
android:id="@+id/layoutOption"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffffff"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
>
<ImageView
android:id="@+id/logoImmoweb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/logoimmoweb"
android:layout_gravity="top"
/>
 ...
</TableLayout>
</ScrollView>

, но если у вас есть дополнительный элемент вне таблицы, он вылетает с примером java.lang.IllegalStateException: ScrollView can host only one direct child

<ScrollView
android:id="@+id/widget27"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffffff"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<ImageView
android:id="@+id/logoImmoweb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/logoimmoweb"
android:layout_gravity="top"
/>
<TableLayout
android:id="@+id/layoutOption"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffffff"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
>
...
</TableLayout>
</ScrollView>

Надеюсь, эта помощь.

4 голосов
/ 03 ноября 2012

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

Просто оберните Scrollview в своймакет tracker.xml с RelativeLayout, и вы должны хорошо идти

3 голосов
/ 05 октября 2014

Вы должны добавить LinearLayout в ScrollView, он будет работать.

2 голосов
/ 17 ноября 2013

Другая возможность заключается в том, что закрывающий элемент не совпадает.То есть.

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="wrap_content">
    <LinearLayout ...>
        ...
    </LinearLayout>
</LinearLayout>

Ошибка в последней строке.

1 голос
/ 30 июня 2011

Гм ... не помещайте несколько представлений в представление прокрутки. Поместите в него единое представление, которое является тем типом макета, который вам нужен для нескольких представлений - TableLayout, FrameLayout и т. Д.

0 голосов
/ 19 июля 2018

Я страдаю от этой проблемы на прошлой неделе, а затем найду наилучший возможный ответ на эту проблему.

Scrollview может содержать только одного прямого потомка

0 голосов
/ 16 августа 2015

Попробуйте использовать <FrameLayout> вместо <fragment> в вашем main.xml

Так что вместо

<fragment 
    android:name="android.gallery.TrackerFragment"
    android:id="@+id/tracker1"
    android:layout_height="500dp"
    android:layout_width="300dp"
    android:layout_weight="1">
</fragment>

использование

<FrameLayout
    android:id="@+id/tracker1"
    android:layout_height="500dp"
    android:layout_width="300dp"
    android:layout_weight="1"
/>

Это решило аналогичную проблему с ScrollView, где я заменял фрагмент из действия на:

getSupportFragmentManager().beginTransaction()
    .replace(R.id.details_container, new DetailsFragment(), DETAILFRAGMENT_TAG)
    .commit();
0 голосов
/ 22 августа 2011

изменить (2-й ответ):

Я играл с кодом и до сих пор не уверен, ПОЧЕМУ это происходит, определенно что-то не так в диспетчере фрагментов, когда он обменивается фрагментами (замените (resId, фрагмент))

В моем фрагменте onCreateView был такой код:

    View view = inflater.inflate(R.layout.post_fragment, null, false);
    if (item == null)
        return view;

    return BuildView(view);

post_fragment - это пустой холст с 1 ScrollView, 1 LinearLayout внутри и некоторыми другими ViewGroups внутри него. Это делается для загрузки пустого холста при 1-й загрузке (элемент равен нулю), а во 2-й раз при вводе пользователем получаются фактические данные для показа.

по некоторым причинам, которые мне не известны, как видно из logcat, FragmentManagerImpl.moveToState вызывал ScrollView.AddChild, вызывая ошибку.

Теперь я изменил свои фрагменты на CreateView на:

    if (item == null)
        return inflater.inflate(R.layout.empty, null, false);

    View view = inflater.inflate(R.layout.post_fragment, null, false);
    return BuildView(view);

так что «пустой» холст - это FrameLayout, на котором ничего нет, и теперь все работает счастливо. Я уверен, что это звучит как какая-то странная ошибка в реальной структуре фрагментов, но это обходной путь.

1-й ответ:

Raptrex, насколько я вижу. Да, этот макет таблицы - единственный ребенок, который есть у вашего scrowview. У меня точно такая же проблема, и я очень расстроен, пытаясь ее решить.

Из LogCat / Debug, кажется, что в диспетчере фрагментов есть что-то, что вызывает, и .AddView (просмотр) в моем ScrollView (проверьте журнал), это зависит от того, как я изменяю свой XML-макет, я получаю эту ошибку или нет что, скажем так, звучит довольно абсурдно!

Есть идеи как? Почему? Что? Я слушаю ...

FATAL EXCEPTION: main
java.lang.IllegalStateException: ScrollView can host only one direct child
at android.widget.ScrollView.addView(ScrollView.java:219)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:787)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:977)
at android.app.BackStackRecord.run(BackStackRecord.java:638)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1309)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:398)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:132)
at android.app.ActivityThread.main(ActivityThread.java:4123)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:491)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
at dalvik.system.NativeStart.main(Native Method)
...