5

Aggiungo dinamicamente le viste a un layout relativo e le definisco in modo programmatico. Le viste possono essere spostate sullo schermo in modo che la loro posizione stia cambiando.Impostazione dinamica delle viste con l'impostazione LayoutParams.addRule fino all'ultima posizione della vista

Quando si tenta di impostare una vista (pulsante2) per sedersi sotto un'altra vista (pulsante1), il pulsante2 viene inserito nella vecchia posizione del pulsante1 (la posizione predefinita in cui le viste vengono aggiunte prima dello spostamento). Ho collegato le immagini per ottimizzarlo meglio.

Questo è il layout originale Original Layout

layout dopo Button2 viene riposizionato Re-positioned Layout

Ho uno sfondo LinkedList tenere traccia di tutte le modifiche di visualizzazione e visualizzare gli attributi per il layout, se questo fa la differenza.

Qui ci sono le funzioni di codice:

come sto riposizionamento Button1:

Buttons b = (Buttons) viewIndex; 
           positioningLayout = new RelativeLayout.LayoutParams(b.getLayoutParams()); 
           positioningLayout.addRule(RelativeLayout.CENTER_VERTICAL); 
           b.setLayoutParams(positioningLayout); 
           baseLayout.addView(b); 

Riposizionamento vista sotto un altro frammento vista Codice:

Buttons b = (Buttons) viewIndex; 
           positioningLayout = new RelativeLayout.LayoutParams(b.getLayoutParams()); 
           positioningLayout.addRule(RelativeLayout.BELOW, viewIdFromList.intValue()); 
           b.setLayoutParams(positioningLayout); 
           b.invalidate(); 

Come sto aggiungendo le viste al layout.

uiList.addView(new Buttons(this), "BUTTON"); 
      setDialogView(uiList.getLast()); 
      showDialog(SET_ID); 
      reloadUI(); 

setDialogView è solo di passaggio la vista della finestra SET_ID modo che possa assegnare manualmente un ID per la visualizzazione (per la prova). reloadUI() trova solo l'ultima vista aggiunta allo sfondo LinkedList e la aggiunge al relativoLayout usando .addView;

Se necessitate di più codice, fatemelo sapere. Mi manca una chiamata per aggiornare i layout della vista dopo aver apportato una modifica alle viste child relativeLayout? Sembra che la vista si stia riposizionando visivamente ma i LayoutParam effettivi non si aggiornano quindi quando si imposta Button2 su Button1 si ottiene la posizione precedente.

C'è un modo per forzare una posizione di layout relativa riposizionare?

+0

si può mostrare il layout principale? –

+0

L'interfaccia utente viene creata in modo completamente dinamico, quindi non viene utilizzato alcun XML:/ – Sevros

risposta

2

Penso che dovresti provare una soluzione semplice - sostituire b.invalidate() con b.requestLayout(). Per ulteriori controlli sullo sfondo, this link. Non l'ho provato ma spero che funzionerà. Quindi il codice dovrebbe essere simile:

Buttons b = (Buttons) viewIndex; 
positioningLayout = new RelativeLayout.LayoutParams(b.getLayoutParams()); 
positioningLayout.addRule(RelativeLayout.BELOW, viewIdFromList.intValue()); 
b.setLayoutParams(positioningLayout); 
b.requestLayout(); 

O forse si può semplificare questo a:

Buttons b = (Buttons) viewIndex; 
((RelativeLayout.LayoutParams) b.getLayoutParams()).addRule(RelativeLayout.BELOW, viewIdFromList.intValue()); 
b.requestLayout(); 
+0

Questo ha funzionato, grazie! Potresti spiegare perché requestlayout() funziona ma non invalida()? Non pensavo che requestlayout() abbia rinfrescato la vista quando è stata chiamata. – Sevros

+0

Certo, 'requestLayout()' dovrebbe essere chiamato, quando la posizione della vista oi limiti nel layout genitore sono stati cambiati, mentre 'invalidate()' dovrebbe essere chiamato quando l'aspetto della vista è stato cambiato. Da un lato, quando si chiama 'requestLayout()' allora i metodi 'onLayout()' e 'onMeasure()' verranno attivati, d'altra parte quando si chiama 'invalidate()', quindi 'onDraw () 'Il metodo verrà licenziato. – rom4ek

+0

Quindi, 'invalidate()' semplicemente ridisegna la vista stessa, quando 'requestLayout()' aggiorna la posizione e i limiti della vista. Prego e sto cercando la tua taglia: D – rom4ek

1

Sembra che tu stia andando nella giusta direzione ma sta facendo un piccolo errore. Senza più codice è abbastanza difficile fornire la soluzione reale. Ma proverò a sottolineare l'errore.

Sede, relativamente posizionare gli elementi di programmazione in un RelativeLayout è necessario assegnare ID univoci a ciascuno di essi.

Come,

Button b = new Button(this); 
b.setId(1); 

Button c = new Button(this); 
c.setId(2); 

Ogni elemento deve avere ID univoci.

Ora, se si desidera posizionare il tasto B verticalmente al centro,

layout.addRule(RelativeLayout.CENTER_VERTICAL); 
b.setLayoutParams(layout); 

Ora, se si desidera posizionare pulsante C al di sotto di esso,

layout.addRule(RelativeLayout.BELOW, b.getId()); 
layout.addRule(RelativeLayout.ALIGN_PARENT_LEFT); 
b.setLayoutparams(layout); 

Questo sarà certamente posizionare il pulsante c sotto il pulsante b.Come hai detto, puoi utilizzare una qualsiasi struttura dati di tua scelta per tenere traccia degli ID di ciascun elemento.

1

Questo è solo un esempio di dettaglio su come si sposta il pulsante correttamente. Quindi, prima, creare un ID univoco per il View, vale a dire creare un nuovo file di risorse XML in res/values/, e il nome ids.xml:

structure

E il contenuto di ids.xml è:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <item name="button_1" type="id"/> 
    <item name="button_2" type="id"/> 
</resources> 

Noi devi impostare un id per il tuo layout principale:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/layout_main"> <!-- the id --> 

    <!-- content of this layout --> 

</RelativeLayout> 

Quindi, creiamo e Button s:

RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.layout_main); 

    final Button button1 = new Button(this); 
    button1.setId(R.id.button_1); 
    button1.setText("BUTTON 1"); 
    button1.setTextColor(Color.BLACK); 

    final Button button2 = new Button(this); 
    button2.setId(R.id.button_2); 
    button2.setText("BUTTON 2"); 
    button2.setTextColor(Color.BLACK); 

    relativeLayout.addView(button1, new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, 
      RelativeLayout.LayoutParams.WRAP_CONTENT)); 
    relativeLayout.addView(button2, new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, 
      RelativeLayout.LayoutParams.WRAP_CONTENT)); 

    RelativeLayout.LayoutParams params1 = (RelativeLayout.LayoutParams) button1.getLayoutParams(); 
    params1.addRule(RelativeLayout.CENTER_IN_PARENT); // set to the center of screen 
    button1.setLayoutParams(params1); 

    final RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams) button2.getLayoutParams(); 
    params2.addRule(RelativeLayout.ALIGN_PARENT_TOP); 
    params2.addRule(RelativeLayout.ALIGN_PARENT_LEFT); 
    button2.setLayoutParams(params2); 

    button2.setOnClickListener(new View.OnClickListener() { 
     @SuppressLint("NewApi") 
     @Override 
     public void onClick(View v) { 
      /* We need to remove the existing rules and update it! 
      * For API 16 and earlier, set the rule to 0, e.g. --> layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0); 
      * For API 17 and higher, call layoutParams.removeRule(RelativeLayout.ALIGN_PARENT_LEFT); 
      */ 

      int api = android.os.Build.VERSION.SDK_INT; 
      if (api >= Build.VERSION_CODES.JELLY_BEAN_MR1) { // API level 17 
       params2.removeRule(RelativeLayout.ALIGN_PARENT_TOP); 
       params2.removeRule(RelativeLayout.ALIGN_PARENT_LEFT); 
      }else if (api < Build.VERSION_CODES.JELLY_BEAN_MR1) { 
       params2.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0); 
       params2.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0); 
      } 

      params2.addRule(RelativeLayout.CENTER_IN_PARENT); 
      params2.addRule(RelativeLayout.BELOW, R.id.button_1); // place below button1 
      button2.setLayoutParams(params2); 
     } 
    }); 

Quindi una volta che si fa clic su button2, si sposterà al di sotto button1.

+0

Grazie per la rapida risposta, ma purtroppo non ha funzionato – Sevros

Problemi correlati