3

ArrayAdapter のような BaseAdapter サブクラスを拡張しないインターフェイスを実装して、ListAdapter を実装しようとしています。しかし、見返りとして得られるのは、特定の原因について何も教えてくれない ClassCastException だけです。

まず、開発したいアプリケーションについて:

Android 対応デバイス用の 16 進数ビュー (および後で 16 進数エディター) を作成したいと考えています。ListAdapter は通常どおりのビジネスであり、問​​題なく動作します。ただし、SectionIndexer 部分はそうではありません。通常のスクロール中に指が疲れないように、ユーザーが大きなファイルをスクロールできるようにしたいと考えています。そこで、ロードしたファイルを 1024 バイト パーツ (高速スクロール セクション) に分割することにしました。

それでは、コードをお見せしましょう:

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;
}
}

静的配列をスクロールするだけなので、チュートリアルのようにハッシュ マップは使用しませんでした。したがって、ポジションを返すだけで十分です。とにかく関数が呼び出されたことがないので、これは問題ではありません。

通常のフリングでスクロールできますが、「グラバー」に触れると、アプリケーションは強制終了について通知します。最初は文字セクション文字列でのみ機能すると思っていましたが、これでも問題は解決しませんでした。

ただし、ここに私が得るスタックトレースがあります:

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)

システム情報が必要な場合: Android 2.3.7 (CyanogenMod) を実行している HTC Desire GSM を使用しています。強制終了するエミュレート環境(Android 2.1)も試しました。

私は自分が間違っていることを理解していませんでした。Android は、このスタック トレース以上のものを教えてくれません。この特定の問い合わせに対するGoogle検索は、空または「機能していません」と出てきました。

ListAdapter にこのチュートリアルを使用しました。

高速スクロールとセクション インデックスを備えた Android ListView

4

1 に答える 1

3

Googleコードの問題リストを調べて解決策を見つけました。投稿する前にこれを行うべきだったので、申し訳ありません。

いずれかの方法:

そのフレームワークのバグは、今では 2 年以上前のものです。ですから、すぐに修正されることを願っています。

このバグを回避または回避するには、次のものに置き換える必要がありimplements ListAdapterますextends BaseAdapter

面白いことに、Bugreporter はすでにこのバグの解決策を提供しています。

ただし、Android 4.0 にはまだ存在します (エミュレーターでテスト済み)。ですから、この質問がこの小さな問題にもっと注意を向けてくれることを願っています。

参照: Android の問題 3522

于 2011-11-05T08:58:14.503 に答える