Android-макет, заменяющий представление другим представлением во время выполнения

175

У меня есть xmlфайл -layout main с двумя текстовыми представлениями A / B и представлением C. У меня есть два других xmlфайла -layout option1и option2. Можно ли загрузить option1или option2во время выполнения через Java в C? Если да, то какую функцию я должен использовать?

Кристиан
источник

Ответы:

372

Вы можете заменить любое представление в любое время.

int optionId = someExpression ? R.layout.option1 : R.layout.option2;

View C = findViewById(R.id.C);
ViewGroup parent = (ViewGroup) C.getParent();
int index = parent.indexOfChild(C);
parent.removeView(C);
C = getLayoutInflater().inflate(optionId, parent, false);
parent.addView(C, index);

Если вы не хотите заменять уже существующее представление , а выбираете между option1 / option2 во время инициализации, вы можете сделать это проще: установите android:idдля родительского макета, а затем:

ViewGroup parent = (ViewGroup) findViewById(R.id.parent);
View C = getLayoutInflater().inflate(optionId, parent, false);
parent.addView(C, index);

Вы должны будете установить «index» на правильное значение в зависимости от структуры представлений. Вы также можете использовать ViewStub : добавить ваш вид C как ViewStub, а затем:

ViewStub C = (ViewStub) findViewById(R.id.C);
C.setLayoutResource(optionId);
C.inflate();

Таким образом, вам не придется беспокоиться о значении «index» выше, если вы захотите реструктурировать макет XML.

broot
источник
Должен ли я удалить фрагмент или этот фрагмент также будет удален?
К - Токсичность в СО растет.
3
@KarlMorrison Этот вопрос почти 4 года и не имеет ничего общего с фрагментами. Я предлагаю подать новый вопрос и / или посмотреть, android.app.FragmentTransactionи это replace()метод.
Люпз
Жаль, что ваш ответ слишком сложен - в комментариях - для начинающих Android-программистов :-(
Антонио Сесто
2
@AntonioSesto что слишком сложно? Где ты запутался?
AdamMc331,
@broot Я хочу, чтобы изображения динамически добавлялись в мою линейную планировку, которую я сделал. позже я удаляю некоторые изображения из макета. тогда я хочу восстановить его на своей позиции, откуда я его убрал. означает, что я хочу добавить изображения без удаления родителя ребенка, пожалуйста, помоги мне?
PriyankaChauhan
43

И если вы делаете это очень часто, вы можете использовать ViewSwitcher или ViewFlipper для облегчения замены представления.

Snicolas
источник
Да, если есть вопрос об альтернативных представлениях, тогда лучше использовать представление flipper / switcher
Zoombie
2
@Sail Adi, вы пытались одурачить учебный код ViewSwitcher?
Сниколас
Я знаю, что это старый - но предостережение в том, что ViewSwitcher инициализирует и содержит оба представления в себе (FrameLayout).
Викрам Бодичерла
Это должен быть рекомендуемый ответ. Почему бы просто не использовать готовое хорошо протестированное решение.
3
private void replaceView(View oldV,View newV){
        ViewGroup par = (ViewGroup)oldV.getParent();
        if(par == null){return;}
        int i1 = par.indexOfChild(oldV);
        par.removeViewAt(i1);
        par.addView(newV,i1);
    }
Kaiwalya Rangle
источник
6
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и / или почему он решает проблему, улучшит долгосрочную ценность
ответа
0

в моем случае это работает, oldSensor и newSnsor - oldView и newView:

private void replaceSensors(View oldSensor, View newSensor) {
            ViewGroup parent = (ViewGroup) oldSensor.getParent();

            if (parent == null) {
                return;
            }

            int indexOldSensor = parent.indexOfChild(oldSensor);
            int indexNewSensor = parent.indexOfChild(newSensor);
            parent.removeView(oldSensor);
            parent.addView(oldSensor, indexNewSensor);
            parent.removeView(newSensor);
            parent.addView(newSensor, indexOldSensor);
        }
ch13mob
источник