Android布局:在运行时用另一个视图替换视图

188
我有一个名为main的xml-layout文件,其中包含两个文本视图A/B和一个视图C。我还有另外两个名为option1和option2的xml-layout文件。是否可以在运行时通过Java将option1或option2加载到C中?如果可以的话,需要使用哪个函数?
4个回答

386

您可以随时替换任何视图。

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

如果你不想替换已有的View,而是在初始化时选择选项1/选项2,那么你可以更轻松地做到这一点:为父布局设置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();

这样,如果您想重新构建XML布局,就不必担心上面的“索引”值了。


4
这个问题已经快四年了,与碎片无关。我建议您提出一个新问题和/或查看android.app.FragmentTransaction以及它的replace()方法。 - lupz
2
@AntonioSesto 什么太复杂了?你在哪里感到困惑了? - AdamMc331
@broot 我想动态地向我的线性布局中添加图片。稍后,我会从布局中删除一些图像。然后我想将其恢复到我删除的位置。也就是说,我想在不删除子元素的情况下添加图像。你能帮我吗? - PriyankaChauhan
我更改了方向后,它回到了旧视图。除了实现viewflipper/switcher之外,有什么方式可以解决这个错误? - pete
@pete 这不是一个 bug。旋转后,活动会被销毁并重新创建 - 因此您的 XML 再次用于重新创建布局 - 因此您必须再次操纵布局以满足您的需求。我建议您编写一个方法来操作视图,并在每次 onCreate() 后调用该方法。 - Someone Somewhere
显示剩余2条评论

44

是的,如果涉及到替代视图的问题,那么使用视图翻转器/切换器会更好。 - Zoombie
2
@Shail Adi,你尝试过在谷歌上搜索ViewSwitcher教程代码吗? - Snicolas
我知道这很老 - 但是需要注意的是,ViewSwitcher在自身(FrameLayout)中初始化并保存两个视图。 - Vikram Bodicherla
这应该是推荐的答案。为什么不使用一个现成的经过充分测试的解决方案呢? - user9599745

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

7
虽然这段代码可能回答了问题,但提供有关它如何以及/或为什么解决问题的额外背景信息将提高答案的长期价值。 - frobinsonj

0

在我的情况下,它可以工作,oldSensor和newSensor - 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);
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接