片段-当字符串来自saveInstanceState时,EditText.setText(String)不起作用,但是当进行硬编码时,EditText.setText(String)不起作用 [英] fragment - EditText.setText(String) not working when string comes from savedInstanceState but works when hard coded

本文介绍了片段-当字符串来自saveInstanceState时,EditText.setText(String)不起作用,但是当进行硬编码时,EditText.setText(String)不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个片段:

ContactUsFragment.java

import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.app.Fragment;
import android.support.design.widget.TextInputLayout;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Toast;


/**
 *
 */
public class ContactUsFragment extends Fragment {

    private EditText et_name, et_phoneno;
    private String name = "", phone = "";
    private boolean instanceSaved = false;

    public ContactUsFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(savedInstanceState != null) {
            Toast.makeText(getActivity().getBaseContext(), "Not null", Toast.LENGTH_LONG).show();
            name = savedInstanceState.getString("sv_name");
            phone = savedInstanceState.getString("sv_phone");
            instanceSaved = savedInstanceState.getBoolean("InstanceSaved");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_contact_us, container, false);
        registerETs(view);

        if(instanceSaved) {
            Toast.makeText(getActivity().getBaseContext(), "Instance was saved", Toast.LENGTH_LONG).show();
            Toast.makeText(getActivity().getBaseContext(), name, Toast.LENGTH_LONG).show(); //--This line works. Gives the correct value of string upon orientation change--
            Toast.makeText(getActivity().getBaseContext(), phone, Toast.LENGTH_LONG).show();
            et_name.setText(name); //--This line does not work--
            et_name.setText("Another String"); //--This  line does not work--
            et_phoneno.setText(phone); //--This line does not work--
        }

        et_name.setText("A String"); //--This line works--

        return view;
    }

    @Override
    public void onStart() {
        super.onStart();

    }

    public void registerETs(View view) {
        et_name = (EditText)view.findViewById(R.id.input_name);
        et_phoneno = (EditText)view.findViewById(R.id.input_phoneno);
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        Toast.makeText(getActivity().getBaseContext(), "saving", Toast.LENGTH_LONG).show();
        savedInstanceState.putString("sv_name", et_name.getText().toString());
        savedInstanceState.putString("sv_phone", et_phoneno.getText().toString());
        savedInstanceState.putBoolean("InstanceSaved", true);
    }
}

我面临的问题是if(instanceSaved){...}中的et_name.setText(name)无法正常工作.它什么也没设置.好像名称是从if(savedInstanceSaved != null){...}获取null值一样.但是我在各种代码块中使用的Toasts可以按预期工作.它保存在onSaveInstanceState(Bundle savedInstanceState){...}中,执行if(savedInstanceSaved != null){...},这意味着我的savedInstanceState不为空,并且还在if(instanceSaved){...}中显示了name字符串的正确值.这意味着在orientation更改期间,我的代码可以正常工作.但是它没有在setText(String)方法中设置任何文本.

The problem I am facing is that, the et_name.setText(name) inside if(instanceSaved){...} is not working. It sets nothing. As if, name is getting null value from if(savedInstanceSaved != null){...}. But the Toasts that I have used inside my various blocks of code is working as expected. It is saving in onSaveInstanceState(Bundle savedInstanceState){...}, executing if(savedInstanceSaved != null){...}, meaning my savedInstanceState is not null and also showing the correct value for name string in if(instanceSaved){...}. That means my code is working correctly during an orientation change. But it is not setting any text in setText(String) method.

我也尝试使用setText("String"),并且有效.如代码所示.我在做什么错,我想念什么?请帮忙.谢谢.

I also tried using setText("String"), and that works. As shown in code. What wrong am I doing and what am I missing? Please help. Thank you.

注意: 我在android.support.design.widget.TextInputLayout

NOTE: I am using EditTexts inside android.support.design.widget.TextInputLayout

我发现无论如何,setText(name)始终采用String name的初始值.即使Toast中的name显示新的更新值,但setText()总是以某种方式使用初始值. 另外,我注意到,如果我改变方向三次,应用程序就会崩溃.

I found that no matter what, setText(name) is always taking the initial value of String name. Even though name in Toast shows the new updated value, setText() is somehow always using the initial value. Also, I noticed that if I change the orientation thrice, the app crashes.

推荐答案

如果视图具有ID,则Android会自动恢复视图状态.这在onCreateView()之后发生.所以,你的代码工作,您的更改只是失去了.

If your views have IDs, which they do, then Android will automatically be restoring the view state. This happens after onCreateView(). So your code is working, your changes are just lost.

要详细说明,请引用官方片段文档:

    一旦片段与其活动相关联,就会调用
  1. onAttach(Activity).
  2. 调用
  3. onCreate(Bundle)进行片段的初始创建.
  4. onCreateView(LayoutInflater,ViewGroup,Bundle)创建并返回与片段关联的视图层次结构.
  5. onActivityCreated(Bundle)告诉片段其活动已经完成了自己的Activity.onCreate().
  6. onViewStateRestored(Bundle)告诉该片段其视图层次结构的所有保存状态都已还原.
  7. onStart()使片段对用户可见(基于正在启动的包含活动).
  8. onResume()使片段开始与用户进行交互(基于要恢复的包含活动).
  1. onAttach(Activity) called once the fragment is associated with its activity.
  2. onCreate(Bundle) called to do initial creation of the fragment.
  3. onCreateView(LayoutInflater, ViewGroup, Bundle) creates and returns the view hierarchy associated with the fragment.
  4. onActivityCreated(Bundle) tells the fragment that its activity has completed its own Activity.onCreate().
  5. onViewStateRestored(Bundle) tells the fragment that all of the saved state of its view hierarchy has been restored.
  6. onStart() makes the fragment visible to the user (based on its containing activity being started).
  7. onResume() makes the fragment begin interacting with the user (based on its containing activity being resumed).

更新:

根据下面的评论,我有99%的把握是问题不在您显示的代码范围内.您的问题是您的内存中有两个ContactUsFragment副本.

Based on your comment below I'm 99% confident the problem is outside of the code you've displayed. Your problem is that you have two copies of ContactUsFragment in memory.

已恢复状态的一个,包括EditText的文本,然后必须重新创建的另一个.因此,您会看到吐司弹出窗口(随着旧片段的还原),但是您看不到放置在EditText中的值,因为您已经用新的ContactUsFragment替换了旧片段的视图.的视图,尚未恢复.

One that has had its state restored, including the EditText's text, and then another one that you must have recreated. Hence you're seeing the toast pop-up (as the old fragment is restored), but you're not seeing the values you place in the EditText, because you've replaced the old fragment's view with the new ContactUsFragment's view, which has not been restored.

这篇关于片段-当字符串来自saveInstanceState时,EditText.setText(String)不起作用,但是当进行硬编码时,EditText.setText(String)不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆