如何刷新/重画在Android Sceneform中呈现的TextView?

时间:2019-02-28 18:13:41

标签: android arcore sceneform

我的目的是在Android Sceneform应用的增强图像中使用TextView(“信息卡”)显示动态传感器读数。

我使用SceneForm的AugmentedImage示例作为基础。我从Solarsystem示例中复制了信息卡的概念,最后(经过一些令人沮丧的工作),设法找到了一种从lambda函数中获取TextView的方法,以便我可以在主要活动中使用setText(相当多的方法)时间,因为我以前的Java 1.2经验)。现在,我可以将setText()成功设置为带有时间戳值的TextView(已用getText()调试),但稍后将尝试更改它以通过HTTP或MQTT获取值。

问题在于,一旦使用正确显示的第一个值启动了视图,就无法在屏幕上重新绘制TextView /(信息卡)。我试图使TextView实例和其他方法无效,以使节点重新绘制而没有成功。

在AugmentedImageActivity中:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment);
    fitToScanView = findViewById(R.id.image_view_fit_to_scan);

    LinearLayout mainLayout = (LinearLayout) findViewById(R.layout.activity_main);
    LayoutInflater inflater = getLayoutInflater();
    View infoCardLayout = inflater.inflate(R.layout.info_card_view, mainLayout, false);
    textView = (TextView) infoCardLayout.findViewById(R.id.textView);

    arFragment.getArSceneView().getScene().addOnUpdateListener(this::onUpdateFrame);
}

在AugmentedImageActivity中:

private void onUpdateFrame(FrameTime frameTime) {
    Frame frame = arFragment.getArSceneView().getArFrame();
    Log.d("TW_onUpdateFrame","onUpdateFrame");
    String t = String.valueOf(System.currentTimeMillis());
    t = t.substring(t.length()-6);
    textView.setText(t);

在setImage的AugmentedImageNode.java中:

  ...
  localPosition.set(0.0f, 0.0f, -0.8f * image.getExtentZ());
  infoCard = new Node();
  infoCard.setParent(this);
  infoCard.setEnabled(true);
  infoCard.setLocalPosition(localPosition);
  infoCard.setLocalRotation(new Quaternion(new Vector3(1.0f,0.0f,0.0f),-90));

  ViewRenderable.builder()
          .setView(context, R.layout.info_card_view)
          .build()
          .thenAccept(
                  (renderable) -> {
                      infoCard.setRenderable(renderable);
                      TextView textView = (TextView) renderable.getView();
                      textView.setText("Value from setImage");
                  })
          .exceptionally(
                  (throwable) -> {
                      throw new AssertionError("Could not load info card view.", throwable);
                  });

如何以及在哪里获取信息卡的TextView的重新粉刷?还考虑到将来需要通过HTTP异步获取值吗?带有thenAccept的lambda函数的ViewRenderable.builder()让我大哭:)

1 个答案:

答案 0 :(得分:0)

您正在通过在构造函数中对其进行膨胀然后再使ViewRenderable构建器对其进行膨胀来两次创建该视图。您保存的不是真正呈现的那个。

您只构建一次ViewRenderable,因此thenAccept的回调仅被调用一次。您需要将其中获得的视图保存到AugmentedImageNode中的某个变量中,然后使用getter函数将其公开,以便可以在AugmentedImageActivity中对其进行检索。然后,您将像以前一样在setText中呼叫onUpdateFrame

请记住,renderable.getView()为您提供了布局视图,您仍然需要调用findViewById来获取textView。