为啥 setText() 在 TextView 上的以下代码中不起作用?

Posted

技术标签:

【中文标题】为啥 setText() 在 TextView 上的以下代码中不起作用?【英文标题】:Why is setText() not working in the following code on the TextView?为什么 setText() 在 TextView 上的以下代码中不起作用? 【发布时间】:2014-02-14 09:30:35 【问题描述】:
// All required Imports

public class PuzzleActivity extends  Activity implements OnClickListener
    private PuzzlerDB db; 
    private Puzzle puz; 

    private int puzId=1;     
    private String puzAns="";
    private int score=0;

    private TextView tvPuzContent;
    private EditText etPuzAns;
    private Button btnCheck;

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

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        final boolean customTitleSupported = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); 

        setContentView(R.layout.activity_puzzle);

        if ( customTitleSupported ) 
            getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
        

        db = new PuzzlerDB(this);
        puz = db.getPuzzle(puzId); 
        puzAns = puz.getAnswer(); 

        tvPuzContent = (TextView) findViewById(R.id.tv_puz_content);
        tvPuzContent.setText(puz.getContent());
        btnCheck = (Button) findViewById(R.id.btn_check);
        btnCheck.setOnClickListener(this);   

        android.util.Log.v("IN SIDE ACTIVITY: ", "id: "+ puzId + " answer: "+puz.getAnswer());

    

    @Override
    public void onClick(View v) 
        switch (v.getId()) 
        case R.id.btn_check:
            checkAndNotify(puzAns);
            break;
               
    

    private void checkAndNotify(String puzAns)
    
        String ans = ((EditText)findViewById(R.id.te_puz_ans)).getText().toString();

        if(ans.trim().equalsIgnoreCase(puzAns.trim()))
        
            //show pop-up dialog for right answer
            new AlertDialog.Builder(this).setTitle("The Puzzler:")
                .setMessage("Wow! Right Answer!!")
                .setNeutralButton("Continue", new DialogInterface.OnClickListener()
                
                    public void onClick(DialogInterface dlg, int sumthin) 
                      
                        android.util.Log.v("IN SIDE function:", " onClick of Dialog");
                        update();
                    
                ).show();

        else
            new AlertDialog.Builder(this).setTitle("The Puzzler:")
            .setMessage("Sorry! You have to rethink!!")
            .setNeutralButton("Continue", new DialogInterface.OnClickListener()
            
                public void onClick(DialogInterface dlg, int sumthin) 
                
                    // do nothing – it will close on its own
                
            ).show();          
        
    

    protected void update() 
        score = score + 10;
        ++puzId;                    
    

    @Override
    protected void onResume() 
        super.onResume();
        setContentView(R.layout.activity_puzzle);
        puz = db.getPuzzle(puzId);
        if(puz != null)
        
            tvPuzContent.setText(puz.getContent());
            android.util.Log.v("IN SIDE onResume:", " Content: "+ puz.getContent());
            puzAns = puz.getAnswer();           
        
    

    @Override
    protected void onDestroy() 
            super.onDestroy();
            db.close();
    

活动布局如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:background="@drawable/bgimg"
    android:layout_gravity="center">

    <TableLayout android:layout_
        android:layout_
        android:layout_gravity="center"
        android:layout_margin="20dp"
        android:stretchColumns="*">

        <TableRow>      
            <TextView android:id="@+id/tv_puz_content"
                android:layout_
                android:layout_
                android:layout_span="3"
                android:typeface="serif"
                android:textStyle="bold"
                android:textSize="20sp"
                android:text="" />
        </TableRow>

        <TableRow>          
            <EditText android:id="@+id/te_puz_ans"
                android:layout_
                android:layout_
                android:layout_marginTop="10dp"
                android:layout_span="3"             
                android:hint="Answer"  />
        </TableRow>

        <TableRow android:gravity="center">         
            <Button android:id="@+id/btn_check"
                android:layout_
                android:layout_
                android:hint="Check"  />

            <Button android:id="@+id/btn_skip"
                android:layout_
                android:layout_
                android:hint="Skip"  />

            <Button android:id="@+id/btn_hint"
                android:layout_
                android:layout_
                android:hint="Hint"  />
        </TableRow>
    </TableLayout>
</LinearLayout>

db 查询正在正确返回内容,我可以通过 logcat 检查。但是文本视图没有显示出来。但 EditText 和按钮正在显示。

我尝试了其他帖子中的各种选项,例如(i)将 TextView 设为静态(ii)接收字符串中的拼图内容,然后通过 setText() 和其他方法设置它,但均未成功。能否请您提出解决方案。

【问题讨论】:

你在 puz var 中得到了什么? 你在这个日志中得到了什么? android.util.Log.v("IN SIDE onResume:", " Content:"+ puz.getContent()); 是的。 puz 正在设置其所有数据成员的值。我在上面的日志中得到了拼图的内容,例如:'01-23 22:28:17.937: V/IN SIDE onResume:(18673): Content: What is the value of 2 x 5?' 是 puz.getContent() 类型的字符串吗?也许你调用另一个重载 TextView setText() 然后 setText(CharSequence text)... 【参考方案1】:

您在onResume() 中调用setContentView(R.layout.activity_puzzle);,但tvPuzContent 变量在onCreate() 中被实例化,因此它指的是从原始调用到onCreate 中的setContentView 的文本视图。

基本上,在onCreate 结束时,您已经分配了所有变量,但是随后系统调用了onResume,然后您再次调用setContentView,这会丢弃您的原始布局,因此所有变量都指向不在屏幕上的旧视图。

只是不要在onResume() 中调用setContentView,因为无论如何您都不会更改布局。

【讨论】:

感谢您的回答。我更正了那部分。我从 onResume() 中删除了 setContentView() 并在屏幕上显示了内容。但是为什么在关闭警报对话框后没有调用 onResume() 呢?如果我没记错的话,因为应该调用 onResume() 对话解除后活动已经进入前台。这应该已经通过 getPuzzle() 得到了新的谜题并且应该更新了 textview?如何使用新的拼图内容重绘活动? 我不认为对话框算作将您的活动置于后台 - 对话框本质上是您的活动中的另一个视图。只有另一个活动才能使您的活动进入后台。如果新的activity是透明的或者不是全屏的,只会触发onPause/onResume,不会触发onStop/onRestart/onStart。如果您希望在对话框关闭时发生某些事情,请为其创建一个方法,并从对话框的按钮侦听器中调用该方法。 这就是重点。我的印象是,当任何事情阻止活动时,它是“onPaused”。但是当阻塞元素(本例是Dialog)是Activity本身的另一个组件时,情况并非如此。为此+1。谢谢。

以上是关于为啥 setText() 在 TextView 上的以下代码中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

在其他方法 Android 中使用 Textview.setText

在 onPreExecute() 内部调用时 TextView.setText() 的 NullPointerException

尝试在 recyclerview kotlin 上的空对象引用上调用虚拟方法 'void android.widget.TextView.setText(java.lang.CharSequence)

textView.setText();崩溃

如何修复翻译无法使用TextView.setText()?

Android TextView : “Do not concatenate text displayed with setText”