I am working on an app that uses 5 tabs and each tab has a different fragment. In all of these fragments I have from 1 up to 10 dynamically created tablelayouts and each one of them can have as many rows as the user wants. Each row may have up to 16 columns of EditText, Spinner, Checkbox. My problem is that when I rotate my phone I lose all the data inside these tablelayouts. My ViewPagerAdapter that hosts these fragments extends FragmentStatePagerAdapter. I am not losing any data outside the tables. I understand that when I rotate the phone they are recreated but I want to keep my data. I do not want to create a database because when I finish adding data in my app I want to save everything to a .txt file. This is code for one of my tables
table18 = (TableLayout) view.findViewById(R.id.blg_parameter18_table);
TableRow.LayoutParams tlparams18 = new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT);
//Create header
TableRow table18HeaderRow = new TableRow(view.getContext());
table18HeaderRow.setLayoutParams(tlparams18);
TextView table18HeaderColumn0 = new TextView(view.getContext());
setTableHeaderView(table18HeaderRow, table18HeaderColumn0, R.string.blg_parameter18_0, tlparams18);
TextView table18HeaderColumn1 = new TextView(view.getContext());
setTableHeaderView(table18HeaderRow, table18HeaderColumn1, R.string.blg_parameter18_1, tlparams18);
TextView table18HeaderColumn2 = new TextView(view.getContext());
setTableHeaderView(table18HeaderRow, table18HeaderColumn2, R.string.blg_parameter18_2, tlparams18);
TextView table18HeaderColumn3 = new TextView(view.getContext());
setTableHeaderView(table18HeaderRow, table18HeaderColumn3, R.string.blg_parameter18_3, tlparams18);
TextView table18HeaderColumn4 = new TextView(view.getContext());
setTableHeaderView(table18HeaderRow, table18HeaderColumn4, R.string.blg_parameter18_4, tlparams18);
TextView table18HeaderColumn5 = new TextView(view.getContext());
setTableHeaderView(table18HeaderRow, table18HeaderColumn5, R.string.blg_parameter18_5, tlparams18);
TextView table18HeaderColumn6 = new TextView(view.getContext());
setTableHeaderView(table18HeaderRow, table18HeaderColumn6, R.string.blg_parameter18_6, tlparams18);
TextView table18HeaderColumn7 = new TextView(view.getContext());
setTableHeaderView(table18HeaderRow, table18HeaderColumn7, R.string.blg_parameter18_7, tlparams18);
TextView table18HeaderColumn8 = new TextView(view.getContext());
setTableHeaderView(table18HeaderRow, table18HeaderColumn8, R.string.blg_parameter18_8, tlparams18);
TextView table18HeaderColumn9 = new TextView(view.getContext());
setTableHeaderView(table18HeaderRow, table18HeaderColumn9, R.string.blg_parameter18_9, tlparams18);
table18.addView(table18HeaderRow);
createRowTable18(table18, table18NumOfRows, tlparams18);
public void createRowTable18(TableLayout table18, int numOfRows, TableRow.LayoutParams tlparams18) {
TableRow table18Row = new TableRow(table18.getContext());
table18Row.setLayoutParams(tlparams18);
table18Row.setId(numOfRows);
CheckBox table18RowColumn1 = new CheckBox(getContext());
CheckBox table18RowColumn2 = new CheckBox(getContext());
CheckBox table18RowColumn3 = new CheckBox(getContext());
CheckBox table18RowColumn4 = new CheckBox(getContext());
CheckBox table18RowColumn5 = new CheckBox(getContext());
CheckBox table18RowColumn6 = new CheckBox(getContext());
EditText table18RowColumn7 = new EditText(getContext());
final TextView table18RowColumn8 = new TextView(getContext());
EditText table18RowColumn9 = new EditText(getContext());
Spinner spinner18 = new Spinner(getContext());
ArrayAdapter<CharSequence> adapter18 = ArrayAdapter.createFromResource(getContext(),
R.array.blg_parameter18_1_array, android.R.layout.simple_spinner_item);
adapter18.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner18.setAdapter(adapter18);
table18Row.addView(spinner18);
spinner18.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String selection = (String) parent.getItemAtPosition(position);
if (!TextUtils.isEmpty(selection)) {
if (selection.equals(getString(R.string.blg_parameter_18_1_0))) {
table18RowColumn8.setText(null);
} else if (selection.equals(getString(R.string.blg_parameter_18_1_a))) {
table18RowColumn8.setText("kWh");
} else if (selection.equals(getString(R.string.blg_parameter_18_1_b))) {
table18RowColumn8.setText("lt");
} else if (selection.equals(getString(R.string.blg_parameter_18_1_c))) {
table18RowColumn8.setText("lt");
} else if (selection.equals(getString(R.string.blg_parameter_18_1_d))) {
table18RowColumn8.setText("Nm^3");
} else if (selection.equals(getString(R.string.blg_parameter_18_1_e))) {
table18RowColumn8.setText("Nm^3");
} else if (selection.equals(getString(R.string.blg_parameter_18_1_f))) {
table18RowColumn8.setText("kg");
} else if (selection.equals(getString(R.string.blg_parameter_18_1_g))) {
table18RowColumn8.setText("kWh");
}
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
setTableRowCheckBox(table18Row, table18RowColumn1);
setTableRowCheckBox(table18Row, table18RowColumn2);
setTableRowCheckBox(table18Row, table18RowColumn3);
setTableRowCheckBox(table18Row, table18RowColumn4);
setTableRowCheckBox(table18Row, table18RowColumn5);
setTableRowCheckBox(table18Row, table18RowColumn6);
table18RowColumn7.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
setTableRowEditView(table18Row, table18RowColumn7, tlparams18);
setTableRowTextView(table18Row, table18RowColumn8, tlparams18);
table18RowColumn7.setInputType(InputType.TYPE_CLASS_DATETIME | InputType.TYPE_DATETIME_VARIATION_NORMAL);
setTableRowEditView(table18Row, table18RowColumn9, tlparams18);
table18.addView(table18Row);
}
public void addRow18() {
createRowTable18(table18, table18NumOfRows, tlparams);
table18NumOfRows++;
}
public void removeRow18() {
if (table18NumOfRows > 0) {
table18.removeViewAt(table18NumOfRows);
table18NumOfRows--;
} else {
Toast.makeText(getContext(), "Δεν υπάρχουν γραμμές στον πίνακα", Toast.LENGTH_SHORT).show();
}
}
When I complete inserting data they are too many to save and recall them one by one everytime i rotate the phone. Any ideas?
When your orientation changes, Android destroys your current activity and creates a new activity again, so you must manage your state.
You can use onSaveInstanceState to save the state and then get the same it in onCreate, for example:
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("MyObject", myObject);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
final MyDataType myData = savedInstanceState.getString("MyObject"));
// fill your layout...
}
}
You can manage the state of your fragments too, please check here. Fragments can be "retain his instance" please read this or this.
Here another great post.
In some projects where I worked, when the application was not prepared for screen rotation, we had to disable this configuration.
I hope this will be useful for you.
Android will automatically save and restore your tables and the associated text views, but you need to do a couple of things.
Make sure each view you want to save has an id. Only views will an id will be saved. See generateViewId and setId.
Note: In order for the Android system to restore the state of the views in your activity, each view must have a unique ID, supplied by the android:id attribute.
Even with an id set, Android will not by default save the value of a TextView presumably because TextViews tend to be static. You can force a save/restore of a TextView by using freezesText.
android:freezesText
If set, the text view will include its current complete text inside of its frozen icicle in addition to meta-data such as the current cursor position. By default this is disabled; it can be useful when the contents of a text view is not stored in a persistent place such as a content provider. For EditText it is always enabled, regardless of the value of the attribute.
There may be some odds and ends to tend to, but that should be the bulk of the changes needed.
I'm new to Android Programming.
I want to implement p: data table tag functionality as of prime faces in android.
I want a table layout in XML through which I can iterate over a list of values from bean along with a checkbox for each row.
Using checkbox listener I want that particular row to be editable and vice versa. and that row should contain text views which allow the user to edit the text and also add row functionality which add an empty row to table to allow a user to enter values and save it.
can anyone suggest how can I proceed?
Thank you.
You have to manage all this in your Java class.
Here is a triggerless example for dynamically added checkboxes.
for(int i = 0; i < 20; i++) {
CheckBox cb = new CheckBox(getApplicationContext());
cb.setText("I'm dynamic!");
ll.addView(cb);
}
Here is a simple example. Simply put the event listener on the desired checkbox and do the processing according to what you want.
public class MainActivity extends AppCompatActivity {
private CheckBox checkBox1;
private TextView tv1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = (TextView) findViewById(R.id.tv_1);
tv1.setText("This is an example");
checkBox1 = (CheckBox) findViewById(R.id.checkBox1);
checkBox1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(checkBox1.isChecked()){
tv1.setText("Hi i am check");
tv1.setTextColor(Color.RED);
}else {
tv1.setText("Hi i am not checked");
tv1.setTextColor(Color.BLUE);
}
}
});
}
}
I am making an example of dynamic textview, that are created by pressing a button. the format in which they are created is similar to:
1- Textview (fist created)
2- TextView
3- TextView (last created)
I wonder if we can create them in an ascending order, one above the previous TextView.
something like this:
3- TextView (last created)
2- TextView
1- TextView (first created)
this is my example code:
private OnClickListener onClick() {
return new OnClickListener() {
#Override
public void onClick(View v) {
mLayout.addView(createNewTextView("TextView"));
count = count +1;
}
};
}
private TextView createNewTextView(String text) {
final LayoutParams lparams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
final TextView textView = new TextView(this);
textView.setLayoutParams(lparams);
textView.setText(count+ "- " + text);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
return textView;
}}
You can specify the index where TextView has to be added in ViewGroup...
ViewGroup.addView(TextView, 0);
each time you are creating a TextView and adding to mLayout, add with the index 0 which will add on top of previous TextView
mLayout.addView(createNewTextView("TextView"),0);
You could create a LinearLayout and add one below the other, using layout.addView(TextView). I've a psedo code below which explains how it is done.
for(Option option : options){
view = View.inflate(mContext,R.layout.textView,null);
((TextView)view.findViewById(R.id.txt_key)).setText(" SOME TEXT : ");
((TextView)view.findViewById(R.id.txt_value)).setText("SOME VALUE ");
mLlCtr.addView(view);
}
I have a program that has a text input and a button. When I type something into the input and press the button I want that String to be added to a String Arraylist and have that Arraylist displayed in a TextView. Right now I have a method:
public void addString(View view)
{
EditText editText = (EditText) findViewById(R.id.edit_choice);
String message = editText.getText().toString();
choices.add(message);
}
"edit-choices" is the name of the text input and "choices" is the name of the array list. First of all am I doing this correctly? Second, how to I get the text view to display the contents of "choices". Right now my TextView id is just textView1
Please keep in mind that it is not the best way to show list items in a TextView. You can do this using a ListView. Anyhow, see pseudo code below (didn't test that in Eclipse, however, it should show how it is basically going to work):
public class YourActivity extends Activity {
Vector<String> choices = new Vector<String>();
public void onCreate(Bundle ....) {
(Button) myButton = (Button) findViewById(R.id.button);
myButton.setOnClickListener(new OnClickListener() {
#Override
public boolean button.onClick() {
addString();
TextView textView = (TextView) findViewById(R.id.text_view);
String listRepresentation = "";
for (String choice : choices)
if ("".equals(listRepresentation))
listRepresentation = choice; else
listRepresentation = ", " +choice;
textView.setText(listRepresentation );
}
});
}
public void addString(View view)
{
EditText editText = (EditText) findViewById(R.id.edit_choice);
String message = editText.getText().toString();
choices.add(message);
}
}
So simply assign an OnClickListener to your button that does what you need.
The question is how you want the Text to be displayed...
Either like a list view or just as a normal text.
If you want to show the text as a normal text in the text view you can simply do something like this.
for(String msg : choices)
{
textView1.setText(textView1.getText()+msg);
}
If you want the choices to be displayed in list view you need to set an adapter to the list view using the choices that you have.
First of all am I doing this correctly?
If it works for you, sure. I would maybe cache the EditText so you don't have to "find" it every time you want to access it's content.
Your only "problem" here is, that a TextView has no method that accepts a List<String>. So, you'll need to make a single string out of your list of strings.
You can simply iterate over the list and con-cat them together:
StringBuilder b = new StringBuilder();
for (String s : choices){
b.append(s+"\n");
}
textview.setText(b.toString());
This will simply build one string from all the items in your list, adding line-breaks after every item.
You'll need to set your TextView's android:inputType-attribute to textMultiLine, so it will actually show you multiple lines.
Here is my code for how i make adding Dynamically TextView in to Table Layout using LinearLayout for it.
table_personalData.removeAllViews();
int i=0;
for(String header : headerDetail){
TextView label=new TextView(this);
TextView value=new TextView(this);
label.setTextAppearance(this, R.style.TextBase);
value.setTextAppearance(this, R.style.TextBase);
label.setText(String.format("%s:", header));
value.setText(String.format("%s", lead.data[i]==null?"":lead.data[i]));
i++;
LinearLayout rowview=new LinearLayout(this);
rowview.setOrientation(0);
rowview.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
rowview.addView(label);
rowview.addView(value);
table_personalData.addView(rowview);
}
By Above code i get my table layout with dynamically added textview in that .
here i use Liner Layout for added two textview in One Row .
headerDetail is a ArrayList<String> headerDetail
lead.data[i] i used this to get my values for particular label.
All this work fine for me now what my problem is
Now i want to do one thing that is when we click one of the TextView of my LinearLayout i want that TextView in dynamically.
So finally my question is about to get retrieve textview value when we touch or click any textview which is in Linearlayout and LinearLayout is in TableLayout.
Anyone have idea what should i have to do with this .
i also try something like below but i don't get i can i get TextView Value from below code.
table_personalData.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
for(int i=0;i<table_personalData.getChildCount();i++){
//CharSequence desc=table_personalData.getChildAt(i).getContentDescription();
//Log.v("log_tag", "the values are"+ desc);
}
}
});
EDIT:
if you want the Value of TextView when we Touch on that There is Two way that i write Below :
value.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
TextView txt;
txt=(TextView)findViewById(v.getId());
String tempEmail;
tempEmail=txt.getText().toString().trim();
String aEmailList[]={tempEmail};
pattern=Pattern.compile(EMAIL_PATTERN);
if(validate(tempEmail)){
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("plain/text");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,aEmailList );
startActivity(emailIntent);
}else{
pattern=Pattern.compile(PHONE_No_PATTERN);
if(validate(tempEmail)){
tempEmail=tempEmail.replaceAll("[^\\d]", "");
String uri="tel:" +tempEmail;
Intent mIntent=new Intent(Intent.ACTION_CALL);
mIntent.setData(Uri.parse(uri));
startActivity(mIntent);
}else{
//Toast.makeText(LeadDetailActivity.this, "Please Touch on Email or Mo:Number", Toast.LENGTH_SHORT).show();
}
}
}
});
1)Create how many text view u want,but set id for each one,and aslo set same click listener for all
TextView value1=new TextView(this);
value1.setid(1);
value1.setOnClickListener(clickListener);
TextView value2=new TextView(this);
value1.setid(2);
value2.setOnClickListener(clickListener);
TextView value3=new TextView(this);
value3.setid(3);
value3.setOnClickListener(clickListener);
2)second create one onclick listener,inside this listener u will get all cliks. so based on view id u can dynamically do anything
OnClickListener clickListener=new OnClickListener() {
public void onClick(View v) {
int id=v.getId();
}
};