2011-11-04 3 views
3

J'essaye d'implémenter un ListAdapter en implémentant l'Interface qui n'étend pas les sous-classes de BaseAdapter comme ArrayAdapter. Mais tout ce que je reçois en retour est une ClassCastException qui ne me dit rien sur sa cause spécifique.ListAdapter avec implémenté SectionIndexer throws ClassCastException

Tout d'abord au sujet de l'application que je veux développer:

Je veux créer un affichage hexadécimal (et plus tard un éditeur de Hex-) pour les appareils Android activé. Le ListAdapter était comme d'habitude et fonctionne parfaitement. La partie SectionIndexer ne le fait cependant pas. Je veux permettre à l'utilisateur de faire défiler des fichiers volumineux afin qu'il n'ait pas de doigts fatigués pendant le défilement normal. J'ai donc décidé de diviser un fichier chargé en 1024 Byte Parts (mes sections de défilement rapide).

-moi donc de vous montrer le code:

package in.waslos.kneo.hexviewer.models; 

import in.waslos.kneo.hexviewer.R; 
import in.waslos.kneo.hexviewer.views.ByteTextView; 

import java.util.ArrayList; 

import android.content.Context; 
import android.database.DataSetObserver; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ListAdapter; 
import android.widget.SectionIndexer; 
import android.widget.TextView; 

public class ByteViewModel implements ListAdapter,SectionIndexer { 
private ArrayList<DataSetObserver> listener = new ArrayList<DataSetObserver>(); 
private byte[] byteData; //contains the byte data from some file 
private LayoutInflater xmlInflater; 
private Context context; 

private StringBuffer buffer = new StringBuffer(); 

private String[] sections; 

public ByteViewModel(Context context,byte[] data) { 
    if(data != null && context != null){ 
     this.byteData = data; 
     this.context = context; 

     sections = new String[data.length/1024]; //1K sections 
     for(int i=0;i<sections.length;i++){ 
      sections[i]=String.format("%d", (i+1)); 
      Log.e("sections",sections[i]); 
     } 
    } 
} 

public class ViewHolder{ 
    TextView address; 
    ByteTextView binData; 
    TextView asciiData; 
} 

private ViewHolder viewHolder; 

@Override 
public boolean areAllItemsEnabled() { 
    return true; 
} 

@Override 
public boolean isEnabled(int position) { 
    return true; 
} 

@Override 
public int getCount() { 
    return byteData.length%16 == 0 ? byteData.length/16: byteData.length/16 + 1; 
} 

@Override 
public Object getItem(int position) { 
    return byteData; 
} 

@Override 
public long getItemId(int position) { 
    return position*16; 
} 

@Override 
public int getItemViewType(int position) { 
    return 0; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    if(convertView==null){ 
     if(xmlInflater==null){ 
      xmlInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     } 
     convertView = xmlInflater.inflate(R.layout.hexviewitem, parent,false); 

     viewHolder = new ViewHolder(); 
     viewHolder.address = (TextView)convertView.findViewById(R.id.address_view); 
     viewHolder.binData = (ByteTextView)convertView.findViewById(R.id.byte_view); 
     viewHolder.asciiData= (TextView)convertView.findViewById(R.id.data_view); 
     convertView.setTag(viewHolder); 
    } 
    viewHolder = (ViewHolder)convertView.getTag(); 
    //get leading zeros for the address/offset column 
    viewHolder.address.setText(Long.toString(position*16 + 0x100000000L, 16).substring(1)); 
//costume view for the byte view column 
    viewHolder.binData.setByteValue(position*16, byteData); 
    viewHolder.asciiData.setText(getAsciiRep(position)); 


    return convertView; 
} 

@Override 
public int getViewTypeCount() { 
    return 1; 
} 

@Override 
public boolean hasStableIds() { 
    return true; 
} 

@Override 
public boolean isEmpty() { 
    return false; 
} 

@Override 
public void registerDataSetObserver(DataSetObserver observer) { 
    listener.add(observer); 
} 

@Override 
public void unregisterDataSetObserver(DataSetObserver observer) { 
    listener.remove(observer); 
} 
//gets string ascii representation for a byte 
private String getAsciiRep(int pos){ 
    pos = pos*16; 
    buffer.delete(0, buffer.length());  
    for(int i = 0;i<16;i++){ 
     if(pos+i<byteData.length) 
      if(byteData[pos+i]<0x20){ 
      buffer.append('.'); 
      } else { 
       buffer.append((char)byteData[pos+i]);    
      } 
     else { 
      buffer.append(' '); 
     } 
    } 

    return buffer.toString(); 
} 

@Override 
public int getPositionForSection(int section) { 
    return section*1024;//this function is never called! 
} 

@Override 
public int getSectionForPosition(int position) { 
    return position/1024;//this function is never called! 
} 

@Override 
public Object[] getSections() { 
    Log.e("Indexer", "returning sections!"); //this function is never called! 
    return sections; 
} 
} 

Je ne pas utiliser des cartes de hachage comme dans le tutoriel que je défile que par un tableau statique. Donc, les positions de retour devraient être suffisantes. Ce qui n'a pas d'importance puisque les fonctions n'ont jamais été appelées de toute façon.

Tout fonctionne toujours vous pouvez faire défiler par fling normal mais si vous touchez le "grabber" l'application vous informe de sa fermeture forcée. J'ai d'abord pensé que cela ne fonctionnait qu'avec des chaînes de caractères, mais cela ne résout pas non plus le problème.

Cependant voici la trace de la pile je reçois:

11-04 18:29:13.914: W/dalvikvm(17078): threadid=1: thread exiting with uncaught exception (group=0x4012b560) 
11-04 18:29:13.924: E/AndroidRuntime(17078): FATAL EXCEPTION: main 
11-04 18:29:13.924: E/AndroidRuntime(17078): java.lang.ClassCastException:in.waslos.kneo.hexviewer.models.ByteViewModel 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.widget.FastScroller.getSectionsFromIndexer(FastScroller.java:291) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.widget.FastScroller.onTouchEvent(FastScroller.java:435) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.widget.AbsListView.onTouchEvent(AbsListView.java:2141) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.widget.ListView.onTouchEvent(ListView.java:3446) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.view.View.dispatchTouchEvent(View.java:3901) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:903) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:869) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1737) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1153) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.app.Activity.dispatchTouchEvent(Activity.java:2096) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1721) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2200) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.view.ViewRoot.handleMessage(ViewRoot.java:1884) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.os.Handler.dispatchMessage(Handler.java:99) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.os.Looper.loop(Looper.java:130) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at android.app.ActivityThread.main(ActivityThread.java:3835) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at java.lang.reflect.Method.invokeNative(Native Method) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at java.lang.reflect.Method.invoke(Method.java:507) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
11-04 18:29:13.924: E/AndroidRuntime(17078): at dalvik.system.NativeStart.main(Native Method) 

Si vous avez besoin d'informations sur le système: J'utilise un HTC Desire GSM en cours d'exécution 2.3.7 (CyanogenMod) Android. J'ai aussi essayé un environnement émulé (Android 2.1) dont la force se ferme aussi.

Je n'ai pas compris ce que je fais mal. Android ne me dit rien de plus que cette trace de pile. Recherche Google à cette enquête spécifique est venu vide ou "ne fonctionne pas".

J'ai utilisé ce tutoriel pour mon ListAdapter:

Android ListView with fast scroll and section index

Répondre

3

J'ai trouvé la solution en regardant à travers la liste des questions au code Google. Aurait dû le faire avant de poster si désolé pour cela.

Anyways:

Son un Bug-cadre qui est plus de deux ans maintenant. Alors espérons que ce sera corrigé bientôt.

Pour éviter ou contourner ce bug vous devez remplacer implements ListAdapter par extends BaseAdapter

La partie drôle est que le BugReporter déjà fourni une solution pour ce bogue.

Cependant, il est toujours présent dans Android 4.0 (testé en émulateur)! J'espère donc que cette question attirera davantage l'attention sur ce petit problème.

Voir: Android issue 3522

Questions connexes