我實際上試圖做的是爲Sqlite SQL語句「創建表」創建自己的表單。我決定讓表格只接受一個且只有一個表格字段。我不知道sqlite可以創建一個複合(多列)主鍵,直到以後。無論如何,我可以在StackOverFlow上分享它。
好吧..我通過跟蹤Map數據結構中的TableRow-view-id和RadioButtons-view-id來解決這個問題。要返回所選RadioButton的值,我必須使用由每個RadioButton的onClickListener事件/方法設置的Activity類global /成員變量。
當然,我必須爲TableRow和RadioButton找到一個視圖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);
}
});
}
}