2014-01-18 50 views
1

Android非常新。我有一个活动可以创建一些N个自定义视图。它创建的每个自定义视图都被添加到Activity LinearLayout并显示在屏幕上。这工作得很好,直到我旋转屏幕。突然,自定义视图不能正确显示其数据。在我的测试场景中,Activity创建了2个自定义视图实例,第一个显示了“名称1”,而第二个显示了每个自定义视图的EditText中的“名称2”。当我切换方向时(这一切都在我的Nexus 7上完成),这两个自定义视图的EditText都会说“名称2”。我在活动和自定义视图的构造函数中使用了println语句,以确保正确的值仍被传入,但显示方式不同。有任何想法吗?下面是一些简单的代码:屏幕方向变化时Android复合视图呈现错误

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> 

这里是一个链接到截图: http://imgur.com/a/2HqmS

这里是prinln输出结果从代码提供良好的预期视图时:

01-17 17:44:49.588: I/System.out(22474): activity adding view for Bench Press 
01-17 17:44:49.618: I/System.out(22474): templateXercise id =4 
01-17 17:44:49.618: I/System.out(22474): set name:Bench Press, confirmed val=Bench Press4 
01-17 17:44:49.618: I/System.out(22474): activity adding view for Incline Bench 
01-17 17:44:49.648: I/System.out(22474): templateXercise id =6 
01-17 17:44:49.648: I/System.out(22474): set name:Incline Bench, confirmed val=Incline Bench6 

下面是从代码中的println输出结果时,屏幕方向的变化和活动的onCreate方法被调用:

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 

你可以看到,我传递的预期值到第一个自定义视图,但它显示了第二个值。您在这里看到的代码大大简化了原来的视图。任何Android大师知道我在这里做错了什么?

回答

0

你需要什么保存您的CustomViews状态,当您更改设备的方位了Android OS从初始化视图的开头,以便尽量实现了您的视图方法

onSaveInstanceState 

将由在onPause称为前导向方法改变,在这里你会从EditText上保存数据

onRestoreInstanceState 

日之后将被称为Ë定位完成,正确的数据添加到您的意见

这里全码:

How to prevent custom views from losing state across screen orientation changes

+0

但是当方向的变化,我正在收拾的自定义视图,然后我的活动重新添加。如果自定义视图是以xml声明的,而不是以编程方式声明的,您的方法是否必要?令我惊讶的是,我创建了两个自定义视图实例,一个用于数据库中的每条记录,当方向发生变化时,每个记录都具有完全相同的值,当我明确地向它们传递唯一值时。 – user3208751

+0

它看起来像我的活动Wrt从onRestoreInstanceState方法重建我的视图相同的方法。为什么onCreate会搞乱视图,但是在屏幕方向改变后onRestoreInstanceState不会出现?感谢提示穆罕默德妈妈。 – user3208751

+1

onCreate方法为活动创建新的初始化,所以它会清除所有的变量和视图数据,但android操作系统可能是如果你声明具有唯一id的视图将保存视图的状态,但如果你在自定义视图中使用一个id并使用自定义查看两次android操作系统将把两个自定义视图的初始值与相同的子视图ID –