Diseño de Android que reemplaza una vista con otra vista en tiempo de ejecución

175

Tengo un xmlarchivo principal de distribución con dos vistas de texto A / B y una vista C. Tengo otros dos xmlarchivos de distribución option1y option2. ¿Es posible cargar cualquiera option1o option2en tiempo de ejecución a través de Java en C? Si es así, ¿qué función debo usar?

cristiano
fuente

Respuestas:

372

Puede reemplazar cualquier vista en cualquier momento.

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

Si no desea reemplazar la Vista ya existente , pero elige entre la opción1 / opción2 en el momento de la inicialización, entonces podría hacerlo más fácilmente: configure el android:iddiseño primario y luego:

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

Deberá establecer el "índice" en el valor adecuado según la estructura de las vistas. También puede usar un ViewStub : agregue su vista C como ViewStub y luego:

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

De esa manera, no tendrá que preocuparse por el valor de "índice" anterior si desea reestructurar su diseño XML.

broot
fuente
¿Debo eliminar el fragmento o también se eliminará?
K - La toxicidad en SO está creciendo.
3
@KarlMorrison Esta pregunta tiene casi 4 años y no tiene nada que ver con fragmentos. Sugiero presentar una nueva pregunta y / o echar un vistazo android.app.FragmentTransactiony su replace()método.
lupz
Es una pena que su respuesta sea demasiado compleja, en los comentarios, para programadores novatos de Android :-(
Antonio Sesto
2
@AntonioSesto ¿Qué es demasiado complejo? ¿Dónde te confundiste?
AdamMc331
@broot Quiero agregar imágenes daynamically a mi diseño lineal que he hecho. luego elimino algunas imágenes del diseño. entonces quiero restaurarlo en su propia posición desde donde lo he eliminado. significa que quiero agregar imágenes sin eliminar a los padres del niño, ¿pueden ayudarme?
PriyankaChauhan
43

Y si lo hace con mucha frecuencia, podría usar un ViewSwitcher o un ViewFlipper para facilitar la sustitución de la vista.

Snicolas
fuente
Sí, si se trata de vistas alternativas, entonces es mejor usar el flipper / conmutador de vista
Zoombie
2
@Shail Adi, ¿intentaste usar un código tutorial de ViewSwitcher?
Snicolas
Sé que esto es antiguo, pero la advertencia es que un ViewSwitcher se inicializa y contiene ambas Vistas en sí mismo (un FrameLayout).
Vikram Bodicherla
Esta debería ser la respuesta recomendada. ¿Por qué no usar una solución preparada y bien probada?
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
fuente
66
Si bien este código puede responder la pregunta, proporcionar un contexto adicional con respecto a cómo y / o por qué resuelve el problema mejoraría el valor a largo plazo de la respuesta
frobinsonj
0

funciona en mi caso, oldSensor y newSnsor - oldView y 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
fuente