What I am in fact trying to do is to make my own form for the Sqlite SQL sentence "Create Table" . I decided to make the form accept only one and only one table field to be primary. I didn't know that sqlite can make a composite (multi-column) primary key until later. Anyways, it's OK that I did this to share it on StackOverFlow.
Well.. I solved it by keeping track of the TableRow-view-ids and the RadioButtons-view-ids in a Map data structure. To return the value of the selected RadioButton, I had to use an Activity class global/member variable that's set by the onClickListener event/method of each RadioButton .
Of course I had to find a view id generator method for the TableRow and the RadioButton. It's in StackOverFlow here. For every TableRow and for every RadioButton there, The view id generator will be used to set their view ids. And this way I can keep track of every TableRow and for every RadioButton on the display.
//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();
}
}
}
SO this is my FAKE RadioGroup. Let's start..
So we start with this XML Layout. I am going to make it simpler by removing the rest of the widgets so you won't be confused by them. Please Read the comments in the 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>
Now we go to the Java code. Read the comments. Many of the variable names are , hopefully, clear. No need to put comments for them.
/**
*
*/
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);
}
});
}
}