Android:requestLayout()调用不正确
当我尝试在Android:requestLayout()调用不正确,android,performance,android-listview,Android,Performance,Android Listview,当我尝试在列表视图中膨胀布局时,会发生以下错误: requestLayout() improperly called by android.widget.TextView{...} during layout: running second layout pass 我正试图在列表视图中为布局充气,如下所示: @Override public View getView(int position, View convertView, ViewGroup parent) { if(conve
列表视图中膨胀布局时,会发生以下错误:
requestLayout() improperly called by android.widget.TextView{...} during layout: running second layout pass
我正试图在列表视图中为布局充气,如下所示:
@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"/>
基于此,我认为XML本身不是问题,除非它与我使用的是ViewPager和片段这一事实有关,请尝试从XML中去掉textSize并在Java代码中进行设置。我认为这会导致布局两次。问题是,当适配器的方法getView()
显示布局时,其他一些代码试图访问此视图以显示布局,从而导致冲突
请注意,一些可能您不关心的方法(如setScale()
,setTypeFace()
)确实调用了requestLayout()
,因此在您的充气语句之后您所做的事情会很有趣。如果您使用的是ListView的第三方扩展,则可能会发生这种情况。用标准ListView替换它,并检查它是否仍然抛出错误
我也有类似的问题。请检查并回答我的问题。这个问题似乎是android实现中的一个bug,请参阅:
通过ListView在代码中激活ListView
的快速滚动功能。setFastScrollEnabled(true)
将触发此错误,您将开始看到
android.widget.TextView{…}未正确调用requestLayout()
布局期间:运行第二个布局过程
在您的控制台中显示消息
这个bug一定是在KitKat(4.4.x)的一个更新中引入的,因为我在KitKat(4.4.0)的初始版本中没有看到它。除了从上面发出的带有调试消息的丑陋的控制台垃圾邮件外,似乎没有其他影响(在某些情况下可能是性能,我还没有测试)
干杯
PS:这不是第一次对快速滚动功能进行窃听,例如,KitKat 4.4.3中修复了63545,但随后出现了75516-->似乎是谷歌最头疼的话题;-)
2015年5月12日编辑:
几分钟前,我将Nexus7更新为Android 5.1(之前运行的是5.0),在这个新版本中,我不再看到这个问题。由于FastScroll指示器的外观在5.1中也发生了变化,我认为谷歌已经解决了这个问题,或者至少已经注释掉了那些向控制台发送垃圾信息的丑陋线条
&仍然是“未解决的”,但我想它们指的是同一个问题,现在在5.1中已解决。我通过在XML中的ListView上禁用fastScroll解决了这个问题
<ListView
android:id="@+id/mListview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fastScrollEnabled="false"
/>
我对摩托罗拉X上的Kitkat 4.4.4和Genymotion有同样的问题。在我的例子中,列表项是一个简单的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;
}
mHolder.txt_fword.setTextSize(22);
mHolder.txt_farth.setTextSize(22);
mHolder.txt_fdef.setTextSize(22);
mHolder.txt_fdef2.setTextSize(22);
mHolder.txt_frem.setTextSize(22);
//if (fdef2.get(pos).equals("")) mHolder.txt_fdef2.setVisibility(View.GONE);
//if (frem.get(pos).equals("")) mHolder.txt_frem.setVisibility(View.GONE);
在我的例子中,此警告阻止按钮在API 21设备中显示。按钮可见性以前设置为“消失”
我得到的唯一解决办法是将其设置为不可见,而不是API 21。这不是一个真正的解决方案,但对我来说是可以接受的
我之所以发布这篇文章,是因为它可能对某些人有用
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
theButton.setVisibility(View.INVISIBLE);
}
else {
theButton.setVisibility(View.GONE);
}
在我的例子中(三星Galaxy S4,API 21),这发生在带有EditText的ListView中。我有一个用于字段验证的侦听器。比如:
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);
}
}
});
这不是一个好的解决方案,但至少它打破了无限循环。对我来说,这个问题是在调用setLayoutParams()
时发生的。解决方案在活套上发布了runnable:
//java
imageView.post(新的Runnable(){
@重写公共void run(){
imageView.setLayoutParams(参数);
}
});
//kotlin
post(可运行{imageView.setLayoutParams(params)})
有时您可能已经修复了该问题,但它仍然保留相同的错误,因此您需要关闭visual studio,然后从项目中删除所有bin和obj文件夹,然后从emulator中卸载应用程序。那么,瓦拉!!一切正常我在相同的警告日志中遇到问题:
requestLayout() improperly called by android.support.v7.widget.AppCompatTextView {...} during layout: running second layout pass
我正在使用recylcerview,并打算用新数据更新它。
唯一适合我的解决方案如下:
步骤(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());
}
我这样解决了这个问题:
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;
}
mHolder.txt_fword.setTextSize(22);
mHolder.txt_farth.setTextSize(22);
mHolder.txt_fdef.setTextSize(22);
mHolder.txt_fdef2.setTextSize(22);
mHolder.txt_frem.setTextSize(22);
//if (fdef2.get(pos).equals("")) mHolder.txt_fdef2.setVisibility(View.GONE);
//if (frem.get(pos).equals("")) mHolder.txt_frem.setVisibility(View.GONE);
问题是.setVisibility(View.GONE),更改为.setVisibility(View.VISIBLE) 谢谢你的建议!不幸的是,这不起作用,请看我的更新。这有什么好运气?我面临着同样的问题:(不幸的是,没有-因为这只是一个警告,我可能会遗憾地忽略它。…
内部的first if块中还发生了什么?它通过ViewHolder重用视图看看这个。花了最后一个小时试图解决这个问题。关闭快速滚动,消息就消失了。至少我知道这不是我想要的d、 感谢您提供的信息。是否有任何解决方案可以删除此日志?我正在尝试将我的ImageView
大小保留在onSaveInstanceState
中,此时出现此错误并使我的应用程序崩溃。不确定如何修复此日志,但此答案比“这是一个错误”更具描述性,非常感谢。因此,对我来说,这不是滚动问题。如果你想使用快速滚动,我认为这不是一个解决方案。我可能也有同样的问题,但该链接已断开。编辑:通过以下方式解决:imageView.post(新运行
mHolder.txt_fword.setTextSize(22);
mHolder.txt_farth.setTextSize(22);
mHolder.txt_fdef.setTextSize(22);
mHolder.txt_fdef2.setTextSize(22);
mHolder.txt_frem.setTextSize(22);
//if (fdef2.get(pos).equals("")) mHolder.txt_fdef2.setVisibility(View.GONE);
//if (frem.get(pos).equals("")) mHolder.txt_frem.setVisibility(View.GONE);