当屏幕方向改变时,Android复合视图渲染不正确
Android非常新。我有一个创建一些自定义视图的活动。它创建的每个自定义视图都会添加到活动线性布局中,并显示在屏幕上。在我旋转屏幕之前,这一切都很好。突然,自定义视图无法正确显示其数据。在我的测试场景中,活动创建了我的自定义视图的两个实例,第一个实例在每个自定义视图的EditText中显示“名称1”,而第二个实例在每个自定义视图的EditText中显示“名称2”。当我切换方向时(这都是在我的Nexus 7上完成的),两个自定义视图的EditText都会显示“名称2”。我在活动和自定义视图的构造函数中使用了println语句,以确保仍然传入正确的值,但它只是以不同的方式显示。有什么想法吗?下面是一些简化的代码:当屏幕方向改变时,Android复合视图渲染不正确,android,android-custom-view,Android,Android Custom View,Android非常新。我有一个创建一些自定义视图的活动。它创建的每个自定义视图都会添加到活动线性布局中,并显示在屏幕上。在我旋转屏幕之前,这一切都很好。突然,自定义视图无法正确显示其数据。在我的测试场景中,活动创建了我的自定义视图的两个实例,第一个实例在每个自定义视图的EditText中显示“名称1”,而第二个实例在每个自定义视图的EditText中显示“名称2”。当我切换方向时(这都是在我的Nexus 7上完成的),两个自定义视图的EditText都会显示“名称2”。我在活动和自定义视图的构造
public class EditTemplateWorkout extends Activity{
private int templateWorkoutId = -1;
private TemplateWorkout templateWorkout;
@SuppressWarnings("unchecked")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_template);
Intent intent = this.getIntent();
templateWorkoutId = intent.getIntExtra(Messages.TEMPLATEWORKOUTID_MESSAGE, -1);
templateWorkout = templateWorkoutId == -1 ? new TemplateWorkout() : LiftDroidDbHelper.TemplateWorkoutService.get(templateWorkoutId, true, this);
final EditText editTextName = (EditText) this.findViewById(R.id.editTextName);
editTextName.setText(templateWorkout.getName());
editTextName.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if(!s.equals("") ){
String txtVal = editTextName.getText().toString();
templateWorkout.setName(txtVal);
}
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void afterTextChanged(Editable s) {
}
});
LinearLayout root = (LinearLayout)this.findViewById(R.id.rootLayout);
root.removeAllViews();
for(TemplateExercise te : templateWorkout.getTemplateExercises()){
root = (LinearLayout)this.findViewById(R.id.rootLayout);
System.out.println("activity adding view for "+te.getName());
EditTemplateExerciseView editTemplateExercise = new EditTemplateExerciseView(te, this, null);
editTemplateExercise.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
root.addView(editTemplateExercise);
}
int moot = 3;
}
}
public class EditTemplateExerciseView extends LinearLayout {
TemplateExercise templateExercise;
public EditTemplateExerciseView(TemplateExercise te, Context context, AttributeSet attrs) {
super(context, attrs);
templateExercise = te;
setOrientation(LinearLayout.HORIZONTAL);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.view_edit_template_exercise, this, true);
TextView txtName = (TextView) this.findViewById(R.id.templateExerciseNameTxt);
txtName.setText(templateExercise.getName() + templateExercise.getTemplateExerciseID());
System.out.println("templateXercise id ="+te.getTemplateExerciseID());
System.out.println("set name:"+templateExercise.getName() + ", confirmed val="+txtName.getText());
}//constructor
}
这是我的简化自定义视图的副本:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name:"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="@+id/templateExerciseNameTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10" >
<requestFocus />
</EditText>
</LinearLayout>
</merge>
以下是当屏幕方向改变且调用活动的onCreate方法时,代码的println输出结果:
01-17 17:45:31.568: I/System.out(22474): activity adding view for Bench Press
01-17 17:45:31.588: I/System.out(22474): templateXercise id =4
01-17 17:45:31.588: I/System.out(22474): set name:Bench Press, confirmed val=Bench Press4
01-17 17:45:31.588: I/System.out(22474): activity adding view for Incline Bench
01-17 17:45:31.618: I/System.out(22474): templateXercise id =6
01-17 17:45:31.618: I/System.out(22474): set name:Incline Bench, confirmed val=Incline Bench6
01-17 17:45:31.648: W/IInputConnectionWrapper(22474): showStatusIcon on inactive InputConnection
01-17 17:45:31.808: W/IInputConnectionWrapper(22474): getTextBeforeCursor on inactive InputConnection
01-17 17:45:31.878: W/IInputConnectionWrapper(22474): getTextBeforeCursor on inactive InputConnection
01-17 17:45:31.978: W/IInputConnectionWrapper(22474): getTextBeforeCursor on inactive InputConnection
01-17 17:45:32.178: W/IInputConnectionWrapper(22474): getTextBeforeCursor on inactive InputConnection
01-17 17:45:32.318: W/IInputConnectionWrapper(22474): getTextBeforeCursor on inactive InputConnection
01-17 17:45:32.338: W/IInputConnectionWrapper(22474): getTextBeforeCursor on inactive InputConnection
您可以看到,我正在将预期值传递到第一个自定义视图中,但它显示了第二个自定义视图的值。您在这里看到的代码与视图最初所做的相比大大简化了。有谁知道我做错了什么 您需要它保存您的CustomViews状态,当您更改设备的方向时,android操作系统从一开始就初始化您的视图,因此尝试在您的视图方法中实现
onSaveInstanceState
在方向更改之前,onpause方法将调用它,在这里您将从edittext保存数据
及
它将在定向完成后调用,并将正确的数据添加到视图中
下面是完整的代码:
但在我的活动中,当方向发生变化时,我清除了自定义视图,然后重新添加它们。如果自定义视图是用xml声明的,而不是以编程方式声明的,那么您的方法是否才有必要?令我惊讶的是,我创建了两个自定义视图实例,一个用于数据库中的每条记录,当方向发生变化时,当我明确地向它们传递唯一值时,它们都具有完全相同的值。看起来相同的方法适用于我的Activity wrt从onRestoreInstanceState方法重建视图。为什么onCreate会弄乱视图,而onRestoreInstanceState在屏幕方向更改后不会弄乱视图?感谢Mohammed Momn.onCreate方法为“活动”创建新的初始化,这样它将清除所有变量和视图数据,但如果您使用唯一id声明视图,则android操作系统可能会为您的视图保存状态,但如果您在自定义视图中使用一个id并使用自定义视图两次,则android操作系统会将初始值设置为两次具有相同子视图idonRestoreInstanceState的自定义视图在创建活动时调用,在此Bunndle对象将保存已销毁活动的最后状态,您可以在主题“android生命周期”中了解更多信息
onSaveInstanceState
onRestoreInstanceState