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状态(在本例中为文本内容)将覆盖之前的所有状态。这就是你的问题发生的原因
解决方案:
onRestoreInstanceState
,而不调用super方法,这样可以防止视图自动恢复其状态,但我认为这不是个好主意,因为默认情况下可能需要恢复其他内容,而不仅仅是EditTextEditText根据剩余值还原文本。如果您的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
}