mardi 21 novembre 2017

Get the Id of a checkbox inside a Listview based on CursorAdapter

I searched trough a lot of posts and tutorials but could not find an answer yet - maybe I just didn't recognize the correct way as I am new to android.

My App is a To Do List with an SQL Database behind. There are 3 fragments which are populated by a Cursor Loader. Each List Item contains a TextView and a Checkbox, both based on the SQL Database. Now I want to change a SQL Value after checking the Checkbox (It's a 0 for unchecked, 1 for checked). I got it working if I click on the right Listitem but I not yet for a specific Checkbox as I can not get the right ID and right now I get a Nullpointer because I can not find the right Checkbox for each ListItem.

In short: I want the specific Checkbox to do what the whole ListItem is doing right now

I can provide more code if needed

I am thankful for each critic or suggestion.

public class TagSeite extends Fragment {

    public static final int URI_LOADER_TAG = 0;
    TagCursorAdapter mTagCursorAdapter;
    public EditText mTextEingabeTag;



    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        inflater = getActivity().getLayoutInflater();


        final View rootView = inflater.inflate(R.layout.fragment_tag_seite, container, false);
        setHasOptionsMenu(true);


        ListView tagListView = (ListView) rootView.findViewById(R.id.tag_list_view);
        registerForContextMenu(tagListView);


        //den Cursor Adapter erschaffen (Objekt Instanz)
        mTagCursorAdapter = new TagCursorAdapter(getActivity(), null);
        //diesen Adapter auf die ListView jagen
        tagListView.setAdapter(mTagCursorAdapter);

        tagListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, final long id) {
                checkBoxHandler(id);

            }
        });

        CheckBox cbx = (CheckBox) tagListView.findViewById(R.id.abgehakt_tag);
        cbx.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getContext(), "Checkbox", Toast.LENGTH_SHORT).show();
            }
        });



        return rootView;


    }


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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_add:

                LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getContext());
                View mView = layoutInflaterAndroid.inflate(R.layout.user_input_dialog_box, null);
                AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(getContext());
                alertDialogBuilderUserInput.setView(mView);

                //View finden, die man für Userinput braucht
                //Wird erst initialisiert, wenn die View mit dem EditText offen ist (sonst Nullpointer Error)
                mTextEingabeTag = (EditText) mView.findViewById(R.id.textEingabe);

                alertDialogBuilderUserInput
                        .setCancelable(false)
                        .setPositiveButton("eintragen", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialogBox, int id) {
                                insertData();
                            }
                        })

                        .setNegativeButton("abbrechen",
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialogBox, int id) {
                                        dialogBox.cancel();
                                    }
                                });

                AlertDialog alertDialogAndroid = alertDialogBuilderUserInput.create();
                alertDialogAndroid.show();

        }



        return super.onOptionsItemSelected(item);
    }

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


        //den loader initialisieren
        getLoaderManager().initLoader(URI_LOADER_TAG, null, LoaderGesamtListenerTag);
        //getLoaderManager().initLoader(URI_LOADER_FUER_ALERTDIALOG, null, LoaderDialogListener);

    }



    //Lange auf ein Item drauf halten
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.setHeaderTitle("Was willst du tun?");
        final int ändernTagSeite = 1;
        final int löschenTagSeite = 2;
        menu.add(0, ändernTagSeite, 0, "Ändern");
        menu.add(0, löschenTagSeite, 0, "Löschen");
        /*
        menu.add(0, v.getId(), 0, "ändern");
        menu.add(0, v.getId(), 0, "Löschen");
         */
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        //info.position will give the index the selected Item

        //if (item.getTitle() == "ändern")

        switch (item.getItemId()) {

            case 1:
            //kleines pop-Up für den UserInput erschaffen
            LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getContext());
            View mView = layoutInflaterAndroid.inflate(R.layout.user_input_dialog_box, null);
            AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(getContext());
            alertDialogBuilderUserInput.setView(mView);
            TextView dialogTitle = (TextView) mView.findViewById(R.id.dialogTitle);
            dialogTitle.setText(R.string.alterDialogBoxUpdaten);
            //View finden, die man für Userinput braucht
            //Wird erst initialisiert, wenn die View mit dem EditText offen ist (sonst Nullpointer Error)
            mTextEingabeTag = (EditText) mView.findViewById(R.id.textEingabe);
            long id = mTagCursorAdapter.getCursor().getInt(0);

            Toast.makeText(getContext(), "id=" + id, Toast.LENGTH_SHORT).show();

            //int id2 = (int)id;
            Uri currentUri = ContentUris.withAppendedId(Contract.TabellenEigenschaften.CONTENT_URI_TAG, id);
            String currentString = "";
            Toast.makeText(getContext(), "uri: " + currentUri,
                    Toast.LENGTH_SHORT).show();
            //!!DAS HAT NUR 20 stunden gedauert
            //dieser cursor weiß dank der currentUri schon, was er will und muss nur noch mittels .query an die datenbank geschickt werden
            //Zurück kommt ein "geladener" Cursor, der dann auch nur einen Eintrag enthält
            //dieser wird ausgelesen und fertig
            Cursor cursor2 = getContext().getContentResolver().query(currentUri, null, null, null, null);
            if (cursor2.moveToFirst()) {
                currentString = cursor2.getString(cursor2.getColumnIndex(Contract.TabellenEigenschaften.SPALTE_EINS_TAG));
            }
            //die TextView mit dem SQL Wert füllen
            mTextEingabeTag.setText(currentString);
                mTextEingabeTag.setSelection(mTextEingabeTag.getText().length());
                cursor2.close();


            alertDialogBuilderUserInput
                    .setCancelable(false)
                    .setPositiveButton("updaten", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialogBox, int id) {

                            //Hier wird eine neue currentUri gebaut, die schon die richtige Position(id) des aktuellen DB Eintrages hat
                            long idUpdate = mTagCursorAdapter.getCursor().getInt(0);
                            Uri currentUriUpdate = ContentUris.withAppendedId(Contract.TabellenEigenschaften.CONTENT_URI_TAG, idUpdate);
                            //String aus der Textbox rausziehen und trimmen(überfl. abschneiden)
                            String updateString = mTextEingabeTag.getText().toString().trim();
                            //neue Values eintragen
                            ContentValues updateValues = new ContentValues();
                            updateValues.put(Contract.TabellenEigenschaften.SPALTE_EINS_TAG, updateString);
                            //Hier wird dann geupdated mit aktueller Uri und dem String Wert
                            int rowsAffected = getContext().getContentResolver().update(currentUriUpdate, updateValues, null, null);
                            if (rowsAffected == 0) {
                                // If no rows were affected, then there was an error with the update.
                                Toast.makeText(getContext(), "MIES gelaufen",
                                        Toast.LENGTH_SHORT).show();
                            } else {
                                // Otherwise, the update was successful and we can display a toast.
                                Toast.makeText(getContext(), "erfolgreich geupdated",
                                        Toast.LENGTH_SHORT).show();
                            }
                        }
                    })

                    .setNegativeButton("abbrechen",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialogBox, int id) {
                                    dialogBox.cancel();
                                }
                            });


            AlertDialog alertDialogAndroid = alertDialogBuilderUserInput.create();
            alertDialogAndroid.show();

                break;


        //} else if (item.getTitle() == "Löschen") {

            case 2:
            //Anscheinend (es ist 2 uhr nachts), kann man die id des jeweils angeklickten items finden
            //indem man den Cursor drauf los lässt und nach dem Eintrag in der nullten Spalte, also id spalte fragt. voll einfach
            long id2 = mTagCursorAdapter.getCursor().getInt(0);
            Uri currentUri2 = ContentUris.withAppendedId(Contract.TabellenEigenschaften.CONTENT_URI_TAG, id2);
            //Löschen, falls Uri akzeptabel
            if (currentUri2 != null) {
                int mRowsDeleted = getContext().getContentResolver().delete(currentUri2, null, null);
                if (mRowsDeleted == 1) {
                    Toast.makeText(getContext(), "erfolgreich gelöscht", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(getContext(), "etwas ist nicht gut gegangen", Toast.LENGTH_SHORT).show();
                }
            }
            break;
        }
        return super.onContextItemSelected(item);
    }



    //Helper method um alle Einträge zu löschen
    private void deleteAllEntries() {
        int rowsDeleted = getContext().getContentResolver().delete(Contract.TabellenEigenschaften.CONTENT_URI_TAG, null, null);
        Toast.makeText(getContext(), "Es wurden " + rowsDeleted + " Einträge gelöscht", Toast.LENGTH_SHORT).show();
    }

    public void insertData() {
        //sog. trim schneidet überflüssige Daten heraus
        String spalteEinsString = mTextEingabeTag.getText().toString().trim();
        int checkboxInt = 0;

        //neue Values eintragen
        ContentValues values = new ContentValues();
        values.put(Contract.TabellenEigenschaften.SPALTE_EINS_TAG, spalteEinsString);
        values.put(Contract.TabellenEigenschaften.SPALTE_ZWEI_TAG, checkboxInt);

        //mit der richtigen Uri die Werte in die Datenbank einfügen (Content Uri + aktuelle values)
        Uri newUri = this.getContext().getContentResolver().insert(Contract.TabellenEigenschaften.CONTENT_URI_TAG, values);

        //Bestätigung / Error
        if (newUri == null) {
            Toast.makeText(getContext(), "Versag auf Tagt", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(getContext(), "Wurde notiert", Toast.LENGTH_SHORT).show();
        }
    }

    public void checkBoxHandler(long idTemp) {
        int istAbgehaktIndex = mTagCursorAdapter.getCursor().getColumnIndex(Contract.TabellenEigenschaften.SPALTE_ZWEI_TAG);
        int inhalt_spalte_zwei = mTagCursorAdapter.getCursor().getInt(istAbgehaktIndex);

        if (inhalt_spalte_zwei == 1) {
            insertCheckboxValue0(idTemp);
        } else {
            insertCheckboxValue1(idTemp);
        }
    }

    public void insertCheckboxValue0(long id) {
        int checkboxInt = 0;
        //neue Values eintragen
        ContentValues values = new ContentValues();
        values.put(Contract.TabellenEigenschaften.SPALTE_ZWEI_TAG, checkboxInt);
        Uri currentUriCheckbox0 = ContentUris.withAppendedId(Contract.TabellenEigenschaften.CONTENT_URI_TAG, id);

        //mit der richtigen Uri die Werte in die Datenbank einfügen (Content Uri + aktuelle values)
        int rowsAffected = getContext().getContentResolver().update(currentUriCheckbox0, values, null, null);

        //Bestätigung / Error
        if (rowsAffected == 0) {
            Toast.makeText(getContext(), "Versagt, nichts bei SQL passiert", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(getContext(), "Checkbox + SQL geändert!", Toast.LENGTH_SHORT).show();
        }

    }


    public void insertCheckboxValue1(long id) {
        int checkboxInt = 1;
        //neue Values eintragen
        ContentValues values = new ContentValues();
        values.put(Contract.TabellenEigenschaften.SPALTE_ZWEI_TAG, checkboxInt);
        Uri currentUriCheckbox1 = ContentUris.withAppendedId(Contract.TabellenEigenschaften.CONTENT_URI_TAG, id);

        //mit der richtigen Uri die Werte in die Datenbank einfügen (Content Uri + aktuelle values)
        int rowsAffected = getContext().getContentResolver().update(currentUriCheckbox1, values, null, null);

        //Bestätigung / Error
        if (rowsAffected == 0) {
            Toast.makeText(getContext(), "Versagt, nichts bei SQL passiert", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(getContext(), "GUT GEMACHT! (SQL geändert)", Toast.LENGTH_SHORT).show();
        }

    }

    public LoaderManager.LoaderCallbacks<Cursor> LoaderGesamtListenerTag
            = new LoaderManager.LoaderCallbacks<Cursor>() {

        @Override
        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
            String[] projection = {
                    Contract.TabellenEigenschaften.SPALTE_EINS_TAG,
                    Contract.TabellenEigenschaften.SPALTE_ZWEI_TAG,};

            CursorLoader loader = new CursorLoader(getContext(),
                    Contract.TabellenEigenschaften.CONTENT_URI_TAG,
                    projection,
                    null,
                    null,
                    null);
            return loader;

        }

        @Override
        public void onLoaderReset(Loader<Cursor> loader) {
            mTagCursorAdapter.swapCursor(null);
        }

        @Override
        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
            mTagCursorAdapter.swapCursor(data);
        }
    };

}




Aucun commentaire:

Enregistrer un commentaire