Динамическое изменение пользовательского интерфейса с помощью слияния и включения тегов в зависимости от клика - PullRequest
2 голосов
/ 18 января 2011

Я новичок в android и программировании в целом, так что будьте проще!

Я создал - возможно, слишком сложный, но он делает то, что я хочу - main.xml с моим макетом, который выглядит примерно так:1003 *

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_scrollview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    >
<LinearLayout
    ...
    >
    <TextView  
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/title"
        android:gravity="center"
    />
    <TableLayout
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:stretchColumns="0"
        >
        <TableRow>
            <TextView/>
            <Spinner/>
        </TableRow>
        <TableRow>
            <TextView/>
            <Spinner/>
        </TableRow>
    </TableLayout>
    <TableLayout
        android:id="@+id/main_tablelayout2"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:stretchColumns="*"
        >
        <include
            android:id="@+id/include"
            layout="@layout/price0"
        />
        <TableRow>
            <TextView/>
            <EditText/>
        </TableRow>
    </TableLayout>
</LinearLayout>
</ScrollView>

Это один из вариантов, которые я пытаюсь включить (price1.xml):

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TableRow>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:text="@string/price1"
        android:gravity="center_vertical"
    />
    <EditText
        android:id="@+id/price1"
    />
</TableRow> 
</merge>

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

Ошибка logcat:

01-18 15:31:42.826: ERROR/AndroidRuntime(719): FATAL EXCEPTION: main
01-18 15:31:42.826: ERROR/AndroidRuntime(719): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at android.view.ViewGroup.addViewInner(ViewGroup.java:1976)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at android.view.ViewGroup.addView(ViewGroup.java:1871)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at android.widget.TableLayout.addView(TableLayout.java:421)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at android.view.ViewGroup.addView(ViewGroup.java:1828)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at android.widget.TableLayout.addView(TableLayout.java:403)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at android.view.ViewGroup.addView(ViewGroup.java:1808)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at android.widget.TableLayout.addView(TableLayout.java:394)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at com.kavi.eta.Calculate$1.onItemSelected(Calculate.java:36)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at android.widget.AdapterView.fireOnSelected(AdapterView.java:871)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at android.widget.AdapterView.access$200(AdapterView.java:42)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at android.widget.AdapterView$SelectionNotifier.run(AdapterView.java:837)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at android.os.Handler.handleCallback(Handler.java:587)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at android.os.Handler.dispatchMessage(Handler.java:92)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at android.os.Looper.loop(Looper.java:123)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at android.app.ActivityThread.main(ActivityThread.java:3647)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at java.lang.reflect.Method.invokeNative(Native Method)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at java.lang.reflect.Method.invoke(Method.java:507)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
01-18 15:31:42.826: ERROR/AndroidRuntime(719):     at dalvik.system.NativeStart.main(Native Method)

Похоже, я делаю код Java неправильно, но не могувыясните, как правильно удалить стандартное включение и заменить его другим макетом:

public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) { 
            int index = formatSpinner.getSelectedItemPosition();
            if (index == 0) {

                TableLayout tl = (TableLayout)findViewById(R.id.main_tablelayout2);
                tl.removeView(findViewById(R.id.include));

                LayoutInflater inflater = getLayoutInflater();
                tl.addView(inflater.inflate(R.layout.price1, tl, true));
            }

Извините за длинный пост, но я искал везде и не могу найти четкий ответ.Надеюсь, это, по крайней мере, послужит хорошим примером ...

Ответы [ 3 ]

0 голосов
/ 12 февраля 2011

На самом деле не нашел правильного решения для этого, но для полноты, это то, что я в конечном итоге делал: я продолжал получать исключение NullPointerException при использовании findViewById для любого из представлений в price1.xml (т.е. включаемый xml).Это по замыслу?Это была проблема, так как мне приходилось динамически добавлять / удалять определенные представления в зависимости от ввода пользователя.

У меня все еще есть тег include в моем main.xml, который я удаляю, просматривая позицию относительно его родителя(опять же, я не мог заставить findViewById работать, но это так же эффективно).Затем я надуваю другой xml-файл на его место, в зависимости от ввода пользователя.

if (position == 0) {
                    LinearLayout ll = (LinearLayout)findViewById(R.id.main_linearlayout);
                    ll.removeViewAt(3);
                    LayoutInflater inflater = getLayoutInflater();
                    ll.addView(inflater.inflate(R.layout.replacement1, null), 3);

                } else if (position == 1) {
                    LinearLayout ll = (LinearLayout)findViewById(R.id.main_linearlayout);
                    ll.removeViewAt(3);
                    LayoutInflater inflater = getLayoutInflater();
                    ll.addView(inflater.inflate(R.layout.replacement2, null), 3);

Я также очистил свой main.xml, чтобы удалить ненужное вложение макетов, и исключил теги слияния и использовал TableLayout в качествекорневые теги для моего включенного XML.Это похоже на мои проблемы с пользовательским интерфейсом (пока!) ...

0 голосов
/ 27 декабря 2013

Вы получите NullPointerException, если попытаетесь использовать findViewById() для элементов, присутствующих во включенном макете.Они не находятся в макете, который добавлен в setContentView(View), поэтому вы должны указать свой тег включения и идентификатор, такой как includeLayout, в следующем фрагменте кода -

<include android:id="@+id/includedLayout" layout="@layout/yourLayout"/>

и найти его с помощью обычного findViewById() вызовите

ViewGroup includedLayout = (ViewGroup)findViewById(R.id.includedLayout);

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

View myVIew = includedLayout.findViewById(R.id.myViewId);

Хотя тема старая, но я думаю, этот ответ поможет будущим читателямнайти именно то, что происходит в их макетах.

0 голосов
/ 19 января 2011

Я тоже новичок, но, возможно, это поможет:

Вы можете попробовать удалить. Я не думаю, что этот тег уместен в этом случае, потому что у вас не будет двух одинаковых макетов, напрямую вложенных в любом случае. Хотя в этом случае я не ожидаю исключения IllegalStateException.

Вы добавляете Views в свой onCreate ()?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...