Save dynamically created tablelayout on screen rotation - android

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.

Related

Android: Showing a toast message when the checkbox is checked for the dynamically created checkboxes

When an ImageButton is clicked a checkBox is created dynamically in my app.
The problem I'm facing is with toast messages not showing or let's say the listener I am using for the checkboxes to show a toast message when the checkbox is checked is working only for the current/latest checkbox that has been created. Not for the checkboxes that had been created previously.
Problem,
I saw that the problem could be with the variable (toDoCheckBox) I am using to save the newly created checkbox instance and every time it's getting overriding dynamically as I create newer checkboxes. So for the previous checkboxes, there is no reference pointing to them in order for the listener to work. (the problem could be this or not, i don't know for sure) Even if this is the problem i don't know how to solve it
What i tried is that,
creating the instance of checkbox on both onCreate as well as the createCheckBox method so that I could assign the listener in both the places.
on the onCreate()
on the createCheckbox()
Only the latest created checkbox works and shows the toast messages
Can someone help me or guide me with the problem,
I want the toast message to show for every checkboxes
i posted only the code that could be of some use
private CheckBox toDoCheckBox;
private EditText defaultEditText;
private List<CheckBox> listCheckBoxes;
private int previousViewId = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.defaultEditText = findViewById(R.id.defaultEditText);
toDoCheckBox = new CheckBox(this);
this.listCheckBoxes = new ArrayList<>();
this.checkBoxListener = new View.OnClickListener(){
#Override
public void onClick(View view){
if(toDoCheckBox.isChecked()){
toDoCheckBox.setChecked(true);
Toast.makeText(MainActivity.this,"You did a good work, keep it up!",Toast.LENGTH_SHORT).show();
}
}
};
toDoCheckBox.setOnClickListener(checkBoxListener);
}
public void createCheckBox() {
//CREATING A CHECKBOX
toDoCheckBox = new CheckBox(this);
toDoCheckBox.setText(defaultEditText.getText().toString());
toDoCheckBox.setTextSize(20);
toDoCheckBox.setId(View.generateViewId());
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) defaultEditText.getLayoutParams();
ConstraintLayout.LayoutParams newParams = new ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
);
newParams.width = params.width;
newParams.height = params.height;
//Constraints
newParams.startToStart = params.startToStart;
newParams.endToEnd = params.endToEnd;
newParams.topToTop = params.topToTop;
newParams.topToBottom = params.topToBottom;
//Margins
newParams.leftMargin = params.leftMargin;
newParams.topMargin = params.topMargin;
newParams.bottomMargin = params.bottomMargin;
newParams.rightMargin = params.rightMargin;
constraintLayout.addView(toDoCheckBox, -1, newParams);
previousViewId = toDoCheckBox.getId();
defaultEditText.setVisibility(View.INVISIBLE);
createEditText();
toDoCheckBox.setOnClickListener(checkBoxListener);
this.listCheckBoxes.add(toDoCheckBox);
totalCheckBox++;
}
Try to use the local checkbox object instead of the global toDoCheckBox.

Get text from dynamically created EditText on click of a button

I am creating a dynamic layout in which I have 2 EditText and one Button. On click of a button a new same king of layout is created. I want , when I click on the button I should be able to get data from edittexts and store them and then add new layout.I am not able to get data from edittext , it is coming up blank.
Below is my code . I am also adding screenshot of my layout
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
ll_newView = (LinearLayout)findViewById(R.id.ll_newView);
scrollView = (ScrollView)findViewById(R.id.scrollView);
bt_addView = (Button)findViewById(R.id.bt_addView);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT);
LinearLayout one = new LinearLayout(MainActivity2.this);
//=====First EditText======//
params.weight = 5.0f;
params.setMargins(16,8,8,16);
EditText et_one = new EditText(MainActivity2.this);
et_one.setPadding(10,10,10,10);
et_one.setHint("Edit Text 1");
et_one.setBackground(getResources().getDrawable(R.drawable.edit_text_border));
et_one.setLayoutParams(params);
one.addView(et_one);
//=====Second EditText======//
EditText et_two = new EditText(MainActivity2.this);
et_two.setPadding(10,10,10,10);
et_two.setHint("Edit Text 2");
et_two.setBackground(getResources().getDrawable(R.drawable.edit_text_border));
et_two.setLayoutParams(params);
one.addView(et_two);
Button bt_plus = new Button(MainActivity2.this);
bt_plus.setText("+");
one.addView(bt_plus);
ll_newView.addView(one);
bt_plus.setOnClickListener(getOnClickDoSomething(et_one.getText().toString().trim(),et_two.getText().toString().trim()));
}
View.OnClickListener getOnClickDoSomething(final String one1,final String two1) {
return new View.OnClickListener() {
public void onClick(View v) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT);
LinearLayout one = new LinearLayout(MainActivity2.this);
Log.e("========","=====one ="+one1+"=========two = "+two1);
//=====First EditText======//
params.weight = 5.0f;
params.setMargins(16,8,8,16);
EditText et_one = new EditText(MainActivity2.this);
et_one.setPadding(10,10,10,10);
et_one.setHint("Edit Text 1");
et_one.setBackground(getResources().getDrawable(R.drawable.edit_text_border));
et_one.setLayoutParams(params);
one.addView(et_one);
//=====Second EditText======//
EditText et_two = new EditText(MainActivity2.this);
et_two.setPadding(10,10,10,10);
et_two.setHint("Edit Text 2");
et_two.setBackground(getResources().getDrawable(R.drawable.edit_text_border));
et_two.setLayoutParams(params);
one.addView(et_two);
Button bt_plus = new Button(MainActivity2.this);
bt_plus.setText("+");
one.addView(bt_plus);
ll_newView.addView(one);
bt_plus.setOnClickListener(getOnClickDoSomething(et_one.getText().toString().trim(),et_two.getText().toString().trim()));
Log.e("========","=====one ="+et_one.getText().toString().trim()+"=========two = "+ et_two.getText().toString().trim());
}
};
}
You are passing to the getOnClickDoSomething function the text of the newly created editText, so understandably it will be blank. What you may want is to change getOnClickDoSomething, so that it accepts reference to the editTexts themselves, and later you can retrieve the their current text. (You will have to be careful not to leak views, as you have anonymous classes holding on to the Views.)
Example: Just change the following lines as follows
bt_plus.setOnClickListener(getOnClickDoSomething(et_one, et_two)); }
View.OnClickListener getOnClickDoSomething(final EditText one1,final EditText two1)
Log.e("========","=====one ="+one1.getText().toString().trim(),+"=========two = "+two1.getText().toString().trim());

Create RecyclerView UI dynamically - Android

I am working on an e-commerce App . Here I am working on Products Filtering .
Here filters are dynamic, It means once filter page will display BRANDS and PRICE then next time it can display BRANDS , PRICE , STYLES ..etc .
There may be many cases to filter products .
Application is receiving filters dynamically from Webservice .
So here I am creating filters dynamically using data received from the webservice . For this I am using RecyclerView to display dynamic filters
.
Here is the code of RecyclerView where I am creating filters dynamically .
onCreateViewHolder() :
#Override
public FilterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LinearLayout topLayout = new LinearLayout(mContext);
topLayout.setOrientation(LinearLayout.VERTICAL);
if (filterItems != null) {
for (int filterItemsCount = 0; filterItemsCount < filterItems.size(); filterItemsCount++) {
LinearLayout ll = new LinearLayout(mContext);
ll.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(10, 10, 10, 10);
AFileterItem filterItem = filterItems.get(filterItemsCount);
TextView textView = new TextView(mContext);
textView.setText(filterItem.getFiletrLabel());
ll.addView(textView);
for (int i = 0; i < filterItem.getList().size(); i++) {
VlauesItem item1 = filterItem.getList().get(i);
CheckBox cb = new CheckBox(mContext);
cb.setId(i);
cb.setText(item1.getValueItemLabel());
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Toast.makeText(mContext, String.valueOf(isChecked), Toast.LENGTH_SHORT).show();
}
});
ll.addView(cb);
}
topLayout.addView(ll);
}
}else{
topLayout.addView(null);
}
FilterViewHolder viewHolder = new FilterViewHolder(topLayout);
return viewHolder;
}
Now , the problem is :
When I create filters dynamically then RecyclerView creates same filter more than once .
I want to know how should I manage above code so that I can eliminate this problem .
You need to understand what ViewHolders are. ViewHolder of a concrete type has single layout. If it is possible consider creating different viewholder types, or one with predefined layout, which will be customized in onBind callback. What you see is happening, because RecyclerView reuses view, and calls onCreateViewHolder only to fill the screen with items, then they are reused.

getText from all TextView which created by user

This is my Add button code which will get the text from AutoCompleteTextView and list into ListView on each click of Add button. I am so confusing about getting text from all TextView which created by user.
Because I need to compare the user inputs in all TextViewwith symptoms column in database to diagnose the disease. Hope you guys can help me =)
private OnClickListener onClick() {
return new OnClickListener() {
#Override
public void onClick(View v) {
mLayout.addView(createNewTextView(mEditText.getText().toString()));
}
};
}
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("Symptom: " + text);
textView.setText(text);
return textView;
}
You can maintain a ArrayList where you can store all the getText() if all the text views.
Just define and initialize your arraylist before you use it.
Initialize like below
ArrayList<String> arrayList = new ArrayList<String>();
And in createNewTextView() method you can have the below line to add the names to arraylist
arrayList.add(text)
later you can use these arraylist for reference and get all the text entered by user

How to find out if an EditText has been created?

In a dialog layout, I create a second EditText programmatically depending on user choices. When I want to return the inputs, I need to know if a second EditText has been created or not. And I don't understand how to make this check. My statement if (edittextTwo != null) is always null, even when the second EditText has been displayed and entered text into.
Here are the methods which create the second EditText and return their inputs:
if (edittextTwo != null)
private void displayASecondEdittext(String title) {
ViewGroup layout = (ViewGroup) findViewById(R.id.layout_editdialog);
TextView titleTwo = new TextView(this);
titleTwo.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
titleTwo.setText(title);
layout.addView(titleTwo);
EditText edittextTwo = new EditText(this);
edittextTwo.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
layout.addView(edittextTwo);
}//END displayASecondInputfield
private void returnResult() {
Intent resultIntent = new Intent(this, EditDialog.class);
resultIntent.putExtra(EDITONE, edittextOne.getText().toString());
if (edittextTwo != null) {
resultIntent.putExtra(EDITTWO, edittextTwo.getText().toString());
Log.v(TAG, "edittextTwo ="+edittextTwo.getText().toString());
}
setResult(Activity.RESULT_OK, resultIntent);
finish();
}//END returnResult
move EditText edittextTwo; out side of your method. put it here:
public class myActivity extends Activity
EditText edittextTwo = null;
And then, in your DisplayASecondEditText(), do this instead of what you have:
edittextTwo = new EditText(this);
This will make your declaration global, and allow all all methods to access the variable.
I don't understand how your code above even compiles, since edittextTwo is a local variable in displayASecondEdittext. Make it a member variable in your activity and it should work.

Categories

Resources