性能-Android:requestLayout()调用不正确
当我尝试给ListView
中的布局充气时,会发生以下错误:
requestLayout() improperly called by android.widget.TextView{...} during layout: running second layout pass
我正尝试在ListView
中扩大布局,如下所示:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
LayoutInflater inflater = (LayoutInflater) musicActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item, parent, false);
...
}else{...}
}
被夸大的布局看起来像下面这样简单,仍然会产生错误
<TextView
android:id="@+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/txt_size"/>
我调查了类似的问题,但没有找到解决方案,似乎可以解决问题1,问题2,问题3。
有谁知道是什么原因导致这种类型的错误? 有任何故障排除建议吗? 有关更多上下文,请在ViewPager
中的Fragment
中显示此ListView
更新
这是完整的XML布局(减去一堆属性),仍然会导致问题
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/txt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/txt2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/txt3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/txt4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
基于此,我认为XML本身不是问题,除非它与我正在使用ViewPager和Fragments有关
此问题似乎是android实现中的错误,请参阅:[https://code.google.com/p/android/issues/detail?id=75516]
通过ListView.setFastScrollEnabled(true)
在代码中激活ListView
的快速滚动功能将触发此错误,您将开始看到
android.widget.TextView错误地调用了requestLayout(){...} 布局期间:运行第二个布局遍
控制台中的消息。
该错误一定是在KitKat(4.4.x)更新中引入的,因为我在最初的KitKat(4.4.0)版本中没有看到它。 除了上面显示调试消息的丑陋控制台垃圾邮件外,似乎没有其他影响(在某些情况下可能是性能,我没有测试过)。
干杯
附言:这不是第一次快速滚动功能出现错误,例如 [https://code.google.com/p/android/issues/detail?id=63545,] 63545已在KitKat 4.4.3中修复,但随后弹出了75516->似乎已成为Google的烦恼主题;- )
编辑2015年5月12日:
几分钟前,我将Nexus 7更新为Android 5.1(之前运行的是5.0),并停止在此新版本中看到此问题。 由于FastScroll指示器的外观在5.1中也发生了变化,因此我认为google已解决此问题,或者至少已注释掉了那些泛滥控制台的丑陋线条。
75516和82461仍然是“未解决”的,但我想那些是指同一个问题,现在在5.1中已解决。
问题是,当适配器的方法setScale()
显示布局时,其他一些代码试图访问该视图以显示它,从而导致冲突。
请注意,有些方法可能根本不涉及您(例如setScale()
、setTypeFace()
)确实会调用requestLayout()
,因此在执行inflate语句后您会做些有趣的事情。
对我来说,这个问题是在setLayoutParams()
呼叫时发生的。 解决方案是在循环器上发布一个可运行的内容,如此处所述
我通过在XML的ListView上禁用fastScroll来解决此问题。
<ListView
android:id="@+id/mListview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fastScrollEnabled="false"
/>
如果您使用的是ListView的某些第三方扩展,则可能会发生这种情况。 用标准ListView替换它,并检查它是否仍然引发错误。
我有类似的问题。 请检查Android布局:运行第二个布局通行证和我的答案。
我在Genymotion的Motorola X上使用Kitkat 4.4.4遇到了相同的问题。 在我的情况下,列表项是一个简单的CheckedTextView,并且在AppCompatCheckedTextView中发生了错误。
作为正常的实现,我将XML布局文件中的内容夸大如下:
if (convertView == null) {
convertView = inflater.inflate(R.layout.checkable_list_entry, parent, false);
}
经过一番尝试,我发现这与XML膨胀有关。 我不知道根本原因,但是作为一种解决方案,我决定通过代码使列表项膨胀,并且也通过代码设置所有属性。
它最终像这样:
CheckedTextView view;
if (convertView == null) {
view = new CheckedTextView(parent.getContext());
view.setMinHeight(getResources().getDimensionPixelSize(R.dimen.default_touch_height));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
view.setTextAppearance(R.style.SectionEntry);
} else {
view.setTextAppearance(parent.getContext(), R.style.SectionEntry);
}
view.setBackgroundResource(R.drawable.form_element);
view.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
view.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT));
} else {
view = (CheckedTextView) convertView;
}
就我而言,此警告阻止了按钮在API 21设备中显示。 该按钮的可见性先前已设置为“消失”。
我得到的唯一解决方法是将API 21设置为INVISIBLE而不是GONE。这不是真正的解决方案,但对我来说是可以接受的。
我只发布此内容,因为它可能对某些人有用。
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
theButton.setVisibility(View.INVISIBLE);
}
else {
theButton.setVisibility(View.GONE);
}
In my case (Samsung Galaxy S4, API 21) this happened in ListView with EditTexts. I have a listener for field validation. Something like:
edit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
error.setVisibility(View.INVISIBLE);
error.setText("");
} else {
String s = edit.getText().toString();
if (s.isEmpty()) {
error.setText("Error 1");
} else if (s.length() < 2 || s.length() > 100) {
error.setText("Error 2");
}
error.setVisibility(View.VISIBLE);
}
}
});
在这些EditText之一中设置焦点后,将进行上述检查。 之后,TextView将更改(TextView包含错误消息,并且位于EditText上)。将焦点设置到第二个或第三个EditText导致对第一个EditText的永久请求并返回到当前状态。 应用程序在请求的无限循环中运行(焦点编辑文本1,焦点编辑文本1,焦点3,焦点3,焦点1等)。
我试图设置listView.setFastScrollEnabled(false)。 我也尝试了一些元素的requestLayout(),例如[https://github.com/sephiroth74/HorizontalVariableListView/issues/93]。目前,我使用XML来固定宽度和高度的TextView:
<TextView
android:id="@+id/error"
android:layout_width="match_parent" (or "200dp", but not "wrap_content")
android:layout_height="20dp"
.../>
经过一些实验,我注意到可以用“ wrap_content”代替20dp的高度。 但是如果文本太长而分成两行,则应用程序再次陷入无限循环。 因此,android:singleLine="true"
将有所帮助。 它已被弃用,但令人惊讶的是android:maxLines="1"
和android:lines="1"
并没有帮助,因为它们再次请求布局。最终,我们有了:
<TextView
android:id="@+id/error"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="#f00"
android:textSize="20sp"
tools:text="Error message"/>
这不是一个好的解决方案,但至少它打破了无限循环。
我在使用相同的警告日志时遇到了问题:
requestLayout() improperly called by android.support.v7.widget.AppCompatTextView {...} during layout: running second layout pass
我正在使用recyclerview并打算用新数据更新它。
唯一对我有用的解决方案如下:
第1步)。 删除当前数据:
public void removeAll() {
items.clear(); //clear list
notifyDataSetChanged();
}
第2步)。 当您想用新数据填充recyclerview时,首先将一个新的LayoutManager设置为recyclerview:
private void initRecycleView() {
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false));
}
步骤(3)。 使用新数据更新recyclerview。 例如 :
public void refreshData(List newItems) {
this.items = newItems;
notifyItemRangeChanged(0, items.size());
}
尝试从xml中删除textSize并将其设置为Java代码。 我认为这导致其布局两次。
有时您可能已经解决了该问题,但是仍然存在相同的错误,所以您需要关闭Visual Studio,然后从项目中删除所有bin和obj文件夹,然后从模拟器中卸载应用程序。 然后哇! 一切都会好的