草庐IT

android - 在多个膨胀的 EditText 上设置文本会导致在旋转后全部填充相同的文本

coder 2023-12-07 原文

我正在充气一些EditTexts并将它们添加到 LinearLayout :

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);
        }
}

第一次运行后的日志如下所示:

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

并且所有的 EditText 中都有正确的文本(“设置空文本:#”)

-

我正在添加 TextChangedListener到我的EditText我膨胀并在文本更改时更新 Map<String, String>并将 uniqueId 作为键,将评论文本作为值。

当我更改其中一条评论后旋转手机时出现问题。我保存评论Map onSaveInstanceState 内部:

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putSerializable(COMMENTS, (Serializable)comments);
}

然后我在 onActivityCreated 中检索它们

if(savedInstanceState != null) {
        Log.v("into","Retrieving...");
        comments = (Map<String, String>)savedInstanceState.getSerializable(COMMENTS);
}

我还遍历了 Map并验证是否有一个条目具有正确的 uniqueId 和正确更改的评论文本。

-

接下来我调用 setupCommentViews()再次。这次日志看起来是正确的,但是 EditTexts ALL 与最后一个(最后一个膨胀的)具有相同的文本。

04-01 17:42:49.664: V/into(28770): Setting empty text: 1
04-01 17:42:49.664: V/into(28770): Setting old text: Changed the second textview
04-01 17:42:49.674: V/into(28770): Setting empty text: 3

但是所有的EditTexts现在说:“设置空文本:3”

使用 ListView这不是我正在寻找的解决方案,因为 EditTexts 有很多错误ListView 内部与 AdjustResize softInputMode

-

任何人都可以阐明这里发生的事情吗?

最佳答案

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

protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
        if (mID != NO_ID && (mViewFlags & SAVE_DISABLED_MASK) == 0) {
            mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
            Parcelable state = onSaveInstanceState();
            if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) {
                throw new IllegalStateException(
                        "Derived class did not call super.onSaveInstanceState()");
            }
            if (state != null) {
                // Log.i("View", "Freezing #" + Integer.toHexString(mID)
                // + ": " + state);
                container.put(mID, state);
            }
        }
    }

EditText继承自TextView,查看TextView的代码我们看到 onSaveInstanceState 方法返回当前文本,onRestoreInstanceState 方法返回文本并显示。

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

解决方案:

  1. 您可以覆盖 Activity 的方法 onRestoreInstanceState 而不是调用 super 方法,这样您就可以防止 View 自动恢复其状态,但我认为这不是个好主意,因为可能其他东西需要默认恢复,不仅仅是你的EditText
  2. 您可以设置属性saveEnabled将 EditText 设置为 false,这样它就不会自行恢复状态,我建议这样做。

关于android - 在多个膨胀的 EditText 上设置文本会导致在旋转后全部填充相同的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22799602/

有关android - 在多个膨胀的 EditText 上设置文本会导致在旋转后全部填充相同的文本的更多相关文章

  1. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  2. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  3. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  4. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  5. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  6. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  7. ruby - 匹配大写字母并用后续字母填充,直到一定的字符串长度 - 2

    我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种

  8. ruby - 使用多个数组创建计数 - 2

    我正在尝试按0-9和a-z的顺序创建数字和字母列表。我有一组值value_array=['0','1','2','3','4','5','6','7','8','9','a','b','光盘','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','','u','v','w','x','y','z']和一个组合列表的数组,按顺序,这些数字可以产生x个字符,比方说三个list_array=[]和一个当前字母和数字组合的数组(在将它插入列表数组之前我会把它变成一个字符串,]current_combo['0','0','0']

  9. ruby-on-rails - before_filter 运行多个方法 - 2

    是否有可能:before_filter:authenticate_user!||:authenticate_admin! 最佳答案 before_filter:do_authenticationdefdo_authenticationauthenticate_user!||authenticate_admin!end 关于ruby-on-rails-before_filter运行多个方法,我们在StackOverflow上找到一个类似的问题: https://

  10. ruby-on-rails - Rails 3.1 中具有相同形式的多个模型? - 2

    我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#

随机推荐