lundi 22 mai 2017

Android check box inside Listview from Custom Cursor Adapter

I am trying to implement a to do list so I am using a custom layout that contains a text view and check box inside a list view. I am using a list fragment and a custom cursor adapter that extends the cursor adapter. I want when I click to a check box to update my database, however I can not refresh my database properly and the list view does not work properly when I delete items. For example when I click on the check box the text gets strike through. When I delete an item the exact below item gets striked through without ticking the text box.

Here is my List fragment code :

public class ToDoListFragment extends ListFragment {

private AlertDialog alertWindow;
private DatabaseAdapt dbAdapter;
private Cursor cursor;
private ToDoCursorAdapter cursorAdapter;
private EditText taskNew;
private CheckBox cb;

public ToDoListFragment() {

    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View fragmentView = super.onCreateView(inflater,container,savedInstanceState);
    cb = (CheckBox) fragmentView.findViewById(R.id.toDoCheckBox);
    taskNew = new EditText(getActivity());
    setHasOptionsMenu(true);
    dbAdapter = new DatabaseAdapt(getActivity().getBaseContext());
    dbAdapter.open();
    cursor = dbAdapter.loadAllTasks();
    cursorAdapter = new ToDoCursorAdapter(getActivity().getBaseContext(),cursor,dbAdapter);
    setListAdapter(cursorAdapter);
    createAlertWindow();
    /*
    cb.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Cursor newCursor = dbAdapter.loadAllTasks();
            ToDoCursorAdapter adapter = (ToDoCursorAdapter)getListAdapter();
            adapter.changeCursor(newCursor);
            cursor=newCursor;
        }
    });
    */
    ge
    return fragmentView;
}

public void onStart(){

    super.onStart();
    registerForContextMenu(getListView());
}
public void onDestroy(){

    super.onDestroy();
    cursor.close();
    dbAdapter.close();

}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {

        super.onListItemClick(l, v, position, id);
        Cursor newCursor = dbAdapter.loadAllTasks();
        ToDoCursorAdapter adapter = (ToDoCursorAdapter)getListAdapter();
        adapter.changeCursor(newCursor);
        cursor=newCursor;



}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.menu_main,menu);
    super.onCreateOptionsMenu(menu, inflater);

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();
    if(id==R.id.add_button){
        taskNew.setText("");
        showAlertWindow();
        return  true;
    }
    return super.onOptionsItemSelected(item);
}

private void createAlertWindow () {

    AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());
    alertDialog.setTitle("Add a new Task");
    alertDialog.setView(taskNew);
    alertDialog.setPositiveButton("Add", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            String text = taskNew.getText().toString();
           // dbAdapter.open();
            dbAdapter.createTask(text,0);
            Cursor newCursor = dbAdapter.loadAllTasks();
            ToDoCursorAdapter adapter = (ToDoCursorAdapter) getListAdapter();
            adapter.changeCursor(newCursor);
            cursor = newCursor;
        }
    });
    alertDialog.setNegativeButton("Cancel",null);

    alertWindow = alertDialog.create();

}

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    MenuInflater menuInflater = getActivity().getMenuInflater();
    menuInflater.inflate(R.menu.long_press_menu,menu);
    MenuItem item = menu.findItem(R.id.editOption);
    item.setVisible(false);
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
    int rowNumber = menuInfo.position;
    cursor.moveToPosition(rowNumber);
    int id = cursor.getInt(cursor.getColumnIndex(DatabaseAdapt.TODO_ID));
    if (item.getItemId() == R.id.deleteOption){
        dbAdapter.deleteTask(id);
        Cursor newCursor = dbAdapter.loadAllTasks();
        ToDoCursorAdapter adapter = (ToDoCursorAdapter)getListAdapter();
        adapter.changeCursor(newCursor);
        cursor = newCursor;
        return true;

    }

    return super.onContextItemSelected(item);
}

public void showAlertWindow () {

    alertWindow.show();
}

}

and here is my Custom Adapter Code:

public class ToDoCursorAdapter extends CursorAdapter {

private  DatabaseAdapt adapter;

 public static class ViewRef {

   TextView text;
   CheckBox check;

 }

public ToDoCursorAdapter(Context context, Cursor cursor, DatabaseAdapt 
 databaseAdapt){
    super(context,cursor,0);
    this.adapter = databaseAdapt;

}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {

   ViewRef viewRef = new ViewRef();
    View convertView = LayoutInflater.from(context).inflate(R.layout.custom_item_todo,parent,false);
    convertView.setTag(viewRef);
    return convertView;
}

@Override
public void bindView(View view, Context context, final Cursor cursor) {
    ViewRef viewRef = (ViewRef) view.getTag();
    viewRef.text = (TextView) view.findViewById(toDoText);
    viewRef.check = (CheckBox) view.findViewById(R.id.toDoCheckBox);
    CheckBox cb = viewRef.check;
    //TextView toDoText = (TextView) view.findViewById(R.id.toDoText);
    //CheckBox toDoCheck = (CheckBox) view.findViewById(R.id.toDoCheckBox);
    cb.setTag(new Integer(cursor.getPosition()));
    String text = cursor.getString(cursor.getColumnIndex(DatabaseAdapt.TODO_TEXT));
    viewRef.text.setText(text);
    //boolean status = ((cursor.getInt(cursor.getColumnIndex(DatabaseAdapt.TODO_CHECKED)) == 1 ? true : false));
    //toDoText.setText(text);
    //toDoCheck.setChecked(status);
   // if (status){
      //  toDoText.setPaintFlags(toDoText.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
    //}
    CompoundButton.OnCheckedChangeListener changeListener = new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

            Integer pos = (Integer) buttonView.getTag();
          //  String currentPos = Integer.toString(pos);
            if(cursor.moveToPosition(pos)){
                int rowId = cursor.getInt(cursor.getColumnIndex(DatabaseAdapt.TODO_ID));
                if(isChecked){
                  adapter.updateTask(rowId,1);
                }
                else  if (!isChecked){
                    adapter.updateTask(rowId,0);
                }
            }
        }
    };
    cb.setOnCheckedChangeListener(changeListener);
   boolean status = ((cursor.getInt(cursor.getColumnIndex(DatabaseAdapt.TODO_CHECKED)) == 1 ? true : false));
    cb.setChecked(status);
    if(status){
        viewRef.text.setPaintFlags(viewRef.text.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
    }
}

}

and here is the custom layout that I inflate in the listview:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://ift.tt/nIICcg"
xmlns:tools="http://ift.tt/LrGmb4"
android:id="@+id/toDoContainer"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp">

<LinearLayout
    android:id="@+id/toDoItemContainer"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/toDoText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="0.75"
        android:layout_gravity="center_horizontal"
        android:inputType="text"
        android:textSize="20sp"
        android:focusableInTouchMode="false"
        android:focusable="false"
        android:clickable="false"
        android:textColor="#000000"
        android:hint="Enter a Task"/>

    <CheckBox
        android:id="@+id/toDoCheckBox"
        android:layout_width="0dp"
        android:layout_height="wrap_content"

        android:layout_weight="0.15" />


</LinearLayout>

I have searched a lot in the site for some similar solutions but could not make something to work since I am also a beginner. I am honestly asking for your help and for any direction as I have spent a lot time and still did not make it to work. Thanks in advance.




Aucun commentaire:

Enregistrer un commentaire