java - 将数据添加到ListView后崩溃

标签 java android listview crash

我是新来的,我想寻求帮助,这是来自Android编程 class 的一项 Activity 。

我将发布必须实现的文件。

ToDoManagerActivity.java

package course.labs.todomanager;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.text.ParseException;
import java.util.Date;

import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import course.labs.todomanager.ToDoItem.Priority;
import course.labs.todomanager.ToDoItem.Status;

public class ToDoManagerActivity extends ListActivity {

    private static final int ADD_TODO_ITEM_REQUEST = 0;
    private static final String FILE_NAME = "TodoManagerActivityData.txt";
    private static final String TAG = "Lab-UserInterface";

    // IDs for menu items
    private static final int MENU_DELETE = Menu.FIRST;
    private static final int MENU_DUMP = Menu.FIRST + 1;

    ToDoListAdapter mAdapter;

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

        // Create a new TodoListAdapter for this ListActivity's ListView
        mAdapter = new ToDoListAdapter(getApplicationContext());

        // Put divider between ToDoItems and FooterView
        getListView().setFooterDividersEnabled(true);


        // TODO - Inflate footerView for footer_view.xml file // VER LUEGO!!!!!

        TextView footerView = (TextView) getLayoutInflater().inflate(R.layout.footer_view, null);

        // TODO - Add footerView to ListView

        getListView().addFooterView(footerView);



        footerView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                Log.i(TAG,"Entered footerView.OnClickListener.onClick()");

                Intent startNewActivity = new Intent(ToDoManagerActivity.this, AddToDoActivity.class);
                startActivityForResult(startNewActivity, ADD_TODO_ITEM_REQUEST);
            }
        });

        // TODO - Attach the adapter to this ListActivity's ListView

        setListAdapter(mAdapter);

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        Log.i(TAG,"Entered onActivityResult()");

        // TODO - Check result code and request code
        // if user submitted a new ToDoItem
        // Create a new ToDoItem from the data Intent
        // and then add it to the adapter

        if (requestCode == ADD_TODO_ITEM_REQUEST) {

            if (resultCode == RESULT_OK) {


                ToDoItem toDoItem = new ToDoItem(data);
                mAdapter.add(toDoItem);

            }
        }


    }

    // Do not modify below here

    @Override
    public void onResume() {
        super.onResume();

        // Load saved ToDoItems, if necessary

        if (mAdapter.getCount() == 0)
            loadItems();
    }

    @Override
    protected void onPause() {
        super.onPause();

        // Save ToDoItems

        saveItems();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);

        menu.add(Menu.NONE, MENU_DELETE, Menu.NONE, "Delete all");
        menu.add(Menu.NONE, MENU_DUMP, Menu.NONE, "Dump to log");
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case MENU_DELETE:
            mAdapter.clear();
            return true;
        case MENU_DUMP:
            dump();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    private void dump() {

        for (int i = 0; i < mAdapter.getCount(); i++) {
            String data = ((ToDoItem) mAdapter.getItem(i)).toLog();
            Log.i(TAG,  "Item " + i + ": " + data.replace(ToDoItem.ITEM_SEP, ","));
        }

    }

    // Load stored ToDoItems
    private void loadItems() {
        BufferedReader reader = null;
        try {
            FileInputStream fis = openFileInput(FILE_NAME);
            reader = new BufferedReader(new InputStreamReader(fis));

            String title = null;
            String priority = null;
            String status = null;
            Date date = null;

            while (null != (title = reader.readLine())) {
                priority = reader.readLine();
                status = reader.readLine();
                date = ToDoItem.FORMAT.parse(reader.readLine());
                mAdapter.add(new ToDoItem(title, Priority.valueOf(priority),
                        Status.valueOf(status), date));
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } finally {
            if (null != reader) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // Save ToDoItems to file
    private void saveItems() {
        PrintWriter writer = null;
        try {
            FileOutputStream fos = openFileOutput(FILE_NAME, MODE_PRIVATE);
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
                    fos)));

            for (int idx = 0; idx < mAdapter.getCount(); idx++) {

                writer.println(mAdapter.getItem(idx));

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != writer) {
                writer.close();
            }
        }
    }

AddToDoActivity.java
package course.labs.todomanager;

import java.util.Calendar;
import java.util.Date;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.TimePickerDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.TimePicker;
import course.labs.todomanager.ToDoItem.Priority;
import course.labs.todomanager.ToDoItem.Status;

public class AddToDoActivity extends Activity {

    // 7 days in milliseconds - 7 * 24 * 60 * 60 * 1000
    private static final int SEVEN_DAYS = 604800000;

    private static final String TAG = "Lab-UserInterface";

    private static String timeString;
    private static String dateString;
    private static TextView dateView;
    private static TextView timeView;

    private Date mDate;
    private RadioGroup mPriorityRadioGroup;
    private RadioGroup mStatusRadioGroup;
    private EditText mTitleText;
    private RadioButton mDefaultStatusButton;
    private RadioButton mDefaultPriorityButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.add_todo);

        mTitleText = (EditText) findViewById(R.id.title);
        mDefaultStatusButton = (RadioButton) findViewById(R.id.statusNotDone);
        mDefaultPriorityButton = (RadioButton) findViewById(R.id.medPriority);
        mPriorityRadioGroup = (RadioGroup) findViewById(R.id.priorityGroup);
        mStatusRadioGroup = (RadioGroup) findViewById(R.id.statusGroup);
        dateView = (TextView) findViewById(R.id.date);
        timeView = (TextView) findViewById(R.id.time);

        // Set the default date and time

        setDefaultDateTime();

        // OnClickListener for the Date button, calls showDatePickerDialog() to
        // show
        // the Date dialog

        final Button datePickerButton = (Button) findViewById(R.id.date_picker_button);
        datePickerButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                showDatePickerDialog();
            }
        });

        // OnClickListener for the Time button, calls showTimePickerDialog() to
        // show the Time Dialog

        final Button timePickerButton = (Button) findViewById(R.id.time_picker_button);
        timePickerButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                showTimePickerDialog();
            }
        });

        // OnClickListener for the Cancel Button,

        final Button cancelButton = (Button) findViewById(R.id.cancelButton);
        cancelButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                Log.i(TAG, "Entered cancelButton.OnClickListener.onClick()");

                // TODO - Indicate result and finish

                finish();

            }
        });

        // TODO - Set up OnClickListener for the Reset Button
        final Button resetButton = (Button) findViewById(R.id.resetButton);
        resetButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i(TAG, "Entered resetButton.OnClickListener.onClick()");

                // TODO - Reset data to default values

                mTitleText.setText("");

                setDefaultDateTime();

                mDefaultStatusButton.setChecked(true);

                mDefaultPriorityButton.setChecked(true);

            }
        });

        // Set up OnClickListener for the Submit Button

        final Button submitButton = (Button) findViewById(R.id.submitButton);
        submitButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i(TAG, "Entered submitButton.OnClickListener.onClick()");

                // gather ToDoItem data

                // TODO - Get the current Priority
                Priority priority = getPriority();

                // TODO - Get the current Status
                Status status = getStatus();

                // TODO - Get the current ToDoItem Title
                String titleString = mTitleText.getText().toString();

                // Construct the Date string
                String fullDate = dateString + " " + timeString;

                // Package ToDoItem data into an Intent
                Intent data = new Intent();
                ToDoItem.packageIntent(data, titleString, priority, status,
                        fullDate);

                // TODO - return data Intent and finish

                setResult(Activity.RESULT_OK, data);
                finish();

            }
        });
    }

    // Do not modify below this point.

    private void setDefaultDateTime() {

        // Default is current time + 7 days
        mDate = new Date();
        mDate = new Date(mDate.getTime() + SEVEN_DAYS);

        Calendar c = Calendar.getInstance();
        c.setTime(mDate);

        setDateString(c.get(Calendar.YEAR), c.get(Calendar.MONTH),
                c.get(Calendar.DAY_OF_MONTH));

        dateView.setText(dateString);

        setTimeString(c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE),
                c.get(Calendar.MILLISECOND));

        timeView.setText(timeString);
    }

    private static void setDateString(int year, int monthOfYear, int dayOfMonth) {

        // Increment monthOfYear for Calendar/Date -> Time Format setting
        monthOfYear++;
        String mon = "" + monthOfYear;
        String day = "" + dayOfMonth;

        if (monthOfYear < 10)
            mon = "0" + monthOfYear;
        if (dayOfMonth < 10)
            day = "0" + dayOfMonth;

        dateString = year + "-" + mon + "-" + day;
    }

    private static void setTimeString(int hourOfDay, int minute, int mili) {
        String hour = "" + hourOfDay;
        String min = "" + minute;

        if (hourOfDay < 10)
            hour = "0" + hourOfDay;
        if (minute < 10)
            min = "0" + minute;

        timeString = hour + ":" + min + ":00";
    }

    private Priority getPriority() {

        switch (mPriorityRadioGroup.getCheckedRadioButtonId()) {
        case R.id.lowPriority: {
            return Priority.LOW;
        }
        case R.id.highPriority: {
            return Priority.HIGH;
        }
        default: {
            return Priority.MED;
        }
        }
    }

    private Status getStatus() {

        switch (mStatusRadioGroup.getCheckedRadioButtonId()) {
        case R.id.statusDone: {
            return Status.DONE;
        }
        default: {
            return Status.NOTDONE;
        }
        }
    }

    private String getToDoTitle() {
        return mTitleText.getText().toString();
    }


    // DialogFragment used to pick a ToDoItem deadline date

    public static class DatePickerFragment extends DialogFragment implements
            DatePickerDialog.OnDateSetListener {

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {

            // Use the current date as the default date in the picker

            final Calendar c = Calendar.getInstance();
            int year = c.get(Calendar.YEAR);
            int month = c.get(Calendar.MONTH);
            int day = c.get(Calendar.DAY_OF_MONTH);

            // Create a new instance of DatePickerDialog and return it
            return new DatePickerDialog(getActivity(), this, year, month, day);
        }

        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear,
                int dayOfMonth) {
            setDateString(year, monthOfYear, dayOfMonth);

            dateView.setText(dateString);
        }

    }

    // DialogFragment used to pick a ToDoItem deadline time

    public static class TimePickerFragment extends DialogFragment implements
            TimePickerDialog.OnTimeSetListener {

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {

            // Use the current time as the default values for the picker
            final Calendar c = Calendar.getInstance();
            int hour = c.get(Calendar.HOUR_OF_DAY);
            int minute = c.get(Calendar.MINUTE);

            // Create a new instance of TimePickerDialog and return
            return new TimePickerDialog(getActivity(), this, hour, minute, true);
        }

        public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
            setTimeString(hourOfDay, minute, 0);

            timeView.setText(timeString);
        }
    }

    private void showDatePickerDialog() {
        DialogFragment newFragment = new DatePickerFragment();
        newFragment.show(getFragmentManager(), "datePicker");
    }

    private void showTimePickerDialog() {
        DialogFragment newFragment = new TimePickerFragment();
        newFragment.show(getFragmentManager(), "timePicker");
    }
}

我认为问题出在这里,我也不知道如何实现statusView.setOnCheckedChangeListener

ToDoListAdapter.java
package course.labs.todomanager;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class ToDoListAdapter extends BaseAdapter {

    private final List<ToDoItem> mItems = new ArrayList<ToDoItem>();
    private final Context mContext;

    private static final String TAG = "Lab-UserInterface";

    public ToDoListAdapter(Context context) {

        mContext = context;

    }

    // Add a ToDoItem to the adapter
    // Notify observers that the data set has changed

    public void add(ToDoItem item) {

        mItems.add(item);
        notifyDataSetChanged();

    }

    // Clears the list adapter of all items.

    public void clear() {

        mItems.clear();
        notifyDataSetChanged();

    }

    // Returns the number of ToDoItems

    @Override
    public int getCount() {

        return mItems.size();

    }

    // Retrieve the number of ToDoItems

    @Override
    public Object getItem(int pos) {

        return mItems.get(pos);

    }

    // Get the ID for the ToDoItem
    // In this case it's just the position

    @Override
    public long getItemId(int pos) {

        return pos;

    }

    // Create a View for the ToDoItem at specified position
    // Remember to check whether convertView holds an already allocated View
    // before created a new View.
    // Consider using the ViewHolder pattern to make scrolling more efficient
    // See: http://developer.android.com/training/improving-layouts/smooth-scrolling.html

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

        // TODO - Get the current ToDoItem
        final ToDoItem toDoItem = (ToDoItem) getItem(position);

        // TODO - Inflate the View for this ToDoItem
        // from todo_item.xml
        RelativeLayout itemLayout = (RelativeLayout) View.inflate(mContext, R.layout.todo_item, parent);

        // TODO - Fill in specific ToDoItem data
        // Remember that the data that goes in this View
        // corresponds to the user interface elements defined
        // in the layout file

        // TODO - Display Title in TextView
        final TextView titleView = (TextView) convertView.findViewById(R.id.titleView);
        titleView.setText(toDoItem.getTitle());

        // TODO - Set up Status CheckBox
        final CheckBox statusView = (CheckBox) convertView.findViewById(R.id.statusCheckBox);


        statusView.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                Log.i(TAG, "Entered onCheckedChanged()");

                // TODO - set up an OnCheckedChangeListener, which
                // is called when the user toggles the status checkbox



            }
        });

        // TODO - Display Priority in a TextView

        final TextView priorityView = (TextView) convertView.findViewById(R.id.priorityView);
        priorityView.setTag(toDoItem.getPriority());

        // TODO - Display Time and Date.
        // Hint - use ToDoItem.FORMAT.format(toDoItem.getDate()) to get date and
        // time String

        final TextView dateView = (TextView) convertView.findViewById(R.id.dateView);
        dateView.setText(ToDoItem.FORMAT.format(toDoItem.getDate()));

        // Return the View you just created
        return itemLayout;

    }
}

这里是日志
10-27 19:39:08.077: D/AndroidRuntime(1373): Shutting down VM
10-27 19:39:08.077: W/dalvikvm(1373): threadid=1: thread exiting with uncaught exception (group=0xb1a33ba8)
10-27 19:39:08.247: E/AndroidRuntime(1373): FATAL EXCEPTION: main
10-27 19:39:08.247: E/AndroidRuntime(1373): Process: course.labs.todomanager, PID: 1373
10-27 19:39:08.247: E/AndroidRuntime(1373): java.lang.UnsupportedOperationException: addView(View, LayoutParams) is not supported in AdapterView
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.widget.AdapterView.addView(AdapterView.java:478)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.LayoutInflater.inflate(LayoutInflater.java:500)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.View.inflate(View.java:17465)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at course.labs.todomanager.ToDoListAdapter.getView(ToDoListAdapter.java:91)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:220)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.widget.AbsListView.obtainView(AbsListView.java:2263)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.widget.ListView.makeAndAddView(ListView.java:1790)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.widget.ListView.fillSpecific(ListView.java:1337)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.widget.ListView.layoutChildren(ListView.java:1608)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.widget.AbsListView.onLayout(AbsListView.java:2091)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.View.layout(View.java:14817)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.ViewGroup.layout(ViewGroup.java:4631)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.View.layout(View.java:14817)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.ViewGroup.layout(ViewGroup.java:4631)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:374)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.View.layout(View.java:14817)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.ViewGroup.layout(ViewGroup.java:4631)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.View.layout(View.java:14817)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.ViewGroup.layout(ViewGroup.java:4631)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1987)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1744)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.Choreographer.doCallbacks(Choreographer.java:574)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.Choreographer.doFrame(Choreographer.java:544)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.os.Handler.handleCallback(Handler.java:733)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.os.Handler.dispatchMessage(Handler.java:95)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.os.Looper.loop(Looper.java:136)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at android.app.ActivityThread.main(ActivityThread.java:5017)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at java.lang.reflect.Method.invokeNative(Native Method)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at java.lang.reflect.Method.invoke(Method.java:515)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
10-27 19:39:08.247: E/AndroidRuntime(1373):     at dalvik.system.NativeStart.main(Native Method)

最佳答案

getView类的yout ToDoListAdapater.java方法中使用此方法。

View todoView = LayoutInflater.from(mContext).inflate(R.layout.todo_item, parent, false);

也找不到convertView中的 View ,像这样使用todoView
final TextView titleView = (TextView) todoView.findViewById(R.id.titleView);

关于java - 将数据添加到ListView后崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26594742/

相关文章:

java - 为什么父类(super class)调用子类的重写方法?

android - 为多屏幕设计以及横向和纵向设计时使用的最佳布局是什么

android - 相机类型的 Camera.open() 和 setPreviewDisplay() 未定义

c# - 为 ListView 中的项目着色

带有复选框删除/获取行 ID 的 Android ListView

android - 在 ListView 上实现右/左滑动

java - 无法删除 HSQLDB 中的表

java - 线程中的junit断言引发异常

android - OpenCV 相机显示错误

java - 字体增大时 JPanel 问题