2011-01-01 8 views
27

Sto facendo un'applicazione per Android e qualcosa di cui ho bisogno è che mostri un elenco di tutti i file e le directory nella scheda SD e deve essere in grado di spostarsi tra le diverse directory. Ho trovato a good tutorial in anddev. Ho modificato alcune cose in modo che l'applicazione si muova nella scheda SD e non nelle directory radice di Android, ma il resto è per lo più lo stesso.Errore logcat: "addView (View, LayoutParams) non è supportato in AdapterView" in un ListView

Questo è il mio file XML per l'attività:

<?xml version="1.0" encoding="utf-8"?> 
<ListView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@id/android:list"  
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <TextView 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" /> 
</ListView> 

E questo è il codice per l'attività:

import hackreatorz.cifrador.R; 

import java.io.File; 
import java.util.ArrayList; 

import android.app.ListActivity; 
import android.content.res.Configuration; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 
import android.widget.Toast; 

public class ArchivosSD extends ListActivity { 

    private ArrayList<String> directoryEntries = new ArrayList<String>(); 
    private File currentDirectory = new File("/sdcard/"); 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     browseToSD(); 
    } 

    @Override 
    public void onConfigurationChanged(Configuration newConfig) { 
     super.onConfigurationChanged(newConfig); 
    } 

    private void browseToSD() { 
     browseTo(new File("/sdcard/")); 
    } 

    private void upOneLevel() { 
     if(this.currentDirectory.getParent() != null) 
      this.browseTo(this.currentDirectory.getParentFile()); 
    } 

    private void browseTo(final File directory) { 
     if (directory.isDirectory()) { 
       this.currentDirectory = directory; 
       fill(directory.listFiles()); 
     } else { 
       Toast.makeText(ArchivosSD.this, this.directoryEntries.get(this.getSelectedItemPosition()), Toast.LENGTH_SHORT).show(); 
       } 
    } 

    private void fill(File[] files) { 
     this.directoryEntries.clear(); 
     this.directoryEntries.add(getString(R.string.current_dir)); 
     if(this.currentDirectory.getParent() != null) 
      this.directoryEntries.add(getString(R.string.up_one_level)); 
      int currentPathStringLength = (int) this.currentDirectory.getAbsoluteFile().length(); 
      for (File file : files) { 
       this.directoryEntries.add(file.getAbsolutePath().substring(currentPathStringLength));   
      } 
     setListAdapter(new ArrayAdapter<String>(this, R.layout.archivos_sd, this.directoryEntries)); 
    } 

    @Override 
    protected void onListItemClick(ListView l, View v, int position, long id) { 
     int selectionRowID = (int) this.getSelectedItemPosition(); 
     String selectedFileString = this.directoryEntries.get(selectionRowID); 
     if (selectedFileString.equals(".")) { 
      this.browseToSD(); 
     } else if(selectedFileString.equals("..")) { 
      this.upOneLevel(); 
     } else { 
      File clickedFile = null; 
      clickedFile = new File(this.currentDirectory.getAbsolutePath() + this.directoryEntries.get(selectionRowID)); 
      if(clickedFile != null) 
       this.browseTo(clickedFile); 
      } 
    } 
} 

non ottengo errori in Eclipse, ma ho un Forza Chiudi quando eseguo l'applicazione sul mio telefono e quando guardo Logcat vedo quanto segue:

01-01 23: 30: 29,858: ERRORE/AndroidRuntime (14911): FATAL ECCEZIONE: principale 01-01 23: 30: 29,858: ERRORE/AndroidRuntime (14911): java.lang.UnsupportedOperationException: addView (View, LayoutParams) non è supportato in AdapterView

Non ho idea di cosa faccio, ho cercato su Google e non ho trovato nulla e ho fatto lo stesso su StackOverflow. Questa è la mia prima aplicazione in Java e per Android, quindi sono un vero n00b e se la risposta era lì, non l'ho capito, quindi sarei davvero grato se potessi spiegare cosa dovrei fare per correggere questo errore e perché.

Grazie per tutto in anticipo.

risposta

14

Quando si crea un Adattatore come il proprio, l'ArrayAdapter necessita di una risorsa di layout contenente solo un TextView. provare a cambiare la vostra creazione ArrayAdapter con:

setListAdapter(new ArrayAdapter<String>(this, 
     android.R.layout.simple_list_item_1, 
     this.directoryEntries)); 

e vedere se funziona.

+0

Ottimo! Funziona grazie mille! Ho un dubbio sulla tua risposta, cosa include "android.Routout.simple_list_item_1"? Se utilizzo "android.R.layout.simple_list_item_1", ​​cosa succede con il layout che ho fatto con Listview e TextView? Molte grazie! –

+0

Quando si crea un ArrayAdapter si passa una risorsa di layout da utilizzare su ogni elemento dell'elenco (e ArrayAdapter richiede solo un TextView). Il file di layout in cui è stata impostata la "schermata" deve essere utilizzato all'interno di onCreate, con setContentView (R.layout.your_layout). –

+0

Potrei cambiare "android.R.layout.simple_list_item_1" per R.layout.myxml se quel file XML ha avuto il seguente codice ?: \t

58

Per gli altri che hanno questo problema e hanno gonfiato un layout in ArrayAdapter s' getView, impostare il parametro parent a null, come in view = inflater.inflate(R.layout.mylayout, null);

+3

Ottimo commento! Ho lottato per ore a causa di questo ... Qualcuno sa perché? –

+0

Anche questo ha risolto il mio problema. Penso che sia qualcosa a che fare con il genitore listview che richiede parametri di layout. – jtwigg

+12

Questa è sicuramente una risposta sbagliata, dovresti sempre passare a un viewgroup padre mentre gonfia, ci sono alcune eccezioni ma questo non è uno di questi, per maggiori informazioni vedi qui: http://www.doubleencore.com/2013/05//Layout-inflazione-as-destinato. Il problema generale che le persone stanno avendo è un xml configurato erroneamente. – Tobrun

48

Regola generale

Si dovrebbe sempre cercare di passare in un genitore mentre gonfia una vista, altrimenti il ​​framework non sarà in grado di identificare quali parametri di layout usare per quella vista gonfiata.

Il modo corretto di gestire l'eccezione è passando falsa come terzo parametro , questo flag indica se una vista deve essere aggiunto direttamente al contenitore superato o meno.

Nel caso di un adattatore, l'adattatore stesso si aggiungerà la vista dopo aver restituito la vista da voi metodo GetView:

view = inflater.inflate(R.layout.mylayout, parent, false);

BaseAdapter campione, viene da just-for-us DevBytes:

@Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View result = convertView; 
     if (result == null) { 
      result = mInflater.inflate(R.layout.grid_item, parent, false); 
     } 

     // Try to get view cache or create a new one if needed 
     ViewCache viewCache = (ViewCache) result.getTag(); 
     if (viewCache == null) { 
      viewCache = new ViewCache(result); 
      result.setTag(viewCache); 
     } 

     // Fetch item 
     Coupon coupon = getItem(position); 

     // Bind the data 
     viewCache.mTitleView.setText(coupon.mTitle); 
     viewCache.mSubtitleView.setText(coupon.mSubtitle); 
     viewCache.mImageView.setImageURI(coupon.mImageUri); 

     return result; 
    } 

CursorAdapter esempio:

@Override 
    public View newView(final Context context, final Cursor cursor, final ViewGroup root)   { 
     return mInflater.inflate(R.layout.list_item_ticket, root, false); 
    } 

Maggiori informazioni su vista l'inflazione può essere trovato in questo article.