我尝试在运行时通过代码在表格布局中创建2,500个图像(一个图像是游戏的一个点),一切都很好,但只有在onTouch事件中,响应非常慢,当我触摸它时需要大约3秒才能响应,我试着通过放置一个可运行的循环测试是20毫秒,当运行时似乎需要1秒才能循环。
public boolean onTouch(View v, MotionEvent event) {
if (v.getId()==R.id.imgTouch) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x1 = event.getX();
y1 = event.getY();
txtTest.setText("" + x1+"/"+img[10][10].getDrawable().toString());
break;
case MotionEvent.ACTION_UP:
break;
}
}
return true;
}
private void LoadScreen() {
int w = (int) (screenWidth / mCols-0.75);
ImageView view;
for (int i = 0; i < mRows; i++) {
TableRow tr = new TableRow(getApplicationContext());
tr.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
for (int j = 0; j < mCols; j++) {
TableRow.LayoutParams lp = new TableRow.LayoutParams(w, w);
lp.setMargins(0,1, 1, 0);
view = new ImageView(getApplicationContext());
view.setLayoutParams(lp);
if (j==mCols-1 || i==mRows-1 || j==0 ||i==0)
view.setBackgroundColor(Color.RED);
else
view.setBackgroundColor(Color.rgb(220,225,219));
view.setImageResource(R.drawable.blank);
tr.addView(view);
img[i][j]=view;
}
tblScreen.addView(tr,new TableLayout.LayoutParams(TableLayout.LayoutParams.FILL_PARENT, TableLayout.LayoutParams.WRAP_CONTENT));
}
}
答案 0 :(得分:1)
视图是包含大量状态的复杂对象,在关键时刻执行非常重要的代码量,主要是在UI线程上。当Android想要显示您的UI时,它需要遍历整个视图层次结构以(a)度量,(b)布局,以及(c)绘制这些视图。对任何视图的更改都可能导致Android重新运行任何或所有这些遍历。此外,还有其他遍历必须在各种情况下发生,例如传播触摸事件。
我无法想到在视图层次结构中应该有2500 ImageView
的任何情况(以及用于排列ImageView
s)的任何容器视图。显然,Android在这样的层次结构中处理UI事件需要花费很长时间,导致对输入事件的响应延迟并且跳过绘制帧。
我不知道您的具体用例,但您应该执行以下任一操作:
View
回收,以便只有您需要显示的视图位于视图层次结构中。这正是像ListView
和RecyclerView
这样的类的用途:它们包含足够的视图来显示适合屏幕的内容,并且它们将回收在屏幕上滚动的视图,因为需要滚动新项目在屏幕上。View
的子类来执行您自己的自定义绘图。每个点不需要一个ImageView
来保持其点的状态,你只需要一个知道如何绘制点的View
。您可以将所有点的状态保存在您喜欢的任何有效数据结构中,并让一个视图绘制所有这些点。考虑这两个选项如何减少视图层次结构的大小(和深度)以及当Android需要遍历它时会产生什么样的效果。