TextView未更新

6

我在使用处理程序类更新TextView中的文本时遇到了一个愚蠢的问题。我正在为Google Maps设置自定义信息窗口。

mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
            @Override
            public View getInfoWindow(Marker marker) {
                return null;
            }

            @Override
            public View getInfoContents(final Marker marker) {
                //setting marker as final***
                View v = getLayoutInflater().inflate(R.layout.my_layout, null);
                TextView name = (TextView) v.findViewById(R.id.name);


                final TextView status = (TextView) v.findViewById(R.id.status);

                for(MyItem mi : myItems){
                    if(mi.getName().equals(marker.getTitle())){

                        name.setText(mi.getName()); //This one updates normaly

                        Handler handler = new Handler();
                        handler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                //this one sets the text, but doesnt update on UI
                                status.setText("Text"); 

                                //Here I call my update text function
                                updateTv(status, "Text");
                                //Refreshing the window***
                                marker.showInfoWindow();

                            }
                        }, 5000);
                        break;
                    }
                }

                return v;
            }
        });
    }

TextView的"name"正常更新,而"status" TextView只更新其内容,但在屏幕上没有视觉上的更新。我尝试了无效化和runOnUiThread(),但似乎都不起作用。我知道解决方案可能非常明显,但我看不到它。

提前感谢您的帮助!

编辑

这是我如何尝试使用runOnUiThread()

public void updateTv(final TextView tv, final String s){

        runOnUiThread(new Runnable() {
            @Override
            public void run() {

                tv.setText(s);

                tv.invalidate();

            }
        });
    }

我的XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Large Text"
        android:id="@+id/name"
        android:layout_gravity="center"
        android:gravity="center_horizontal"
        android:padding="10dp"/>


    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:text="..."
        android:id="@+id/status"
        android:gravity="center_horizontal"/>

</LinearLayout>

解决方案

我通过在上面的代码中调用带有***注释和签名的命令来刷新我的窗口。感谢"clownba0t"


你的布局 XML 文件有问题吗?因为名为 textView 的控件正常工作,它可能与更新机制无关,可能是映射出现了问题! - Ahmad Sanie
1
呵呵,我刚刚查看了 GoogleMap.InfoWindowAdapter.getInfoContents 的文档,它说:“如果在此方法被调用后更改此视图,则这些更改不一定会反映在渲染的信息窗口中。” 我想这就解释了! - clownba0t
1
文档似乎包含有关如何更新信息窗口的一些建议 - 请参见此处 - clownba0t
1
clownba0t,你说得对。问题是Info窗口不是一个“实时”的视图,只是一张图片。我现在正在刷新它,它完美地工作了。我该如何将你的答案标记为正确呢? :) - tensa11
1
这里是解释:http://tekeye.uk/android/examples/ui/android-app-text-not-updating - Peter
显示剩余11条评论
3个回答

1
这源于Android是一个使用消息的操作系统。因此,操作系统中有一部分读取消息并根据消息中的顺序执行操作。
刷新TextView中的文本是通过以下方式完成的:当您执行setText()时,您的代码会准备一条消息并将其发送到操作系统以告诉它“请刷新textView”。
我们可以简化说明,即使您同时向朋友发送10封信,也可能不会同时到达...
在这里,就是这种情况:对于Android,用户界面的消息不是“优先”消息。但是应用程序代码具有高优先级。 因此,当您执行setText()时,消息被发送,但操作系统不会立即读取它,因为在setText()之后,您执行了大量的代码操作。因此,操作系统运行您的代码,并且只有在这个庞大的代码块完成后,操作系统才会说“哦,好吧,也许我收到了一封信”,他打开信件找到“请刷新textView”并执行它。 所以...在您的大量代码之后。
如何解决? 您必须将您的大量代码放入处理程序中。
  TextView tmp_id_top_msg = (TextView) findViewById(R.id.text_top_clavier);
  tmp_id_top_msg.setText("message to display");

  Handler handler_spend_time;
  handler_spend_time = new Handler();
  handler_spend_time.postDelayed(Call_Huge_Code(), 100);

然后:

public Runnable Call_Huge_Code()
{
    return new Runnable()
    {
        public void run()
        {
            // here your code...
        }
    };
}

这将延迟您的代码执行100毫秒,这不足以“减慢”进程,但足以让Android读取“刷新setText”消息。

1

所以您想在从getInfoContents()返回视图后更新它,但这不起作用,因为它不是实时视图,请参见this

有可能奏效的方法是调用:

status.invalidate();

status.invalidate()不起作用,但是我标记了你的答案为正确,因为你解释了我的View不是“live”的问题。 - tensa11
我从API获取了数据,目前正在使用视图模型,这很有效。但是这很奇怪。除非我设置.invalidate(),否则文本不会更新,我不知道为什么。 - ralphgabb

0
你需要做这个:
    status.setText("Some text");
    status.invalidate();
    status.requestLayout();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接