如何以编程方式将所有单选按钮重新分组到运行时以编程方式添加的表行?每个TableRow必须有1个RadioButton

时间:2014-10-01 10:45:07

标签: android grouping android-radiobutton

我有一个表格布局,用在java中创建的表格行来充气。现在,每一行都必须有一个RadioButton。我有一个按钮,每次单击时都会添加一个表格行。在添加行时,必须检查一个且仅一个单选按钮。您看到的RadioButtons会在运行时动态添加。所以我问的是如何保持我的RadioButton选择独特?必须使用单选按钮检查一行且仅一行。

这就是我在这个ASCII艺术素描中的意思:

TableRow EditText (RadioButton) Spinner ../TableRow

TableRow EditText (RadioButton) Spinner ../TableRow

TableRow EditText (RadioButton) Spinner ../TableRow

TableRow EditText (RadioButton) Spinner ../TableRow

TableRow EditText (RadioButton) Spinner ../TableRow

我担心的是RadioButtons不会被分组。这就是我要找的东西:将草图中的RadioButtons分组。

1 个答案:

答案 0 :(得分:0)

我实际上要做的是为Sqlite SQL语句“Create Table”创建自己的表单。我决定让表单只接受一个且只有一个表字段为主要字段。我不知道sqlite可以制作复合(多列)主键,直到以后。无论如何,我可以在StackOverFlow上分享它。

嗯..我通过在Map数据结构中跟踪TableRow-view-id和RadioButtons-view-id来解决它。要返回所选RadioButton的值,我必须使用由每个RadioButton的onClickListener事件/方法设置的Activity类全局/成员变量。

当然,我必须为TableRow和RadioButton找到一个view id生成器方法。这是在StackOverFlow中。对于每个TableRow和每个RadioButton,视图id生成器将用于设置其视图ID。通过这种方式,我可以跟踪每个TableRow以及显示器上的每个RadioButton。

//put this class in a separate Java source code file.
//so you can access it any time from anywhere in your project.
public class UtilityClass {

    private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);


    @SuppressLint("NewApi")
    public static int generateViewId() {

        if (Build.VERSION.SDK_INT < 17) {
            for (;;) {
                final int result = sNextGeneratedId.get();
                // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
                int newValue = result + 1;
                if (newValue > 0x00FFFFFF)
                    newValue = 1; // Roll over to 1, not 0.
                if (sNextGeneratedId.compareAndSet(result, newValue)) {
                    return result;
                }
            }
        } else {
            return View.generateViewId();
        }

    }
}

这是我的 FAKE RadioGroup。我们开始......

所以我们从这个XML布局开始。我将通过删除其余的小部件来简化它,这样你就不会被它们搞糊涂了。请阅读XML中的注释。

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

    <!--Button to add a new TableRow at runtime every time it gets clicked -->
    <Button
        android:id="@+id/add_new_field_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/add_new_field"
        android:textSize="12sp" />

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

        <ScrollView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >

            <TableLayout
                android:id="@+id/table_fields_tablelayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >

             <!-- New Dynamically added TableRows will be added to below this TableRow @+id/field_headers_tablerow -->
                <TableRow
                    android:id="@+id/field_headers_tablerow"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" >

            <!-- Both TextViews here represent table headers only-->

            <!--Below this TextView there will be table field names -->

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:padding="10dp"
                        android:text="@string/field_name"
                        android:textSize="12sp" />


            <!--Below this TextView there will be RadioButtons -->

                     <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:padding="10dp"
                        android:text="@string/primary_key"
                        android:textSize="12sp" />

                </TableRow>

            </TableLayout>
        </ScrollView>
    </HorizontalScrollView>

</TableLayout>

现在我们转到Java代码。阅读评论。许多变量名称有望清楚。无需为他们发表评论。

/**
 * 
 */
package net.superlinux.sqlitestudio;

import java.util.HashMap;
import java.util.Map;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TableLayout;
import android.widget.TableRow;

/**
 * @author oracle
 *
 */
public class CreateTableForm extends Activity {

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */

    /*
     * The Create Table form layout to create an SQLite table and to generate the SQL "Create Table" statement
     * 
     * TableRow EditText (RadioButton) Spinner ../TableRow
     * TableRow EditText (RadioButton) Spinner ../TableRow
     * TableRow EditText (RadioButton) Spinner ../TableRow
     * TableRow EditText (RadioButton) Spinner ../TableRow
     * .
     * .
     * .
     * TableRow EditText (RadioButton) Spinner ../TableRow
     * 
     * (RadioButton) is 
     */
    Button add_new_field_button;
    TableLayout table_fields_tablelayout;

    //this will hold tablerow_view_id of the corresponding checked radiobutton 
    int checked_primary_key_radio_button_view_id=0;

    //the mapping is the generated tablerow_view_id vs it's corresponding field name values.
    //each programmatically generated <TableRow> will mean a table field in the SQL sentence of 'Create Table ...' 
    Map<Integer, String> field_names_list=new HashMap<Integer, String>();

    //each primary key is having a radio button. it will have a generated viewid. 
    //this view id is set as the value side of the Map field_names_is_primary_key_radiobuttons_view_ids whose key is tablerow_view_id
    //this is used to set the

    Map<Integer, Integer> field_names_is_primary_key_radiobuttons_view_ids=new HashMap<Integer, Integer>();


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.create_table_form); // TODO Auto-generated
                                                    // method stub
         add_new_field_button=(Button)findViewById(R.id.add_new_field_button);

         table_fields_tablelayout=(TableLayout)findViewById(R.id.table_fields_tablelayout);

         add_new_field_button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                //Prepare a TableRow to be inflated.
                TableRow tr=new TableRow(CreateTableForm.this);
                tr.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
                final int tablerow_view_id=UtilityClass.generateViewId();
                tr.setId(tablerow_view_id);

                //Adding field name
                final EditText field_name = new EditText(CreateTableForm.this);
                field_name.setLayoutParams(new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
                field_name.setTextSize(12);
                field_name.setHint(R.string.field_name);
                field_name.addTextChangedListener(new TextWatcher() {

                    @Override
                    public void onTextChanged(CharSequence s, int start, int before, int count) {
                        // TODO Auto-generated method stub
                    field_names_list.put(tablerow_view_id, field_name.getText().toString());
                    }

                    @Override
                    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void afterTextChanged(Editable s) {
                        // TODO Auto-generated method stub

                    }
                });
                tr.addView(field_name);


                //Create a new RadioButton
                RadioButton primary_key_radiobutton=new RadioButton(CreateTableForm.this);
                primary_key_radiobutton.setChecked(false);
                primary_key_radiobutton.setLayoutParams(new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));

                //generate the RadioButton a unique viewId
                int radiobutton_view_id=UtilityClass.generateViewId();
                primary_key_radiobutton.setId(radiobutton_view_id);

                //use this Map to say that this RadioButton belongs to this current TableRow 
                // this is done by referring to both using the view ids of each
                field_names_is_primary_key_radiobuttons_view_ids.put(tablerow_view_id, radiobutton_view_id);

                primary_key_radiobutton.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        //checked_primary_key_radio_button_view_id is a (global/Activity class member) variable. 
                        //And this area of the code is added to every RadioButton in the layout to set the event onClickListener.
                        //so whenever any of the RadioButton's gets clicked it will change the variable checked_primary_key_radio_button_view_id 
                        //and remeber that this will be a common value to the whole activity. 
                        //so this is how you get the return value of the selected RadioButton
                        checked_primary_key_radio_button_view_id=tablerow_view_id;

                        //this is used to monitor which radio is for which table row
                        Log.e("radio button at tablerow=", ""+tablerow_view_id);

                        //this is where the fake RadioGroup happens
                        //we uncheck all the rest of RadioButton's by using their view ids. we skip the current one. 
                        for (int tablerow_view_id_as_key : field_names_is_primary_key_radiobuttons_view_ids.keySet()){
                            int radiobutton_view_id_as_value=field_names_is_primary_key_radiobuttons_view_ids.get(tablerow_view_id_as_key);
                            if (v.getId()!=radiobutton_view_id_as_value){       
                                ((RadioButton)findViewById(radiobutton_view_id_as_value)).setChecked(false);
                                }
                        }

                    }
                });
                tr.addView(primary_key_radiobutton);


                table_fields_tablelayout.addView(tr);               

            }
        });
    }

}