Android 在多个文本上设置文本会导致在旋转后使用相同的文本填充所有文本

Android 在多个文本上设置文本会导致在旋转后使用相同的文本填充所有文本,android,android-layout,android-edittext,layout-inflater,screen-rotation,Android,Android Layout,Android Edittext,Layout Inflater,Screen Rotation,我正在放大一些编辑文本,并将它们添加到线性布局中: private void setupCommentViews(){ int i = 0; Iterator<CommentInformation> iterator = commentInformations.iterator(); while(iterator.hasNext()) { i++; View v = LayoutInflater.from

我正在放大一些
编辑文本
,并将它们添加到
线性布局中

private void setupCommentViews(){
    int i = 0;
        Iterator<CommentInformation> iterator = commentInformations.iterator();
    while(iterator.hasNext()) {
            i++;
            View v = LayoutInflater.from(context).inflate(R.layout.comment_row_item, commentsContainer, false);

            EditText commentField = (EditText)v.findViewById(R.id.comment);         

            CommentInformation commentInformation = iterator.next();
            final String uniqueId = commentInformation.getUniqueId();

            String currentCommentText = comments.get(uniqueId);         
            if(currentCommentText != null) {
                Log.v("into","Setting old text: "+currentCommentText);
                commentField.setText(currentCommentText);
            } else {
                Log.v("into","Setting empty text: "+i);
                commentField.setText("Setting empty text: "+i);
            }


            commentField.addTextChangedListener(new TextWatcher() {

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                }

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void afterTextChanged(Editable s) {
                    comments.put(uniqueId, s.toString().trim());
                }
            });

            commentsContainer.addView(v);
        }
}
所有编辑文本中都有正确的文本(“设置空文本:#”)

-

我正在将一个
TextChangedListener
添加到我充气的
EditText
,当文本更改时,我更新一个
Map
,并将uniqueId作为键,注释文本作为值

当我在更改其中一条评论后旋转手机时,问题就出现了。我将注释
Map
保存在
onSaveInstanceState
中:

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putSerializable(COMMENTS, (Serializable)comments);
}
然后我在创建的活动中检索它们

if(savedInstanceState != null) {
        Log.v("into","Retrieving...");
        comments = (Map<String, String>)savedInstanceState.getSerializable(COMMENTS);
}
但是所有的编辑文本现在都会说:“设置空文本:3”

使用
ListView
并不是我想要的解决方案,因为
editText
ListView
AdjustResize
softInputMode

-


有人能解释一下这里发生了什么事吗

默认情况下,当调用活动的
onSaveInstanceState
方法时,它还会遍历视图层次结构,如果可能,尝试保存任何视图的状态,如果稍后调用活动的
onRestoreInstanceState
方法,则恢复这些视图状态。调用每个视图以保存状态时,我们可以在类中看到此方法:

受保护的void dispatchSaveInstanceState(SparseArray容器){
如果(mID!=无ID&(mViewFlags&SAVE\U DISABLED\U MASK)==0){
mPrivateFlags&=~PFLAG\u SAVE\u STATE\u调用;
可包裹状态=onSaveInstanceState();
如果((调用的mPrivateFlags和PFLAG保存状态)==0){
抛出新的非法状态异常(
“派生类未调用super.onSaveInstanceState()”;
}
如果(状态!=null){
//Log.i(“查看”、“冻结”#“+整数.toHexString(mID)
//+“:”+状态);
容器。放置(中间,状态);
}
}
}
EditText继承自TextView,当检查的代码时,我们会看到
onSaveInstanceState
方法返回当前文本,而
onRestoreInstanceState
方法返回文本并显示

现在,回到你的代码。您自己保存文本内容,并在调用
onCreate
时将其还原,但EditText本身也在调用
onRestoreInstanceState
活动方法时保存文本并还原,该方法在调用
onCreate
后调用。当然,还有一件事,所有EditText都具有相同的id,因此,当视图层次结构的状态保存到SparseArray中时,最后一个EditText状态(在本例中为文本内容)将覆盖之前的所有状态。这就是你的问题发生的原因

解决方案:

  • 您可以重写activity的RestoreInstanceState方法
    onRestoreInstanceState
    ,而不调用super方法,这样可以防止视图自动恢复其状态,但我认为这不是个好主意,因为默认情况下可能需要恢复其他内容,而不仅仅是EditText
  • 您可以将EditText的属性设置为false,这样它就不会恢复状态本身,我建议这样做

  • EditText根据剩余值还原文本。如果您的EditText没有剩余内容或所有内容都有相同的剩余内容,则您将有还原问题。

    我也有相同的问题。 在自定义LinearLayout中,我重写了这些方法

       @Override
    protected Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        return new SavedState(superState, txtData.getText().toString());
    }
    
    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        SavedState savedState = (SavedState) state;
        super.onRestoreInstanceState(savedState.getSuperState());
        txtData.setText(savedState.data);
    }
    
    @Override
    protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
        super.dispatchFreezeSelfOnly(container);
    }
    
    @Override
    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
        super.dispatchThawSelfOnly(container);
    }
    
    private class SavedState extends BaseSavedState {
        public final Creator<SavedState> CREATOR = new Creator<SavedState>() {
            @Override
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }
    
            @Override
            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
        private String data;
    
        public SavedState(Parcel source) {
            super(source);
            data = source.readString();
        }
    
        public SavedState(Parcelable superState, String data) {
            super(superState);
            this.data = data;
        }
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(@NonNull Parcel dest, int flags) {
            dest.writeString(data);
        }
    }
    
    @覆盖
    受保护的地块onSaveInstanceState(){
    可包裹的超级状态=super.onSaveInstanceState();
    返回新的SavedState(superState,txtData.getText().toString());
    }
    @凌驾
    RestoreInstanceState上的受保护无效(可包裹状态){
    SavedState SavedState=(SavedState)状态;
    super.onRestoreInstanceState(savedState.getSuperState());
    setxt(savedState.data);
    }
    @凌驾
    受保护的void dispatchSaveInstanceState(SparseArray容器){
    超级发货单(集装箱);
    }
    @凌驾
    受保护的无效dispatchRestoreInstanceState(SparseArray容器){
    超级发货单(集装箱);
    }
    私有类SavedState扩展了BaseSavedState{
    公共最终创建者=新创建者(){
    @凌驾
    public SavedState createFromParcel(中的地块){
    返回新的SavedState(in);
    }
    @凌驾
    public SavedState[]新数组(整数大小){
    返回新的SavedState[大小];
    }
    };
    私有字符串数据;
    公共存储状态(地块源){
    超级(来源);
    data=source.readString();
    }
    公共存储状态(可包裹的超级状态、字符串数据){
    超级(超级国家);
    这个数据=数据;
    }
    @凌驾
    公共int描述内容(){
    返回0;
    }
    @凌驾
    公共无效writeToParcel(@NonNull Parcel dest,int标志){
    目的写入(数据);
    }
    }
    

    希望这能有所帮助。

    我也遇到了这个问题,但我以前必须恢复状态。因此,我创建了一个名为
    FixedEditText
    的视图,并重写了
    dispatchSaveInstanceState()
    dispatchRestoreInstanceState()
    two方法。就这样,

    04-01 17:40:41.244: V/into(28770): Setting empty text: 1
    04-01 17:40:41.254: V/into(28770): Setting empty text: 2
    04-01 17:40:41.254: V/into(28770): Setting empty text: 3
    
     override fun dispatchSaveInstanceState(container: SparseArray<Parcelable>) {
        try {
            val key = initKey()
            if (key != null && isSaveEnabled) {
                val state = onSaveInstanceState()
                if (state != null) {
                    //don't use the id as the key
                    container.put(key.hashCode(), state)
                }
            }
        } catch (e: Exception) {
            super.dispatchSaveInstanceState(container)
            e.printStackTrace()
        }
    }
    
    override fun dispatchRestoreInstanceState(container: SparseArray<Parcelable>) {
        try {
            val key = initKey()
            if (key != null) {
                val state = container.get(key.hashCode())
                if (state != null) {
                    onRestoreInstanceState(state)
                }
            }
        } catch (e: Exception) {
            super.dispatchRestoreInstanceState(container)
            e.printStackTrace()
        }
    }
     private fun initKey(): Any? {
        (parent as? View)?.run {
            //My ViewGroup has diff id.
            return "${this.javaClass.simpleName}$${this.id}"
        }
        return null
    }
    
    覆盖fun dispatchSaveInstanceState(容器:SparseArray){
    试一试{
    val key=initKey()
    if(key!=null&&isSaveEnabled){
    val state=onSaveInstanceState()
    如果(状态!=null){
    //不要将id用作密钥
    container.put(key.hashCode(),state)
    }
    }
    }捕获(e:例外){
    super.dispatchSaveInstanceState(容器)
    e、 printStackTrace()
    }
    }
    覆盖fun dispatchRestoreInstanceState(容器:SparseArray){
    试一试{
    val key=initKey()
    if(key!=null){
    val state=container.get(key.hashCode())
    如果(圣彼得堡)
    
       @Override
    protected Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        return new SavedState(superState, txtData.getText().toString());
    }
    
    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        SavedState savedState = (SavedState) state;
        super.onRestoreInstanceState(savedState.getSuperState());
        txtData.setText(savedState.data);
    }
    
    @Override
    protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
        super.dispatchFreezeSelfOnly(container);
    }
    
    @Override
    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
        super.dispatchThawSelfOnly(container);
    }
    
    private class SavedState extends BaseSavedState {
        public final Creator<SavedState> CREATOR = new Creator<SavedState>() {
            @Override
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }
    
            @Override
            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
        private String data;
    
        public SavedState(Parcel source) {
            super(source);
            data = source.readString();
        }
    
        public SavedState(Parcelable superState, String data) {
            super(superState);
            this.data = data;
        }
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(@NonNull Parcel dest, int flags) {
            dest.writeString(data);
        }
    }
    
     override fun dispatchSaveInstanceState(container: SparseArray<Parcelable>) {
        try {
            val key = initKey()
            if (key != null && isSaveEnabled) {
                val state = onSaveInstanceState()
                if (state != null) {
                    //don't use the id as the key
                    container.put(key.hashCode(), state)
                }
            }
        } catch (e: Exception) {
            super.dispatchSaveInstanceState(container)
            e.printStackTrace()
        }
    }
    
    override fun dispatchRestoreInstanceState(container: SparseArray<Parcelable>) {
        try {
            val key = initKey()
            if (key != null) {
                val state = container.get(key.hashCode())
                if (state != null) {
                    onRestoreInstanceState(state)
                }
            }
        } catch (e: Exception) {
            super.dispatchRestoreInstanceState(container)
            e.printStackTrace()
        }
    }
     private fun initKey(): Any? {
        (parent as? View)?.run {
            //My ViewGroup has diff id.
            return "${this.javaClass.simpleName}$${this.id}"
        }
        return null
    }