2015-08-07 2 views
8

Ho un problema con GridLayoutMangersetSpanSizeLookup, quando cambia l'orientamento dell'attività, sto cambiando il conteggio dello span mentre controllo se la posizione specifica è una sorta di tipo, questo funziona perfettamente sul cambio di orientamento, il mio unico problema è, sto usando zxing biblioteca per fare la scansione del codice a barre, ogni volta che un button si fa clic su sto aprendo l'intento di default zxing e data di recuperare da esso, tuttavia quando zxing sta aprendo va a landscape e il mio attuale orientamento attività è portrait questo dà io il IllegalArgumentException che il gestore di layout genera quando si apre solo l'intento Xzing, il registro di crash è come questo
java.lang.IllegalArgumentException: Item at position 0 requires 2 spans but GridLayoutManager has only 1 spans.
Questo problema non si verifica se ruoto il telefono, accade solo quando lancio l'intento Xzing, non riesco davvero a capire come risolvo questo problema perché mi disturba. ecco la mia spanSizeLookup -GridLayoutManager spanSizeLookup bug

manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { 
    @Override 
    public int getSpanSize(int position) { 
     return adapter.getHolders().get(position).getLabelHolder() != null ? getResources().getInteger(R.integer.span) : 1; 
    } 
}); 

il span è base su dimensioni dello schermo in modo che possa essere 1-2, 2-3 e 3-4. Ripeto questo non mi dà alcun errore sul cambio di orientamento, solo l'errore si verifica quando apro il zxing
P.S se apro zxing intent mentre la mia attività è su landspace l'arresto non si verificherà.

Modifica

sembra che solo lanciare l'intento zxing predefinita che causa questo problema, sto avendo un activity dove va landscape dopo si lancia e la exception non si è verificato, come una soluzione che ho fatto , è che ho creato un activity che gestisce la scansione barcode con un ritardo di 1 secondo per lanciare il intent come se non l'avessi fatto, getterebbe lo stesso exception.

Edit 2

Ho appena scoperto che, anche senza setSpanSpizeLookup l'incidente si verifica ancora. chiamando semplicemente manager.setSpanCount(getResources().getInteger(R.integer.span))

risposta

0

Troppo tardi per rispondere a questa domanda, tuttavia in un ultimo progetto su cui ho lavorato, ho affrontato lo stesso problema & dopo un po 'di debug, ho scoperto qual era la causa del problema ma non ho idea del perché lo avrebbe causato .

zxing Biblioteca intent si chiama in realtà CLEAR_TOP prima di chiamare il startActivityForResult & che era il problema, dopo aver modificato il codice sorgente di zxingIntent per rimuovere quella particolare linea, l'incidente è andato.

0

Modifica: chiama setSpanCount() e ne fa un numero più grande di quello compreso? Forse più codice sarebbe in ordine.

Sembra che potrebbe essere un errore di modifica simultanea. Prova a non utilizzare un ritardo per sé, ma eseguendo modifiche sul thread dell'interfaccia utente. Ciò bloccherà l'interfaccia utente dal tentativo di accedere all'elenco.

if(adapter.getHolders().get(position).getLabelHolder() != null) 
    return getResources().getInteger(R.integer.column); 
else 
    return 1; 

quindi cosa è getResources().getInteger(R.integer.column)?

Non sarà lo stesso numero ogni volta?

+0

getResources(). GetInteger (R.integer.column) dipende dall'orientamento come ho menzionato può essere 2,3,4 a seconda della dimensione del dispositivo e dell'orientamento del dispositivo è – k0sh

+0

ah, ottenuto. nome attributo leggermente confuso. – Andy

+0

kinda di, come im usando quel attr con cose diverse, così invece di creare nuovo attr che fa lo stesso im ri-usarlo: p, im non proprio sicuro se ho provato la tua soluzione, tuttavia lo controllerò subito e aggiornerò u – k0sh

6

Ecco il codice sorgente che genera l'eccezione in GridLayoutManager.layoutChunk()

final int spanSize = getSpanSize(recycler, state, pos); 
if (spanSize > mSpanCount) { 
    throw new IllegalArgumentException("Item at position " + pos + " requires " + 
      spanSize + " spans but GridLayoutManager has only " + mSpanCount 
      + " spans."); 
} 

è la vostra spanSize più grande del tuo spanCount? Prova a eseguire il debug e probabilmente cambia il tuo spanCount e vedi come funziona.

---- ---- Aggiornato

Ci sono due modi per passare da lista e la griglia.

  1. Solo modifica spanCount.

    È necessario chiamare LayoutManager.requestLayout() dopo aver modificato lo spanCount. Altrimenti la tua app potrebbe bloccarsi.

  2. Modifica solo di SpanSizeLookUp.

    private class CustomSpanSize extends GridLayoutManager.SpanSizeLookup { 
    
        private static final int LIST_SPAN_SIZE = 1; 
        private static final int GRID_SPAN_SIZE = 2; 
    
        private int mSpanSize = LIST_SPAN_SIZE; 
    
        public void asList() { 
        mSpanSize = LIST_SPAN_SIZE; 
        } 
    
        public void asGrid() { 
        mSpanSize = GRID_SPAN_SIZE; 
        } 
    
        @Override 
        public int getSpanSize(int position) { 
        return mSpanSize; 
        } 
    } 
    

    e usarlo come quella

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
    
        mLayoutManager = new GridLayoutManager(this, 2); 
    
        mCustomSpanSize = new CustomSpanSize(); 
        mLayoutManager.setSpanSizeLookup(mCustomSpanSize); 
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler); 
        recyclerView.setHasFixedSize(true); 
        recyclerView.setLayoutManager(mLayoutManager); 
    
        ... 
    } 
    
    public void someFunction() { 
        if (changed) { 
        mCustomSpanSize.asList(); 
        } else { 
        mCustomSpanSize.asGrid(); 
        } 
        // use this to update the layout 
        mAdapter.notifyDataSetChanged(); 
        // or you can use this to update the layout 
        mLayoutManager.requestLayout(); 
    } 
    

    in questo modo non andrà in crash nemmeno si dimentica di chiamare notifyDataSetChanged o requestLayout

+0

Ciao Trey, grazie per la risposta, se hai letto la mia domanda, quell'eccezione non si verifica mai se ruoto il telefono manualmente, comunque capita quando pranza zxing intento che a sua volta fa andare la mia attuale attività paesaggio e si blocca, questo è ciò che mi confonde, se lo ruoto, non si bloccherà – k0sh

+1

ciao k0sh, posso chiedere quando il tuo GridLayoutManager avrà solo 1 span. –

+0

quando c'è un elemento che è per esempio lo chiamiamo SEPARATORE – k0sh

0

Sorprendentemente, ho avuto lo stesso problema e appena trovato la soluzione. Dopo aver inizializzato lo GridLayoutManager con lo spanCount passato nel costruttore, la nostra app si arrestava in modo anomalo. MA, se io setSpanCount() dopo aver costruito l'oggetto, FUNZIONA! : O

Utilizziamo RecyclerView 23.0.1. spero che questo aiuti qualcuno.