正在从自定义视图更新 Android UI
Updating Android UI from custom view
我是 Android 开发的新手,仍然难以理解框架的工作原理。我试着写一个简单的游戏来获得一些经验,我想在下面寻求一些帮助。
在我的主要 Activity 中,我有一些 TextView 来显示我游戏中的各种数据,在这些视图下我有一个名为 AnimatedView 的自定义视图,它具有 canvas 我为游戏本身绘制对象的地方。基于 Canvas 上的对象,我想更新 TextView 以显示例如对象的数量,玩家所在的级别等
问题是,即使我可以使用以下代码获取 TextView 对象,当我调用 textView.setText(...) 时,UI.[=15= 上没有任何变化]
下面是我的真实代码的简化版本,用于演示问题:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
...
tools:context="com.danielsh.test.teststuff.MainActivity"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/myTextView"
android:text="Change this!" />
<com.danielsh.test.teststuff.AnimatedView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/animView" />
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
AnimatedView.java
public class AnimatedView extends View {
public AnimatedView(Context context, AttributeSet attrs) {
super(context, attrs);
final Handler uiHandler = new Handler();
final Runnable runnable = new Runnable() {
public void run() {
LayoutInflater inflater = LayoutInflater.from(getContext());
LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.activity_main, null, false);
TextView textView = (TextView) layout.findViewById(R.id.myTextView);
textView.setText("" + (System.currentTimeMillis() / 1000));
textView.invalidate();
}
};
uiHandler.postDelayed(runnable, 1000);
}
}
我假设我没有使用 UI 上可见的实际 TextView 对象,但不确定这样做的正确方法是什么。
任何帮助或指向处理相同问题的现有 post 的任何帮助将不胜感激。
我不清楚你想用 AnimatedView
做什么,所以我无法给你一个真正的解决方案来说明它如何正常工作,只能根据你的问题在这里。如果这是您的完整实施,您也许应该尝试在 activity 本身中实施它的行为。
在您发布的 Runnable
中,您从 XML 扩充了您的布局。这意味着您创建新的布局和视图并将它们分配给您的局部变量。这些视图不是 activity 中显示的布局层次结构的一部分。因此,当您更新 TextView
的文本时,您将永远看不到任何更改。
旁注:使用 postDelayed(Runnable, long)
而不是创建新的 Thread
。
我是 Android 开发的新手,仍然难以理解框架的工作原理。我试着写一个简单的游戏来获得一些经验,我想在下面寻求一些帮助。 在我的主要 Activity 中,我有一些 TextView 来显示我游戏中的各种数据,在这些视图下我有一个名为 AnimatedView 的自定义视图,它具有 canvas 我为游戏本身绘制对象的地方。基于 Canvas 上的对象,我想更新 TextView 以显示例如对象的数量,玩家所在的级别等
问题是,即使我可以使用以下代码获取 TextView 对象,当我调用 textView.setText(...) 时,UI.[=15= 上没有任何变化]
下面是我的真实代码的简化版本,用于演示问题:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
...
tools:context="com.danielsh.test.teststuff.MainActivity"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/myTextView"
android:text="Change this!" />
<com.danielsh.test.teststuff.AnimatedView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/animView" />
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
AnimatedView.java
public class AnimatedView extends View {
public AnimatedView(Context context, AttributeSet attrs) {
super(context, attrs);
final Handler uiHandler = new Handler();
final Runnable runnable = new Runnable() {
public void run() {
LayoutInflater inflater = LayoutInflater.from(getContext());
LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.activity_main, null, false);
TextView textView = (TextView) layout.findViewById(R.id.myTextView);
textView.setText("" + (System.currentTimeMillis() / 1000));
textView.invalidate();
}
};
uiHandler.postDelayed(runnable, 1000);
}
}
我假设我没有使用 UI 上可见的实际 TextView 对象,但不确定这样做的正确方法是什么。
任何帮助或指向处理相同问题的现有 post 的任何帮助将不胜感激。
我不清楚你想用 AnimatedView
做什么,所以我无法给你一个真正的解决方案来说明它如何正常工作,只能根据你的问题在这里。如果这是您的完整实施,您也许应该尝试在 activity 本身中实施它的行为。
在您发布的 Runnable
中,您从 XML 扩充了您的布局。这意味着您创建新的布局和视图并将它们分配给您的局部变量。这些视图不是 activity 中显示的布局层次结构的一部分。因此,当您更新 TextView
的文本时,您将永远看不到任何更改。
旁注:使用 postDelayed(Runnable, long)
而不是创建新的 Thread
。