2016-04-29 22 views
8

Ho un pulsante "aggiungi" e un GridLayout con 6 slot al suo interno, quando faccio clic sul pulsante "aggiungi", viene aggiunta la vista1 nella griglia, faccio clic sull'aggiunta 'pulsante di nuovo view2 viene aggiunto, e così via.Aggiunta di viste in un ordine specifico e memorizzazione di tale ordine

if (!theLayout1.isShown()) { 
     Grid.addView(theLayout1); 
} else if (!theLayout2.isShown()) { 
     Grid.addView(theLayout2); 
} else if (!theLayout3.isShown()) { 
     Grid.addView(theLayout3); 
} ..... // this goes on 

dopo una vista viene aggiunto a verificare se il testo è stato già aggiunto in sharedPrefs modo che possano essere aggiunti automaticamente quando si ricrea l'attività

if (prefs.getString("text4", null) != null) { 
    Grid.addView(theLayout4); 
} 

if (prefs.getString("text5", null) != null) { 
    Grid.addView(theLayout5); 
} 
// each view has one EditText 

il mio problema è, se tolgo view1 e quindi aggiungere di nuovo, verrà inserito nell'ultimo slot come voglio, ma quando ricrearò l'attività tornerà al primo posto, perché poiché il codice viene letto nel suo ordine, aggiungerà le visualizzazioni nel loro ordine iniziale.

Voglio aggiungere le visualizzazioni quando ricreare l'attività nell'ordine in cui erano prima di terminare l'attività, questo può avere una soluzione logica semplice o forse sto solo affrontando il problema molto in modo errato, in ogni caso, è necessario un aiuto !

risposta

1

Il problema (almeno da quello che ho capito dalla tua domanda) è che non si salva nelle preferenze una sorta di indicatore per la posizione della vista nel suo genitore. In questo momento non vi è alcuna differenza tra l'aggiunta per la prima volta e l'aggiunta della vista dopo averlo eliminato, o tra l'aggiunta della vista nello slot 1 e lo slot 5 (ad esempio). Un modo per gestire questo sarebbe di avere una voce in preferenze per ciascuno di questi slot e quindi salvare in tali preferenze di slot l'indicatore di vista:

Ad esempio:

// the base of the slot keys, there will be 6 of them from 1 to 6 inclusive 
private static final String KEY_SLOT = "key_slot"; 

// when adding the view for slot 2 you'll save in preferences text2 it's indicator 
prefEditor.putString(KEY_SLOT + position, text2); // position will be 2, the indicator of the slot in your layout 

// when you delete the view from a slot, nullify it's slot preferences 
// for example deleting the slot 3(child 3 in the layout) 
prefEditor.putString(KEY_SLOT + position, null); position will be 3 

quando si ricrea l'attività guarda tutte le preferenze SLOT e vedi quali valori tengono. Potrebbero essere nulli se il tuo layout consente di avere buchi (come non avere una vista per lo slot 2, ma avere una vista per gli slot 1 e 3) o potrebbero contenere una delle tue variabili di testo * che indicano quale vista deve essere posizionata in quello slot:

// in the activity: 
// iterate over all the SLOT preferences 
for (int i = 1; i <= 6; i++) { 
    String text = prefs.getString(KEY_SLOT + i, null); 
    // if text is null there is no view stored for this slot 
    // keep in mind that you need to add some sort of empty widget to act as a child 
    // or modify the LayoutParams of the other children to take in consideration the empty space 
    // OR 
    // if text is one of your values, like text1, text2 etc 
    // then you know that at slot i you need to place the view corresponding to the text value 
} 
0

è necessario memorizzare il nome il nome del layout + un contatore. es: Layout1, Layout2, Layout3 ...

Quando si desidera farli nell'ordine, solo bisogno di ciclo fino a quando non si ha nulla da recuperare:

 int i = 1; 
     String valueStored = null; 
     do { 
      String key = "layout" + i; // layout1, layout2, layout3... 
      SharedPreferences preferences = activity.getSharedPreferences(key, 0); 
      valueStored = preferences.getString(key, null); 

      // View v = getViewByName(valueStored) get the view by the name retrieved from the shared pref 
      //Grid.addView(view); 
     } while (valueStored != null); // stop when there is nothing more to get 

Speranza che aiuta !

+0

Ok, non aggiungerà i layout nell'ordine (int) i? (layout1 poi layout2 poi layout 3 poi layout4 ...) –

+0

Puoi aggiungere i layout nell'ordine che vuoi! La parte importante è solo recuperarli nell'ordine corretto. – GuillaumeAgis

1

Questo si riduce all'inserimento di elementi in una matrice ordinata. C'è un metodo addView(View child, int index) che aggiungerà la vista nella posizione desiderata, che è ciò che si desidera utilizzare. Avrai bisogno di scorrere i bambini attualmente aggiunti e trovare l'indice corretto in cui inserire quello nuovo. Se si codifica ogni vista con il suo valore prima di aggiungerla, è possibile esaminare i tag per determinare dove si trova questo indice.

private void insertView(View theLayoutN, int n) { 
    // tag the new view with its value 
    theLayoutN.setTag(Integer.valueOf(n)); 

    // iterate over the views currently in the grid, keeping track 
    // of the desired insertion index 
    int insertionIndex = 0; 
    final int childCount = grid.getChildCount(); 
    for (int i = 0; i < childCount; i++) { 
     // get the child currently at index i 
     View child = grid.getChildAt(i); 

     // retrieve its tag, which is its value 
     int childN = ((Integer) child.getTag()).intValue(); 

     // if the child's value is greater than the value of the 
     // one we're inserting, then we have found the insertionIndex 
     if (childN > n) { 
      break; 
     } 

     // increment the insertionIndex 
     insertionIndex++; 
    } 

    grid.addView(theLayoutN, insertionIndex); 
} 

Poi, quando è necessario inserire un layout, si può fare questo:

if (!theLayout1.isShown()) { 
    insertView(theLayout1, 1); 
} else if (!theLayout2.isShown()) { 
    insertView(theLayout2, 2); 
} else if (!theLayout3.isShown()) { 
    insertView(theLayout3, 3); 
} 

Questo dovrebbe garantire che le vostre opinioni sono sempre nell'ordine corretto. Potrebbe essere ulteriormente ottimizzato implementando una ricerca binaria, ma se hai così tante Views dovresti comunque utilizzare un ListView.

Tuttavia, si consiglia di riconsiderare completamente questa architettura, poiché si dispone di molto codice ridondante che può essere semplificato con un ciclo o una struttura di dati. In alternativa, è sempre possibile aggiungere tutte le visualizzazioni e chiamare semplicemente theLayout.setVisibility(View.GONE) quando si desidera nascondere uno e theLayout.setVisibility(View.VISIBLE) quando si desidera mostrarlo.

+0

Ricevo un NullPointer quando provo ad aggiungere una vista dopo averlo rimosso: 'java.lang.NullPointerException: tentativo di richiamare il metodo virtuale 'int java.lang.Integer.intValue()' su un riferimento oggetto nullo' –

+0

significa che la vista non ha il suo set di tag, che è probabilmente perché hai aggiunto quella vista al contenitore direttamente invece di usare 'insertView'. – Jschools

+0

Ho usato 'insertView' –

1

vorrei gestire Una cosa del genere utilizzando JsonArray

Ogni volta che si aggiunge una visualizzazione, aggiunge che il testo nella matrice JSON, e poi conservarlo in vostra preferenza condivisa come una stringa.

jsonarray.toString() 

Si può facilmente aggiungere e rimuovere elementi come le vostre opinioni vengono tolte o aggiunte. Inoltre, questo ti aiuta ad avere una sola preferenza condivisa e impedisce di lavorare con preferenze condivise diverse.

SharedPreferences sf = ..... 
String txt=sf.getString("YOUR_KEY",""); 
JsonArray myViewArray=new JsonArray(txt); 
for(int i=0;i<myViewArray.length();i++){ 
    // ADD VIEW HERE 
} 
2

Prima di tutto è possibile memorizzare i punti di vista tag "o qualunque cosa tu li segno con" in una struttura dati che ha un tag e la posizione che la vista è dentro, quindi memorizzare il codice in SharedPreferences.

public void savePreferences() { 
     SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(activity); 
     SharedPreferences.Editor prefsEditor = mPrefs.edit(); 
     Gson gson = new Gson(); 
     String json = gson.toJson(dataStructure, new TypeToken<DataStructure>() { 
     }.getType()); 
     prefsEditor.putString("ordering", json); 
     prefsEditor.commit(); 
    } 

    public static DataStructure loadPreferences() { 
     SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(activity); 
     Gson gson = new Gson(); 
     String json = mPrefs.getString("ordering", ""); 
     if (!json.equals("")) { 
      return (DataStructure) gson.fromJson(json, new TypeToken<DataStructure>() { 
      }.getType()); 
     } else { 
      return new DataStructure(); 
     } 
    } 

Poi quando si recuperano la struttura di dati come già detto, è possibile ordinare i risultati in base alle loro posizioni utilizzando il seguente codice:

Arrays.sort(dataStructure , new Comparator<DataStructureElement>() { 
    @Override 
    public int compare(DataStructureElement o1, DataStructureElement o2) { 
     return Integer.compare(o1.position, o2.position); 
    } 
}); 

Poi iterare i risultati ordinati in datastructure e aggiungere il viste al GridLayout nell'ordine normale.