Я пытаюсь реализовать ListAdapter, реализуя интерфейс, не расширяющий подклассы BaseAdapter, такие как ArrayAdapter.Но все, что я получаю взамен, - это ClassCastException, который ничего не говорит мне о его конкретной причине.
Сначала о приложении, которое я хочу разработать:
Я хочу создать Hex View (а затем Hex View)-Редитор) для устройств с поддержкой Android.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)
Если вам нужна системная информация:Я использую HTC Desire GSM под управлением Android 2.3.7 (CyanogenMod).Я также попробовал эмулируемую среду (Android 2.1), которая тоже закрывается.
Я не понял, что я делаю неправильно.Android ничего не говорит мне больше, чем эта трассировка стека.Поиск Google по этому конкретному запросу оказался пустым или «не работает».
Я использовал это руководство для моего ListAdapter:
Android ListView с быстрой прокруткой и индексом раздела