ListView的自定义适配器

时间:2012-08-08 09:20:10

标签: android listview android-arrayadapter custom-adapter

我正在尝试制作一个自定义的ListView,它应该显示一个音符标题以及创建音符的时间和日期,每个都在单独的TextView中,而每个音符标题也用存储在DB中的颜色值着色。所以我为它创建了一个自定义适配器:

public class NoteAdapter extends ArrayAdapter<Note> {

public NoteAdapter(Context context, int resource, int textViewResourceId, List<Note> objects) {
    super(context, resource, textViewResourceId, objects);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // Creating the row
    View row = super.getView(position, convertView, parent);

    // Changing the text of time and date
    ((TextView)row.findViewById(R.id.noteTitle)).setText(getItem(position).getTitle());
    ((TextView)row.findViewById(R.id.noteTime)).setText(getItem(position).getTime());
    ((TextView)row.findViewById(R.id.noteDate)).setText(getItem(position).getDate());

    ((TextView)row.findViewById(R.id.noteTitle)).setTextColor(Color.parseColor(getItem(position).getColor()));

    // Returning the row
    return row;
    }
}

在主要活动中,这就是我实施它的方式:

...
NoteAdapter adapter;
NotesManager manager;
private Note nNoteToDelete;
ArrayList<Note> lstAllNotes;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // Setting onClickListener for the "Add note" button when the activity starts
    findViewById(R.id.btnAddNewNote).setOnClickListener(addNewNote);

    // INSTANTIATING

    // Manager - to manage all the DB manipulations
    manager = new NotesManager(this);

    // Retrieving all the notes in the DB
    lstAllNotes = manager.getAllNotes();

    // Setting the ArrayAdapter, to display retrieved data in the ListView
    //adapter = new ArrayAdapter<Note>(this, R.layout.note, lstAllNotes);
    adapter = new NoteAdapter(this, R.layout.main, R.id.noteTitle, lstAllNotes);

    // Setting the ListAdapter
    setListAdapter(adapter);

    // Registering for a single click action for each item in the ListView
    getListView().setOnItemClickListener(editNote);

    // Registering for a long click, which will pop up a context menu
    registerForContextMenu(getListView());

}
...

但是当我测试应用程序时,它会立即崩溃。我在LogCat中遇到这些错误:

08-08 08:59:52.291: E/AndroidRuntime(21268): FATAL EXCEPTION: main
08-08 08:59:52.291: E/AndroidRuntime(21268): java.lang.NullPointerException
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:394)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.widget.ArrayAdapter.getView(ArrayAdapter.java:362)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at com.notepad.NoteAdapter.getView(NoteAdapter.java:24)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.widget.AbsListView.obtainView(AbsListView.java:2267)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.widget.ListView.measureHeightOfChildren(ListView.java:1244)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.widget.ListView.onMeasure(ListView.java:1156)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.View.measure(View.java:15172)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.widget.LinearLayout.measureVertical(LinearLayout.java:681)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.View.measure(View.java:15172)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.View.measure(View.java:15172)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.widget.LinearLayout.measureVertical(LinearLayout.java:833)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.View.measure(View.java:15172)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2148)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.View.measure(View.java:15172)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1848)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1100)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1273)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:998)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4212)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.Choreographer.doCallbacks(Choreographer.java:555)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.Choreographer.doFrame(Choreographer.java:525)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.os.Handler.handleCallback(Handler.java:615)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.os.Handler.dispatchMessage(Handler.java:92)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.os.Looper.loop(Looper.java:137)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at android.app.ActivityThread.main(ActivityThread.java:4745)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at java.lang.reflect.Method.invokeNative(Native Method)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at java.lang.reflect.Method.invoke(Method.java:511)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
08-08 08:59:52.291: E/AndroidRuntime(21268):    at dalvik.system.NativeStart.main(Native Method)

我在这里缺少什么?为什么它会一直崩溃,我该如何解决?

2 个答案:

答案 0 :(得分:4)

您没有在自定义适配器的getView()中夸大视图

你正在做的事情是不对的

// Creating the row
View row = super.getView(position, convertView, parent);

尝试做类似这样的事情,其中​​row.xml将是布局文件夹中的布局文件

LayoutInflater inflater=LayoutInflater.from(context);
View row=inflater.inflate(R.layout.row, parent, false);

其中context是构造函数中初始化的Context类型的局部变量。

答案 1 :(得分:1)

试试这个:

public class NoteAdapter extends ArrayAdapter<Note> {

    LayoutInflater mInflater;
    List<Note> list;
    public NoteAdapter(Context context, int resource, int textViewResourceId, List<Note> objects) {
        super(context, resource, textViewResourceId, objects);
        mInflater=LayoutInflater.from(context);
        list=objects;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        final ViewHolder holder;

        if(convertView==null){
             convertView=mInflater.inflate(R.layout.listitem_layout,null);// R.layout.listitem_layout is your custom layout file
             holder=new ViewHolder();

             holder.title=(TextView)convertView.findViewById(R.id.noteTitle);
             holder.time=(TextView)convertView.findViewById(R.id.noteTime);
             holder.date=(TextView)convertView.findViewById(R.id.noteDate);
             convertView.setTag(holder);
        }
        else{
             holder=(ViewHolder)convertView.getTag();
        }

        Note note=list.get(position);

        holder.title.setText(note.getTitle());
        holder.title.setTextColor(Color.parseColor(note.getColor()));
        holder.time.setText(note.getTime());
        holder.date.setText(note.getDate());      

        return convertView;
    }
    class ViewHolder{
        TextView title;
        TextView time;
        TextView date;
    }
}