@AndroidDev2015
Начал изучать Android/Java

Как обновить ListView при нажатии CheckBox который находится в Custom SimpleCursorAdapter?

Хочу обновлять listview в активити каждый раз при нажатии checkbox, но при вызове метода updateTodo() из checkbox listener приложение не работает.

MainActivity
public class MainActivity extends ListActivity {


    private TodoDatabase dbHelper;
    //private static final int ACTIVITY_CREATE = 0;
    private static final int ACTIVITY_EDIT = 1;
    private static final int DELETE_ID = Menu.FIRST + 1;
    private Cursor cursor;
    private EditText mEditText;
    private Long RowId;

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

        this.getListView().setDividerHeight(2);
        dbHelper = new TodoDatabase(this);

        fillData();
        registerForContextMenu(getListView());

        mEditText = (EditText)findViewById(R.id.editTextNewTask);

        RowId = null;
        Bundle extras = getIntent().getExtras();

        RowId = (savedInstanceState == null) ? null
                : (Long) savedInstanceState
                .getSerializable(TodoDatabase.COLUMN_ID);
        if (extras != null) {
            RowId = extras.getLong(TodoDatabase.COLUMN_ID);
        }

        startService(new Intent(this, TimeService.class));
    }
    .........
    .........
        public void updateTodo(){
        fillData();
    }


    private void fillData() {
        cursor = dbHelper.getAllTodosListView();
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
        startManagingCursor(cursor);
        }

        String[] from = new String[] {TodoDatabase.COLUMN_ACHIEVED, TodoDatabase.COLUMN_SUMMARY,
                                        TodoDatabase.COLUMN_TIMESECONDS};
        int[] to = new int[] {R.id.checkBoxLabel, R.id.textViewLabel };

        // Теперь создадим адаптер массива и установим его для отображения наших
        // данных
        SimpleCursorAdapter notes = new MySimpleCursorAdapter(getApplicationContext(),
                R.layout.list_item, cursor, from, to, 0);

        notes.changeCursor(cursor);
        notes.notifyDataSetChanged();

        setListAdapter(notes);
    }


SimpleCursorAdapter
public class MySimpleCursorAdapter extends SimpleCursorAdapter {

    private Context context;
    private LayoutInflater mInflater;
    private CheckBox mCheckBox;
    private long xId;


    public MySimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
        super(context, layout, c, from, to, flags);
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        final View view = mInflater.inflate(R.layout.list_item, parent, false);
        return view;

    }

    @Override
    public void bindView(View view, final Context context, final Cursor cursor) {
        final TodoDatabase mDbHelper = new TodoDatabase(context);

        final TextView textView = (TextView)view.findViewById(R.id.textViewLabel);
        mCheckBox = (CheckBox)view.findViewById(R.id.checkBoxLabel);

        xId = Long.parseLong(cursor.getString(cursor.getColumnIndex(TodoDatabase.COLUMN_ID)));

textView.setText(cursor.getString(cursor.getColumnIndex(TodoDatabase.COLUMN_SUMMARY)));
        if (cursor.getString(cursor.getColumnIndex(TodoDatabase.COLUMN_TIMESECONDS)) != null) {
            if (cursor.getLong(cursor.getColumnIndex(TodoDatabase.COLUMN_TIMESECONDS)) > 0) {
                if (cursor.getLong(cursor.getColumnIndex(TodoDatabase.COLUMN_TIMESECONDS)) >
                        System.currentTimeMillis()) {
                } else if (cursor.getInt(cursor.getColumnIndex(TodoDatabase.COLUMN_ACHIEVED)) != 1){
                    textView.setTextColor(Color.parseColor("#FF0000"));
                }
            }
        }

        if (cursor.getInt(cursor.getColumnIndex(TodoDatabase.COLUMN_ACHIEVED)) == 1) {
            mCheckBox.setChecked(true);
            textView.setPaintFlags(textView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
            final Long mRowId = xId;

            mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    Long mXRowId = mRowId;
                    if (mCheckBox.isChecked()) {

                        TodoDatabase mDbHelper = new TodoDatabase(context);
                        mDbHelper.updateTodoAchieved(mXRowId, "1");

                        MainActivity ma = new MainActivity();
                        ma.updateTodo(); // Ошибка

                    } else if (!mCheckBox.isChecked()) {

                        TodoDatabase mDbHelper = new TodoDatabase(context);
                        mDbHelper.updateTodoAchieved(mXRowId, "0");

                        MainActivity ma = new MainActivity();
                        ma.updateTodo(); // Ошибка

                    }
                }
            });

        } else {
            mCheckBox.setChecked(false);
            textView.setPaintFlags(textView.getPaintFlags() & (~ Paint.STRIKE_THRU_TEXT_FLAG));
            final Long mRowId = xId;

            mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                Long mXRowId = mRowId;
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (mCheckBox.isChecked()){

                        TodoDatabase mDbHelper = new TodoDatabase(context);
                        mDbHelper.updateTodoAchieved(mXRowId, "1");

                        MainActivity ma = new MainActivity();
                        ma.updateTodo(); // Ошибка

                    } else if (!mCheckBox.isChecked()){

                        TodoDatabase mDbHelper = new TodoDatabase(context);
                        mDbHelper.updateTodoAchieved(mXRowId, "0");

                        MainActivity ma = new MainActivity();
                        ma.updateTodo(); // Ошибка

                    }
                }
            });
        }
    }
}
  • Вопрос задан
  • 1172 просмотра
Пригласить эксперта
Ответы на вопрос 2
artemgapchenko
@artemgapchenko
Ошибка у вас наверняка состоит в том, что падает NullPointerException на обращении к dbHelper, который на момент обращения к нему не инициализирован, так как инициализируется он в onCreate(), который не вызовется, так как вы, почему-то, создаете новый instance класса MainActivity.
Первое. Никогда не создавайте Activity, да и другие компоненты Андроид-приложения через конструкторы. Для создания компонентов есть механизм интентов.
Второе. В адаптере есть прекрасный метод notifyDataSetChanged(), который оповещает AdapterView, работающий с этим адаптером, о том, что данные обновились и неплохо бы перерисовать себя. Выкиньте
MainActivity ma = new MainActivity();
ma.updateTodo(); // Ошибка

и напишите там
notifyDataSetChanged();

P.S. У вас небольшая каша в голове. Советую почитать что-нибудь на тему Андроид-приложений. Начать можно с сайта Александра Климова или с книги "Программирование под Android. Для профессионалов" от Брайна Харди и Билла Филлипса (пусть название вас не смущает, там все подробно расписывается). Если есть английский на уровне чтения технической литературы (а он должен быть, вы как-никак программист), советую читать Харди-Филлипса в оригинале, и периодически заглядывать в официальную документацию, разделы "API Guides" и "Training".
Ответ написан
atetc
@atetc
Админ Android dev-s чата: https://goo.gl/8JKF1f
А не пора ли на RecyclerView переходить?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы