3

I have a page that returns a list of items backs from a database. I want to add each item to my android fragment as a checkbox dynamically with an onClick, that can tell if an item is being checked or un-checked.

How can I add checkboxes dynamically with on-clicks and different titles for each?

Below is the xml I am inserting the checkboxes into:

<?xml version="1.0" encoding="utf-8"?>

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:background="#e5e5e5"

    android:layout_height="match_parent" >

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >




        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="6dp"
                android:layout_marginRight="6dp"
                android:layout_marginTop="4dp"
                android:layout_marginBottom="4dp"
                android:orientation="vertical"
                android:background="@drawable/bg_card">

                <!-- Card Contents go here -->


                <TextView
                    android:id="@+id/styleDescription"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:ems="10"
                    android:textSize="15sp"
                    android:padding="5dip"

                    ></TextView>

                <CheckBox
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="New CheckBox"
                    android:id="@+id/checkBox" />


            </LinearLayout >

        </FrameLayout>

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="6dp"
                android:layout_marginRight="6dp"
                android:layout_marginTop="4dp"
                android:layout_marginBottom="4dp"
                android:orientation="horizontal"
                android:background="@drawable/bg_card">

                <!-- Card Contents go here -->

                <Button
                    android:id="@+id/buttonAddList"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Create List"

                    style="?android:attr/borderlessButtonStyle"
                    android:textColor="@color/orange"
                    android:textStyle="bold"
                    />




            </LinearLayout >

        </FrameLayout>







    </LinearLayout>

</ScrollView>

I currently have one checkbox in the above code. I plan on removing this. That checkbox is just to show where I want my check boxes to show up.

3 Answers 3

3

What you need to do first is add an id to your LinearLayout (in that XML file), the one which is going to hold the CheckBoxes. Then, in the code you need to get that LinearLayout by its id and use addView() to add CheckBoxes that you create dynamically. I imagine in pseudocode it'd look like this:

for (int i = 0; i < numberOfCheckBoxes; i++) {

    CheckBox checkBox = new CheckBox();
    checkBox.setTitle("Your title");
    checkBox.setOnClickListener(new OnClickListener() {

        // Your code to be executed on click
    });

    linearLayout.addView(checkBox);
}

Does this help?

PS: It'd be nice if you kept your code clean - ADT (and I believe Eclipse too) gives you the Shift+Ctrl+F shortcut to indent your code automatically - use it as often as possible ;)

Sign up to request clarification or add additional context in comments.

2 Comments

just where would I throw the onclick listener? at the end of my async task?
I'm not sure how to answer that; maybe I'd be able to if I could see more code but I can't promise anything. What exactly is the problem here? Couldn't you set the listener at the time you create the CheckBox object instances, as in the example I provided?
0

Since you are processing database items, I suggest using a CursorAdapter to do the heavy work for you. A CursorAdapter, like any of the Adapter classes can process the database items and custom-fit them into a layout of your choice, to use in a ListView.

You have to make adjustments to your code:

  • Create a layout file that contains whatever you want to put in the dynamic list. This is an example, say it's named list_contents.xml:

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="6dp"
            android:layout_marginRight="6dp"
            android:layout_marginTop="4dp"
            android:layout_marginBottom="4dp"
            android:orientation="vertical"
            android:background="@drawable/bg_card">
    
            <!-- Card Contents go here -->
    
    
            <TextView
                android:id="@+id/styleDescription"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:ems="10"
                android:textSize="15sp"
                android:padding="5dip"
    
                ></TextView>
    
            <CheckBox
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="New CheckBox"
                android:id="@+id/checkBox" />
    
    
        </LinearLayout >
    
    </FrameLayout>
    
  • Then, instead of returning a List from your AsyncTask, return the Cursor itself
    from your database. This Cursor will be processed by CursorAdapter. I recommend this guide:
    http://www.gustekdev.com/2013/05/custom-cursoradapter-and-why-not-use.html

  • Implement the CursorAdapter methods:

In your implementation of newView(), inflate list_contents.xml (Note that if you use ResourceCursorAdapter you wouldn't need to do this)

In your implementation of CursorAdapter.bindView() do this:

CheckBox checkbox = (CheckBox) view.findViewById(R.id.checkbox);
checkbox.setText(cursor.getString(cursor.getColumnIndex(YOUR_DATABASE_COLUMN_NAME_FOR_CHECKBOX_VALUES)));
checkbox.setOnCheckedChangedListener(listenerInitializedSomewhereFromFragmentCode);
  • Change your ScrollView to a ListView (it can be inside any Layout), and give it an id, say R.id.listview.

  • Finally, in the part where you process the List from the database, where we now have a Cursor instead, just do this:

    CustomCursorAdapter cca = new CustomCursorAdapter(getActivity(), resultFromDatabase, 0); listView.setAdapter(cca);

Note: getActivity() is for when you are working inside a Fragment. It should be a context, so inside an Activity it can just be "this".

Note2: listView should have been initialized at this point via findViewById.

Note3: If listView already has an Adapter and Cursor set, you should consider calling listView.getAdapter().changeCursor() instead.

Comments

0

Simple Code In Kotlin

    fun createCheckbox() {
    var arr_cb = arrayOfNulls<CheckBox>(checkbox_size)
    val layout = findViewById<View>(R.id.layout_checkbox) as ViewGroup
    val ll = LinearLayout(this)
    ll.orientation = LinearLayout.VERTICAL

    for (i in 0 until arr_cb.size) {
        arr_cb[i] = CheckBox(this)
        arr_cb[i]?.text = health_status.get(i).toString()
        arr_cb[i]?.setPadding(25, 0, 0, 0)
        arr_cb[i]?.id = i
        arr_cb[i]?.tag = health_status[i]
        arr_cb[i]?.setTextColor(resources.getColor(R.color.title_color))
        arr_cb[i]?.setOnCheckedChangeListener(
            arr_cb[i]?.let {
                handleCheck(it)
            })

        arr_cb[i]?.buttonTintList =
            ColorStateList.valueOf(resources.getColor(R.color.theme_color))
        ll.addView(arr_cb[i])
    }
    layout.addView(ll)
}

handleCheck method

    private fun handleCheck(chk: CheckBox): CompoundButton.OnCheckedChangeListener? {
    return object : CompoundButton.OnCheckedChangeListener {
        override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
            if (!isChecked) {
                //uncheck
            } else {
                //check
            }
        }
    }
}

and you want to do something use direct checkboxList object like as

val layout = findViewById<View>(R.id.layout_checkbox) as ViewGroup
    val ll = LinearLayout(this@MedicalHistoryActivity)
    ll.orientation = LinearLayout.VERTICAL
    for (i in 0 until health_status.size) {
        arr_cb[i]?.isEnabled = true
        // do something like change color or more
    }
    layout.addView(ll)

for enable checkbox or more.

Thank you

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.