简体   繁体   中英

ListView Checked Checkboxes

I am creating an Android application for communication learning

I make a List of word, it is contains a CheckBoxes and TextView, TextView is to display the the word, the use of the CheckBox is to determine what item in the ListView that I selected.

I store the id of the word in SQLite with "submit" button. when i close and open the activity again i want to see the checked checkboxes but this code only save to my database but not show the selected item when i open the activity again

this is the Activity

public class PerkembanganLevel1 extends AppCompatActivity{

    private ContentDao contentDao;
    private ChildDao childDao;
    private Child anakYangDipilih;

    public Global global;

    private AssessmentDao assessmentDao;
    private Assessment assessment;

    String idYangSudahBisa;

    PerkembanganAdapter perkembanganAdapter = null;

    ContentHistory contentHistory;


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

        contentDao = new ContentDao(this);
        contentDao.open();

        childDao = new ChildDao(this);
        childDao.open();

        anakYangDipilih = ((Global) getApplicationContext()).getChild();

        idYangSudahBisa = anakYangDipilih.getLevel1();

        ArrayList<ContentHistory> listKataLevel1 = (ArrayList<ContentHistory>) contentDao.getAllWordByLevel(1);

        perkembanganAdapter = new PerkembanganAdapter(this, R.layout.list_perkembangan, listKataLevel1);

        ListView level1 =  findViewById(R.id.LVPlv1);
        level1.setAdapter(perkembanganAdapter);
        Log.i("listKataLevel1 ", String.valueOf(listKataLevel1));
        level1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                contentHistory = (ContentHistory) parent.getItemAtPosition(position);

            }
        });
        findViewById(R.id.BtnPLv1Submit).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                idYangSudahBisa = perkembanganAdapter.idYangSudahBisa();

                anakYangDipilih.getId();
                anakYangDipilih.setLevel1(idYangSudahBisa);
                anakYangDipilih.setCreatedBy(((Global) getApplicationContext()).getTherapist().getId());
                anakYangDipilih.setUpdatedBy(((Global) getApplicationContext()).getTherapist().getId());
                anakYangDipilih.setCreatedDate(new Date());
                anakYangDipilih.setUpdatedDate(new Date());
                anakYangDipilih = childDao.saveChild(anakYangDipilih);

                Toast.makeText(PerkembanganLevel1.this, "Perkembangan Anak pada level 1 Berhasil Diperbarui", Toast.LENGTH_SHORT).show();
            }
        });


    }

}

this is the adapter


public class PerkembanganAdapter extends ArrayAdapter<ContentHistory> {


    String idYangSudahBisa;

    private ChildDao childDao;
    private Child anakYangDipilih;

    public ArrayList<ContentHistory> contentHistories;

    public PerkembanganAdapter(Context context, int id, ArrayList<ContentHistory> contentHistories){
        super(context, id, contentHistories);
        this.contentHistories = new ArrayList<>();
        this.contentHistories.addAll(contentHistories);



        childDao = new ChildDao(getContext());
        childDao.open();

        anakYangDipilih = ((Global) context.getApplicationContext()).getChild();
        this.idYangSudahBisa = anakYangDipilih.getLevel1();

    }

    private class ViewHolder{
        TextView title;
        CheckBox checkBoxes;
    }

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

        ViewHolder viewHolder = null;
        if (convertView == null){
            LayoutInflater layoutInflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.list_perkembangan, null);

            viewHolder = new ViewHolder();
            viewHolder.title = convertView.findViewById(R.id.TVListPerkembangan);
            viewHolder.checkBoxes = convertView.findViewById(R.id.CBListPerkembangan);

            convertView.setTag(viewHolder);

            viewHolder.checkBoxes.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    CheckBox checkBox = (CheckBox) v;
                    ContentHistory contentHistory = (ContentHistory) checkBox.getTag();
                    contentHistory.setSelected(checkBox.isChecked());
                    if (checkBox.isChecked()){
                        idYangSudahBisa = idYangSudahBisa + ","+contentHistory.getId();
                        //Toast.makeText(getContext(), ""+idYangSudahBisa,Toast.LENGTH_SHORT).show();
                    } else {
                        idYangSudahBisa = idYangSudahBisa.replace(","+contentHistory.getId(), "");
                        //Toast.makeText(getContext(), ""+idYangSudahBisa,Toast.LENGTH_SHORT).show();
                    }

                }
            });



        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }


        ContentHistory contentHistory = contentHistories.get(position);
        viewHolder.title.setText(contentHistory.getTitle());

        viewHolder.checkBoxes.setChecked(contentHistory.getSelected());
        viewHolder.checkBoxes.setTag(contentHistory);


        return convertView;

    }

    public String idYangSudahBisa(){

        return this.idYangSudahBisa;
    }

}
...

There is no need for a submit button as you can update (toggele) the database in real time when the checkbox is clicked.

The important aspect is the addition of a method in ContentDao such as :-

public void toggleCheckedById(long id) {

    db.execSQL(
            "UPDATE " + TABLE_NAME +
                    " SET " + COLUMN_CHECKED + " = NOT  " + COLUMN_CHECKED +
                    " WHERE " + COLUMN_ID + "=?",
            new String[]{String.valueOf(id)}
    );
}
  • This equates to UPDATE the_table SET the_check_column = NOT the_check_column WHERE the_id_column =?
    • noting that ? is replaced (bound) using the 2nd paarmeter passed to execSQL which in this case is a String[] containing a single element which is the id of the row to be changed.

This can be called from the CheckBox's onClick passing the id extracted from the view's Tag.

Consider this cutdown version of your code :-

The database helper (perhaps your Global.java class) DatabaseHelper.java :-

public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "perkembangan.db";
    public static final int DBVERSION = 1;

    private static DatabaseHelper sInstance;

    private DatabaseHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
    }

    public static synchronized DatabaseHelper getInstance(Context context) {
        if (sInstance == null) {
            sInstance = new DatabaseHelper(context);
        }
        return sInstance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String createContentSQL = "CREATE TABLE IF NOT EXISTS " + ContentDao.TABLE_NAME +
        "(" +
                ContentDao.COLUMN_ID + " INTEGER PRIMARY KEY, " +
                ContentDao.COLUMN_NAME + " TEXT, " +
                ContentDao.COLUMN_CHECKED + " INTEGER DEFAULT 0" +
                ")";
        db.execSQL(createContentSQL);
        /* ADD SOME TESTING DATA WHEN THE DATABASE IS CREATED */
        ContentValues cv = new ContentValues();
        for (int i=0; i < 3; i++) {
            cv.clear();
            cv.put(ContentDao.COLUMN_NAME,"Name" + String.valueOf(i));
            db.insert(ContentDao.TABLE_NAME,null,cv);
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public static String qualifyColumnName(String table, String column) {
        return table + "." + column;
    }
}
  • Note that this adds 3 rows for testing.
  • You probably don't need this.

ContentDao.java (an interpretation thereof) :-

public class ContentDao {

    private static DatabaseHelper sInstance;
    private static SQLiteDatabase db;

    public static final String TABLE_NAME = "content";
    public static final String COLUMN_ID = BaseColumns._ID;
    public static final String QUALIFIEDCOLUMN_ID = DatabaseHelper.qualifyColumnName(TABLE_NAME,COLUMN_ID);
    public static final String COLUMN_NAME = "name";
    public static final String COLUMN_CHECKED = "checked";



    public ContentDao(Context context) {
        db =(sInstance = DatabaseHelper.getInstance(context)).getWritableDatabase();
    }

    public void toggleCheckedById(long id) {

        db.execSQL(
                "UPDATE " + TABLE_NAME +
                        " SET " + COLUMN_CHECKED + " = NOT  " + COLUMN_CHECKED +
                        " WHERE " + COLUMN_ID + "=?",
                new String[]{String.valueOf(id)}
        );
    }

    public SQLiteDatabase getDb() {
        return db;
    }

    public int updateCheckedById(ContentHistory ch) {
        ContentValues cv = new ContentValues();
        cv.put(COLUMN_CHECKED,ch.isChecked());
        return db.update(TABLE_NAME,cv,COLUMN_ID + "=?",new String[]{String.valueOf(ch.getId())});
    }

    public ArrayList<ContentHistory> getContentHistory() {
        ArrayList<ContentHistory> rv = new ArrayList<>();
        Cursor csr = db.query(TABLE_NAME,null,null,null,null,null,null);
        while (csr.moveToNext()) {
            rv.add(new ContentHistory(csr.getLong(csr.getColumnIndex(COLUMN_ID)),
                    csr.getString(csr.getColumnIndex(COLUMN_NAME)),
                    csr.getInt(csr.getColumnIndex(COLUMN_CHECKED))> 0)
            );
        }
        csr.close();
        return rv;
    }



    public class ContentHistory {
        private long id;
        private String name;
        private boolean checked;

        ContentHistory(long id, String name, boolean checked) {
            this.id = id;
            this.name = name;
            this.checked = checked;
        }

        public long getId() {
            return id;
        }

        public void setId(long id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public boolean isChecked() {
            return checked;
        }

        public void setChecked(boolean checked) {
            this.checked = checked;
        }
    }
}
  • NOTE for convenience the ContentHistory class has been included
  • name has been used instead of Title (didn't realise until later)
  • As said the important addition is the toggleCheckedById method.

PerkembanganAdapter.java

public class PerkembanganAdapter extends ArrayAdapter<ContentDao.ContentHistory> {

    ContentDao contentDao;


    public ArrayList<ContentDao.ContentHistory> contentHistories;

    public PerkembanganAdapter(Context context, int id, ArrayList<ContentDao.ContentHistory> contentHistories){
        super(context, id, contentHistories);
        contentDao = new ContentDao(context);
        this.contentHistories = new ArrayList<>();
        this.contentHistories.addAll(contentHistories);
        /*
        childDao = new ChildDao(getContext());
        childDao.open();

        anakYangDipilih = ((Global) context.getApplicationContext()).getChild();
        this.idYangSudahBisa = anakYangDipilih.getLevel1();

        */

    }

    private class ViewHolder{
        TextView title;
        CheckBox checkBoxes;
    }

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

        ViewHolder viewHolder;
        if (convertView == null){
            LayoutInflater layoutInflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.list_perkembangan, null);

            viewHolder = new ViewHolder();
            viewHolder.title = convertView.findViewById(R.id.TVListPerkembangan);
            viewHolder.checkBoxes = convertView.findViewById(R.id.CBListPerkembangan);

            convertView.setTag(viewHolder);

            viewHolder.checkBoxes.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    CheckBox checkBox = (CheckBox) v;
                    ContentDao.ContentHistory contentHistory = (ContentDao.ContentHistory) checkBox.getTag();
                    contentHistory.setChecked(checkBox.isChecked());
                    contentDao.toggleCheckedById(contentHistory.getId()); //<<<<< will update (toggle) database in real time
                    /* NOT NEEDED
                    if (checkBox.isChecked()){
                        //idYangSudahBisa = idYangSudahBisa + ","+contentHistory.getId();
                        //Toast.makeText(v.getContext(), ""+idYangSudahBisa,Toast.LENGTH_SHORT).show();
                    } else {
                        //idYangSudahBisa = idYangSudahBisa.replace(","+contentHistory.getId(), "");
                        //Toast.makeText(getContext(), ""+idYangSudahBisa,Toast.LENGTH_SHORT).show();
                    }
                     */
                }
            });
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        ContentDao.ContentHistory contentHistory = contentHistories.get(position);
        viewHolder.title.setText(contentHistory.getName());
        viewHolder.checkBoxes.setChecked(contentHistory.isChecked());
        viewHolder.checkBoxes.setTag(contentHistory);
        return convertView;
    }
}
  • Note much of the original code has been commeneted out and just the important code needed to demonstrate has been left in.
  • Names that appear to be foreign language names have also been omitted/changed for convenience.
  • Obviously the code will have to be adapted to suit. It is the technique that is being demonstrated.

PerkembanganLevel1.java the Activity :-

public class PerkembanganLevel1 extends AppCompatActivity{

    private ContentDao contentDao;
    private ListView level1;
    private PerkembanganAdapter perkembanganAdapter;
    private ArrayList<ContentDao.ContentHistory> contentHistory;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_perkembangan_level1);
        level1 = this.findViewById(R.id.level1);

        contentDao = new ContentDao(this);
        manageListView();

        /*contentDao.open();

        childDao = new ChildDao(this);
        childDao.open();

        anakYangDipilih = ((Global) getApplicationContext()).getChild();

        idYangSudahBisa = anakYangDipilih.getLevel1();

         */

        /*
        ArrayList<ContentDao.ContentHistory> listKataLevel1 = (ArrayList<ContentDao.ContentHistory>) contentDao.getAllWordByLevel(1);

        perkembanganAdapter = new PerkembanganAdapter(this, R.layout.list_perkembangan, listKataLevel1);

        //ListView level1 =  findViewById(R.id.LVPlv1);
        level1.setAdapter(perkembanganAdapter);
        Log.i("listKataLevel1 ", String.valueOf(listKataLevel1));
        level1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                contentHistory = (ContentDao.ContentHistory) parent.getItemAtPosition(position);

            }
        });
        findViewById(R.id.BtnPLv1Submit).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                idYangSudahBisa = perkembanganAdapter.idYangSudahBisa();

                anakYangDipilih.getId();
                anakYangDipilih.setLevel1(idYangSudahBisa);
                anakYangDipilih.setCreatedBy(((Global) getApplicationContext()).getTherapist().getId());
                anakYangDipilih.setUpdatedBy(((Global) getApplicationContext()).getTherapist().getId());
                anakYangDipilih.setCreatedDate(new Date());
                anakYangDipilih.setUpdatedDate(new Date());
                anakYangDipilih = childDao.saveChild(anakYangDipilih);

                Toast.makeText(PerkembanganLevel1.this, "Perkembangan Anak pada level 1 Berhasil Diperbarui", Toast.LENGTH_SHORT).show();
            }
        });

         */

    }

    /* Will refresh the Listview when returning from an invoked activity just in case data has changed */
    @Override
    protected void onResume() {
        super.onResume();
        manageListView();
    }

    private void manageListView() {
        contentHistory = contentDao.getContentHistory();
        if (perkembanganAdapter == null) {
            perkembanganAdapter = new PerkembanganAdapter(this,R.layout.list_perkembangan,contentHistory);
            level1.setAdapter(perkembanganAdapter);

        } else {
            perkembanganAdapter.notifyDataSetChanged(); // Not really needed if updating when checked
        }
    }
}

Demo results

When first run :-

在此处输入图片说明

Second Run row 2 ticked and then restarted

在此处输入图片说明

Third Run all 3 checkeck boxes reversed and then restarted

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM