Save and restore TableLayout on orientation change - android

In my program I, have a TableLayout with one TableRow where I added more TableRows with 4 TextViews in it dynamically on a Button Click. Now I want to save and restore this table if I change the orientation of my phone.
I have following code which should do this:
#Override
protected void onSaveInstanceState(Bundle outState) {
rowcount = tableLayout.getChildCount();
for (int i = 0; i < rowcount; i++) {
View row = tableLayout.getChildAt(i);
if (row instanceof TableRow) {
View rowchild1 = tableRow.getChildAt(0);
if (rowchild1 instanceof TextView) {
savewarnum[i] = ((TextView) rowchild1).getText().toString();
}
View rowchild2 = tableRow.getChildAt(1);
if (rowchild2 instanceof TextView) {
savewarname[i] = ((TextView) rowchild2).getText().toString();
}
View rowchild3 = tableRow.getChildAt(2);
if (rowchild3 instanceof TextView) {
savewarmeng[i] = ((TextView) rowchild3).getText().toString();
}
View rowchild4 = tableRow.getChildAt(3);
if (rowchild4 instanceof TextView) {
savewarpreis[i] = ((TextView) rowchild4).getText().toString();
}
}
}
outState.putStringArray("Nummer", savewarnum);
outState.putStringArray("Name", savewarname);
outState.putStringArray("Menge", savewarmeng);
outState.putStringArray("Preis", savewarpreis);
outState.putInt("Rows", rowcount);
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
savewarnum = savedInstanceState.getStringArray("Nummer");
savewarname = savedInstanceState.getStringArray("Name");
savewarmeng = savedInstanceState.getStringArray("Menge");
savewarpreis = savedInstanceState.getStringArray("Preis");
rowcount = savedInstanceState.getInt("Rows");
tableLayout = (TableLayout) findViewById(R.id.kaufwaren);
for(int i=0; i<=rowcount; i++) {
View tablechild = tableLayout.getChildAt(i);
if (tablechild instanceof TableRow) {
View rowchild1 = tableRow.getChildAt(0);
if (rowchild1 instanceof TextView) {
((TextView) rowchild1).setText(savewarnum[i]);
}
View rowchild2 = tableRow.getChildAt(1);
if (rowchild2 instanceof TextView) {
((TextView) rowchild2).setText(savewarname[i]);
}
View rowchild3 = tableRow.getChildAt(2);
if (rowchild3 instanceof TextView) {
((TextView) rowchild3).setText(savewarmeng[i]);
}
View rowchild4 = tableRow.getChildAt(3);
if (rowchild4 instanceof TextView) {
((TextView) rowchild4).setText(savewarpreis[i]);
}
}
createtablerow();
}
super.onRestoreInstanceState(savedInstanceState);
}
In my onSavedInstanceState method, I'm going through my table where I save every Textview in a StringArray. In onRestoreInstanceState I'm trying to recreate the table.
Now I have two Problems. My First Problem is, that my Program doesn't go through the table in onSavedInstanceState. It just adds the TextViews of the last row to my string array instead of the TextViews from all Rows.
For example i have two rows:
Row 1: 'abc' '123' 'def' '456'
Row 2: 'cba' '321' 'fed' '654'
Now ABC and CBA should be in my first string array, but there is two times CBA because it's the last row.
My second Problem is in onRestoreInstanceState. As soon as I reach 'View rowchild1 = tableRow.getChildAt(0);' my program crashes.
Does anyone know a solution?

You should initialize tableRow variable before usage in onSaveInstanceState
#Override
protected void onSaveInstanceState(Bundle outState) {
...
View row = tableLayout.getChildAt(i);
if (row instanceof TableRow) {
TableRow tableRow = (TableRow) row;
View rowchild1 = tableRow.getChildAt(0);
...
}
}
Same might be an issue in onRestoreInstanceState.
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
...
if (tablechild instanceof TableRow) {
TableRow tableRow = (TableRow) tablechild;
View rowchild1 = tableRow.getChildAt(0);
...
}
}

Related

android studio how to set some TextViews id's with for

i want to set lots of Edit Texts id's and i don't know how to get those id's.
EditText[] texts;
for(int i=0;i++;i<15){
tests[i]=(EditText)findViewById(R.id. )
}
my Edit Text id's:
et1,et2,et3,...
first create a empty list of EditTexts
then use this code and send them rootView of Your Layout to find all EditTexts :
private List<EditText> editTexts; //global Scop
private void findAllEditTexts(ViewGroup group) {
for (int i = 0, count = group.getChildCount(); i < count; ++i) {
View view = group.getChildAt(i);
if (view instanceof EditText) {
if (editTexts == null)
editTexts = new ArrayList<EditText>();
editTexts.add((EditText) view);
} else if (view instanceof ViewGroup && (((ViewGroup) view).getChildCount() > 0)) {
findAllEditTexts((ViewGroup) view);
}
}
}
now in editTexts List you have all EditTexts :)

Removing Listview row on Button Click

I have a Listview that gets fed questions and their corresponding choices as such:
The following constructor gets all the necessary information to feed the Listview. All string values are in Arraylists.
public BaseQuestionAdapter(Activity a, ArrayList<String> b, ArrayList<String> c, ArrayList<String> d, ArrayList<String> e) {
activity = a;
this.questionTitleArray = b;
this.choicesArray = c;
this.questionIdArray = d;
this.userIdArray = e;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
Each row will hold a single question title and a variable number of choices. Dynamically created buttons will instantiate the choices and on each question title position the buttons will start generating. Like so, the following is the getView method in the BaseAdapter:
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
vi = inflater.inflate(R.layout.question_layout, null);
LinearLayout questionContainer = (LinearLayout) vi.findViewById(R.id.question_container);
LinearLayout choicesContainer = (LinearLayout) vi.findViewById(R.id.choices_container);
ViewGroup answersContainerParent = (ViewGroup) choicesContainer.getParent();
if (answersContainerParent != null)
answersContainerParent.removeView(choicesContainer);
JSONArray choicesJSONArray = new JSONArray(choicesArray);
try {
String bhb = choicesJSONArray.get(position).toString();
jsnArray = new JSONArray(bhb);
} catch (JSONException e) {
e.printStackTrace();
}
for (int answersArrayIterator = 0; answersArrayIterator < jsnArray.length(); answersArrayIterator++) {
try {
final Button choiceButton = new Button(activity);
choiceButton.setId(buttonId);
String questionId = questionIdArray.get(position).toString();
choiceButton.setTag(questionId);
choiceButton.setTag(position);
ViewGroup layout = (ViewGroup) choiceButton.getParent();
if (layout != null)
layout.removeView(choiceButton);
choiceButton.setText(jsnArray.get(answersArrayIterator).toString());
choiceButton.setTextSize(16);
choiceButton.setBackgroundResource(R.drawable.question_button_template_style);
choiceButton.setGravity(Gravity.CENTER);
choiceButton.setWidth(270);
choiceButton.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
String choiceString = choiceButton.getText().toString();
Object questionId = choiceButton.getTag();
setDataToBeSent(userId, questionId, choiceString);
Integer index = (Integer) v.getTag();
System.out.println("SATURN ASCENDS: " + index);
choicesArray.remove(index);
notifyDataSetChanged();
new HttpAsyncTask2().execute();
return false;
}
});
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(10, 10, 10, 10);
choiceButton.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
choiceButton.setLayoutParams(params);
buttonId++;
choicesContainer.addView(choiceButton);
} catch (JSONException e) {
e.printStackTrace();
}
}
TextView questionTitleET = (TextView) vi.findViewById(R.id.question_title);
String questionTitle = questionTitleArray.get(position).toString();
questionTitleET.setText(questionTitle);
ViewGroup questionTitleETParent = (ViewGroup) questionTitleET.getParent();
if (questionTitleETParent != null)
questionTitleETParent.removeView(questionTitleET);
questionContainer.addView(questionTitleET);
questionContainer.addView(choicesContainer);
return vi;
}
What I'm trying to achieve is to remove the parent Listview row whenever a button is LonClicked. I'm trying to achieve this by setting an OnLongClickListener on every button created. Like so:
choiceButton.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Integer index = (Integer) v.getTag();
System.out.println("SATURN ASCENDS: " + index);
choicesArray.remove(index);
notifyDataSetChanged();
return false;
}
});
Problem is that I don't know what to reference precisely in order for that to happen. Don't know whether its the choicesArray or any of the other resources I'm receiving. Currently when I long click on a button nothing happens. Any clue as to where I'm going wrong? Thank you.
As Luksprog said on the comment, you need to remove the items from the container which is referenced in the getCount(). However I would also like to offer an improvement. Instead of using four different lists of Strings, use an Object which holds each of those string.
Eg.
public class MyClass {
public String questionTitle;
public String choice;
public String questionId;
public String userId;
}
After you have this class you can use a single list, which contains your object. This way you won't be confused as to which list items should be removed in order for the list to change.

Dynamic checkboxes adding/deleting to the LinearLayout VS ListView

I have a array which I get from another Activity. I want to display it in the current Activity as CheckBox items and then have ability to check some of them and delete by button clicking. I implement it next way:
public void addFiles()
{
LinearLayout layout = (LinearLayout) findViewById(R.id.filesList);
if(!FileManagerActivity.finalAttachFiles.isEmpty())
{
for (int i=0; i<FileManagerActivity.finalAttachFiles.size();i++)
{
View line = new View(this);
line.setLayoutParams(new LayoutParams(1, LayoutParams.MATCH_PARENT));
line.setBackgroundColor(0xAA345556);
informationView= new CheckBox(this);
informationView.setTextColor(Color.BLACK);
informationView.setTextSize(16);
informationView.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
informationView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.file_icon, 0, 0, 0);
informationView.setText(FileManagerActivity.finalAttachFiles.get(i).getName().toString());
informationView.setId(i);
layout.addView(informationView, 0);
layout.addView(line, 1);
layout.postInvalidate();
}
}
}
, and call it in the onCreate() method. it can be added successfully. Then I get items which were checked like this:
btnFilesRemove.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
LinearLayout layout = (LinearLayout) findViewById(R.id.filesList);
View v = null;
for(int i=0; i<FileManagerActivity.finalAttachFiles.size(); i++) {
v = layout.getChildAt(i);
CheckBox checkBox = (CheckBox) findViewById(i);
boolean checked=checkBox.isChecked();
if (checked)
{
Log.i("was checked",checkBox.getText().toString());
ViewGroup parent = (ViewGroup) v.getParent();
parent.removeView(v);
FileManagerActivity.finalAttachFiles.remove(i);
Log.i("this is view,baby",v.toString());
}
}
}
});
But items can't be deleted. And I'm thinking - what is better - to implement it in this way or maybe it will be more efficient with ListView using. I mean to create ArrayAdapter e.t.c..

How to get title of fragment dialog window (app uses ActionBarSherlock)

I need to compare strings from title of fragment dialogue with R.id.string from resources. It looks like smth like this (user Robotium).
assertTrue(doesAlertTitleExist(getSolo().getString(R.string.error_dialog_title_text)));
But I can't get text from title of dialogue window fragment created with the help of ActionBar Sherlock. This code finds only views from screen over which this dialogue appears, but not views from dialogue.
You can find screenshot here: http://imgur.com/d1ZjL
public boolean doesAlertTitleExist(String extectedTitle) {
List<TextView> views = getDialogTextViews((ViewGroup) getSolo().getView(android.R.id.content));
assertNotNull(views);
for(TextView view : views){
if(view.getText().toString().equals(extectedTitle)){
return true;
}
}
return false;
}
private List<TextView> getDialogTextViews(ViewGroup view) {
List<TextView> out = new LinkedList<TextView>();
int count = view.getChildCount();
for(int i=0; i<count; i++){
View child = view.getChildAt(i);
if(child instanceof ViewGroup){
out.addAll(getDialogTextViews((ViewGroup) child));
}else if(child instanceof TextView){
out.add((TextView) child);
}
}
return out;
}

Save data into an email:

Save data from edit texts, text views, spinner selections, and checkboxes from multiple activities into an email:
I am already using:
Intent EmailSend = new Intent(android.content.Intent.ACTION_SEND);
EmailSend.setType("plain/text");
EmailSend.putExtra(android.content.Intent.EXTRA_TEXT,
"Pretext"+edittext.getText().toString());
the put string is not working for items not listed in the .java
When I use the last line in that i get error saying -edittext cannot resolved-
and how to get data from checkbox & spinner
I will have 80 or so items to compile to this email over 8 activities
I wrote a snippet to automate it a little:
ViewGroup root = (ViewGroup) ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
StringBuilder str = new StringBuilder();
public void extractText(ViewGroup root, StringBuilder str){
int count = root.getChildCount();
for(int i = 0; i < count; i++) {
View v = root.getChildAt(i);
if(v instanceof Spinner) {
str.append(i).append(" Spinner: ").append(((Spinner) v).getSelectedItem());
} else if(v instanceof TextView) {
str.append(i).append(" TextView: ").append(((TextView) v).getText());
} else if(v instanceof CheckBox) {
str.append(i).append(" Checkbox: ").append(((CheckBox) v).isChecked());
}else if(v instanceof ViewGroup){
extractText((ViewGroup)v, str);
}
}
}

Categories

Resources