L
Lybrial
Neues Mitglied
- 0
Hallo,
mir ist heute etwas sehr merkwürdiges begegnet und ich finde einfach
nicht die Lösung für das Problem, ich verstehe nicht mal im geringsten
warum es zu folgendem Verhalten kommt:
Ich habe eine Ansicht in meiner App, in der der User per Knopfdruck
weitere "Zeilen" bestehend aus zwei Spinnern, einer TextView und einem
Button, zur Ansicht hinzufügen kann. Dort kann er dann individuelle Werte
setzen. Sobald nun die View zerstört und neu aufgebaut wird, werden die
Werte aller so hinzugefügten Zeilen auf die Werte der zuletzt hinzugefügten
Zeile gesetzt. Dazu ein Beispiel: Bild links vor der Rotation, Bild rechts danach:
Zum speichern der Werte nutze ich ein Parcelable:
Welches hier in meiner View zum Einsatz kommt:
Die Log-Ausgaben zeigen es, wenn ich zwei Zeilen hinzufüge ist die Log-Ausgabe die Folgende:
Zunächst alles so wie es sein soll. Aber so sieht das nach der Rotation also nach der Zerstörung und Neubildung der View:
Das einzige was hier nicht verändert wurde ist die id, welche ich auch nur
zum Testen reingenommen hatte. Ich hatte kurz vermutet, dass das
Layout eventuell zwei Views als identisch betrachtet, wenn sie keine
unterschiedliche ID haben.
Wie gesagt habe ich keine Ahnung wie es zu dem Verhalten kommt
und bin mit meinem Latein völlig am Ende.
mir ist heute etwas sehr merkwürdiges begegnet und ich finde einfach
nicht die Lösung für das Problem, ich verstehe nicht mal im geringsten
warum es zu folgendem Verhalten kommt:
Ich habe eine Ansicht in meiner App, in der der User per Knopfdruck
weitere "Zeilen" bestehend aus zwei Spinnern, einer TextView und einem
Button, zur Ansicht hinzufügen kann. Dort kann er dann individuelle Werte
setzen. Sobald nun die View zerstört und neu aufgebaut wird, werden die
Werte aller so hinzugefügten Zeilen auf die Werte der zuletzt hinzugefügten
Zeile gesetzt. Dazu ein Beispiel: Bild links vor der Rotation, Bild rechts danach:
Zum speichern der Werte nutze ich ein Parcelable:
Code:
public class AMRState implements Parcelable {
private List<AMRRowState> rowStates = null;
public AMRState() {
this.rowStates = new ArrayList<AMRRowState>();
}
public AMRState(List<AMRRowState> rowStates) {
this.rowStates = rowStates;
}
public AMRState(Parcel in) {
this.rowStates = new ArrayList<AMRRowState>();
in.readList(rowStates, null);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(this.rowStates);
}
public static final Parcelable.Creator<AMRState> CREATOR = new Parcelable.Creator<AMRState>() {
public AMRState createFromParcel(Parcel in) {
return new AMRState(in);
}
public AMRState[] newArray(int size) {
return new AMRState[size];
}
};
public List<AMRRowState> getRowStates() {
return rowStates;
}
public void setRowStates(List<AMRRowState> rowStates) {
this.rowStates = rowStates;
}
}
public class AMRRowState implements Parcelable {
private int activity = -1;
private int hour = -1;
private String pal = null;
public AMRRowState(int activity, int hour, String pal) {
this.activity = activity;
this.hour = hour;
this.pal = pal;
}
public AMRRowState(Parcel in) {
this.activity = in.readInt();
this.hour = in.readInt();
this.pal = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.activity);
dest.writeInt(this.hour);
dest.writeString(this.pal);
}
public static final Parcelable.Creator<AMRRowState> CREATOR = new Parcelable.Creator<AMRRowState>() {
public AMRRowState createFromParcel(Parcel in) {
return new AMRRowState(in);
}
public AMRRowState[] newArray(int size) {
return new AMRRowState[size];
}
};
public int getActivity() {
return activity;
}
public void setActivity(int activity) {
this.activity = activity;
}
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public String getPal() {
return pal;
}
public void setPal(String pal) {
this.pal = pal;
}
}
Welches hier in meiner View zum Einsatz kommt:
Code:
public class AMRFragment extends Fragment implements OnClickListener {
private FragmentManager fragmentManager = null;
private LinearLayout layoutRowParent = null;
private Button buttonAddRow = null;
private AMRState amrState = null;
private int rowID = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.fragmentManager = this.getActivity().getSupportFragmentManager();
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_calc_amr_fragment, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
this.layoutRowParent = (LinearLayout) view.findViewById(R.id.calc_amr_row_parent);
this.buttonAddRow = (Button) view.findViewById(R.id.calc_amr_button_add_row);
this.buttonAddRow.setOnClickListener(this);
this.restoreState(savedInstanceState);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(Globals.KEY_AMR_STATE, this.amrState);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.calc_amr_button_calc : {
this.performCalcAMR();
} break;
case R.id.calc_amr_button_add_row : {
this.performAddRow(view);
} break;
case R.id.calc_amr_row_button_delete : {
this.performDeleteRow(view);
}
}
}
private void restoreState(Bundle inState) {
if(inState != null) {
this.amrState = (AMRState) inState.getParcelable(Globals.KEY_AMR_STATE);
this.inflateEditRows();
} else {
this.amrState = new AMRState();
this.inflateEditRow(-1, -1, -1, null, true);
}
}
private void performCalcAMR() {}
private void performAddRow(View view){
if(this.layoutRowParent.getChildCount() < 25) {
this.inflateEditRow(-1, -1, -1, null, true);
}
}
private void performDeleteRow(View view) {
View parent = (View) view.getParent();
int parentIndex = this.layoutRowParent.indexOfChild(parent);
this.amrState.getRowStates().remove(parentIndex);
this.layoutRowParent.removeView(parent);
}
@SuppressLint("InflateParams")
private void inflateEditRow(int id, int activity, int hour, String pal, boolean addToAMRRowState) {
Log.v("InflateEditRow", "" + id + " - " + activity + " - " + hour + " - " + pal);
final LayoutInflater inflater = (LayoutInflater) this.getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView = inflater.inflate(R.layout.activity_calc_amr_fragment_row, null);
final Spinner spinnerActivities = (Spinner) rowView.findViewById(R.id.calc_amr_row_spinner_activity);
final Spinner spinnerHours = (Spinner) rowView.findViewById(R.id.calc_amr_row_spinner_hours);
final TextView textViewPal = (TextView) rowView.findViewById(R.id.calc_amr_row_textview_pal);
final ImageButton deleteButton = (ImageButton) rowView.findViewById(R.id.calc_amr_row_button_delete);
spinnerActivities.setOnItemSelectedListener(this.listenerActivity);
spinnerHours.setOnItemSelectedListener(this.listenerHour);
if(id != -1) {
rowView.setId(id);
}
if(activity != -1) {
spinnerActivities.setSelection(activity);
}
if(hour != -1) {
spinnerHours.setSelection(hour);
}
if(pal != null) {
textViewPal.setText(pal);
}
if(this.layoutRowParent.getChildCount() == 0) {
deleteButton.setVisibility(View.INVISIBLE);
} else {
deleteButton.setOnClickListener(this);
}
if(addToAMRRowState) {
this.amrState.getRowStates().add(new AMRRowState(this.rowID++, activity, hour, pal));
}
Log.v("InflateEditRow", "rowID: " + rowView.getId() + ", spinnerac: " + spinnerActivities.getSelectedItemPosition() + ", spinnerhours: " + spinnerHours.getSelectedItemPosition() + ", pal: " + textViewPal.getText().toString());
this.layoutRowParent.addView(rowView, this.layoutRowParent.getChildCount());
}
private void inflateEditRows() {
for(AMRRowState amrRowState : this.amrState.getRowStates()) {
this.inflateEditRow(amrRowState.getId(), amrRowState.getActivity(), amrRowState.getHour(), amrRowState.getPal(), false);
}
}
private OnItemSelectedListener listenerActivity = new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
View rowParentView = (View) parent.getParent();
ViewGroup rowParentGroup = (ViewGroup) parent.getParent();
int rowIndex = layoutRowParent.indexOfChild(rowParentView);
String pal = null;
switch (position) {
case 1: pal = "" + 0.95;
break;
case 2: pal = "" + 1.2;
break;
case 3: pal = "" + 1.5;
break;
case 4: pal = "" + 1.7;
break;
case 5: pal = "" + 1.9;
break;
case 6: pal = "" + 2.4;
break;
default: pal = "";
break;
}
for(int i = 0; i < rowParentGroup.getChildCount(); i++) {
if(rowParentGroup.getChildAt(i) instanceof TextView) {
((TextView) rowParentGroup.getChildAt(i)).setText(pal);
}
}
amrState.getRowStates().get(rowIndex).setActivity(position);
amrState.getRowStates().get(rowIndex).setPal(pal);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
};
private OnItemSelectedListener listenerHour = new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
View rowParentView = (View) parent.getParent();
int rowIndex = layoutRowParent.indexOfChild(rowParentView);
amrState.getRowStates().get(rowIndex).setHour(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
};
}
Die Log-Ausgaben zeigen es, wenn ich zwei Zeilen hinzufüge ist die Log-Ausgabe die Folgende:
Code:
12-01 17:49:04.194: V/InflateEditRow(15547): 1 - 1 - 1 - 0.95
12-01 17:49:04.198: V/InflateEditRow(15547): rowID: 1 spinnerac: 1, spinnerhours: 1, pal: 0.95
12-01 17:49:04.198: V/InflateEditRow(15547): 2 - 2 - 2 - 1.2
12-01 17:49:04.202: V/InflateEditRow(15547): rowID: 2spinnerac: 2, spinnerhours: 2, pal: 1.2
Zunächst alles so wie es sein soll. Aber so sieht das nach der Rotation also nach der Zerstörung und Neubildung der View:
Code:
12-01 17:49:18.271: V/InflateEditRow(15547): 1 - 2 - 2 - 1.2
12-01 17:49:18.276: V/InflateEditRow(15547): rowID: 1 spinnerac: 2, spinnerhours: 2, pal: 1.2
12-01 17:49:18.276: V/InflateEditRow(15547): 2 - 2 - 2 - 1.2
12-01 17:49:18.280: V/InflateEditRow(15547): rowID: 2 spinnerac: 2, spinnerhours: 2, pal: 1.2
Das einzige was hier nicht verändert wurde ist die id, welche ich auch nur
zum Testen reingenommen hatte. Ich hatte kurz vermutet, dass das
Layout eventuell zwei Views als identisch betrachtet, wenn sie keine
unterschiedliche ID haben.
Wie gesagt habe ich keine Ahnung wie es zu dem Verhalten kommt
und bin mit meinem Latein völlig am Ende.