Android:requestLayout() 调用不当
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24598977/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android: requestLayout() improperly called
提问by Daiwik Daarun
The following error occurs when I attempt to inflate a layout within a ListView
:
当我尝试在 a 中扩展布局时发生以下错误ListView
:
requestLayout() improperly called by android.widget.TextView{...} during layout: running second layout pass
I am attempting to inflate a layout within a ListView
as follows:
我试图在 a 内膨胀一个布局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{...}
}
The layout being inflated can look as simple as the following, and will still produce the error
被膨胀的布局看起来像下面这样简单,但仍然会产生错误
<TextView
android:id="@+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/txt_size"/>
I have looked into similar questions, and no solutions found seem to work Question 1, Question 2, Question 3.
我研究过类似的问题,但没有找到解决方案似乎适用于问题 1、问题 2、问题 3。
Does anyone know what causes this type of error? Any troubleshooting advice? For more context, this ListView
is displayed within a Fragment
within a ViewPager
有谁知道是什么导致了这种类型的错误?任何故障排除建议?有关更多上下文,这ListView
显示在一个Fragment
内ViewPager
UPDATE
更新
Here is the full XML Layout (minus a bunch of attributes), that still results in the problem
这是完整的 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>
Based on this, I would think the XML itself is not a problem, unless it has to do with the fact that I am using a ViewPager and Fragments
基于此,我认为 XML 本身不是问题,除非它与我使用 ViewPager 和 Fragments 的事实有关
回答by darksaga
This issue seems to be a bug in the android implementation, please see: https://code.google.com/p/android/issues/detail?id=75516
这个问题好像是android实现的一个bug,请看:https: //code.google.com/p/android/issues/detail?id=75516
Activating the fast scroll feature of a ListView
in your code via ListView.setFastScrollEnabled(true)
will trigger this bug and you'll start seeing the
激活ListView
代码中 a 的快速滚动功能viaListView.setFastScrollEnabled(true)
将触发此错误,您将开始看到
requestLayout() improperly called by android.widget.TextView{...} during layout: running second layout pass
requestLayout() 在布局期间被 android.widget.TextView{...} 错误调用:运行第二个布局传递
message in your console.
控制台中的消息。
This bug must have been introduced in one of the KitKat (4.4.x) updates, as I've not seen it with the initial KitKat (4.4.0) release. Apart from the ugly console spamming with the debug message from above, there seem to be no other impacts (maybe performance in some cases, which I haven't tested).
这个错误一定是在 KitKat (4.4.x) 更新之一中引入的,因为我没有在最初的 KitKat (4.4.0) 版本中看到它。除了丑陋的控制台垃圾邮件和上面的调试消息外,似乎没有其他影响(在某些情况下可能是性能,我还没有测试过)。
Cheers
干杯
PS: it's not the first time that the fast scroll feature is bugged, e.g. https://code.google.com/p/android/issues/detail?id=63545, 63545 was fixed in KitKat 4.4.3 but 75516 poped up thereafter --> seems to be a vexed subject for google ;-)
PS:这不是第一次快速滚动功能被窃听,例如https://code.google.com/p/android/issues/detail?id=63545, 63545 在 KitKat 4.4.3 中被修复但 75516 弹出此后 --> 似乎是 google 的一个恼人的话题 ;-)
EDIT May 12 2015:
2015 年 5 月 12 日编辑:
I updated my Nexus 7 to Android 5.1 some minutes ago (was Running 5.0 before) and stopped seeing this issue in this new version. As the appearance of the FastScroll indicator also changed in 5.1, I assume that google fixed this issue or at least commented out those ugly lines that spammed the console...
几分钟前我将我的 Nexus 7 更新到了 Android 5.1(之前运行的是 5.0)并且在这个新版本中不再看到这个问题。由于 FastScroll 指示器的外观在 5.1 中也发生了变化,我认为 google 修复了这个问题,或者至少注释掉了那些在控制台中发送垃圾邮件的丑陋线条......
75516& 82461are still 'unresolved', but I guess that those refer to the same issue, that's now resolved in 5.1.
回答by axl coder
The problem is that while the method getView()
of your adapter is displaying your layout some other code is trying to access this view to display it, resulting in a collision.
问题是,当getView()
您的适配器的方法显示您的布局时,其他一些代码正在尝试访问此视图以显示它,从而导致冲突。
Note that some methods, that maybe you don't take care of (like setScale()
, setTypeFace()
) indeed call requestLayout()
, so it would be interesting what you are doing after your inflate statement.
请注意,某些方法,可能您没有处理(例如setScale()
, setTypeFace()
)确实调用requestLayout()
,因此在您的 inflate 语句之后您正在做的事情会很有趣。
回答by VladimirVip
回答by Joaquin Iurchuk
I fixed this issue by disabling fastScroll on the ListView in the XML.
我通过在 XML 中的 ListView 上禁用 fastScroll 解决了这个问题。
<ListView
android:id="@+id/mListview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fastScrollEnabled="false"
/>
回答by Thomas R.
I had the same issue with Kitkat 4.4.4 on Motorola X with Genymotion. In my case the list item is a simple CheckedTextView and the error occurred in AppCompatCheckedTextView.
我在使用 Genymotion 的摩托罗拉 X 上使用 Kitkat 4.4.4 时遇到了同样的问题。在我的例子中,列表项是一个简单的 CheckedTextView,错误发生在 AppCompatCheckedTextView 中。
As a normal implementation I inflated the item from XML layout file like below:
作为正常实现,我从 XML 布局文件中夸大了项目,如下所示:
if (convertView == null) {
convertView = inflater.inflate(R.layout.checkable_list_entry, parent, false);
}
After some trying I found out that this has something to do with XML inflation. I don't know the root cause, but as a solution I decided to inflate the list item by code and set all the properties by code too.
经过一些尝试,我发现这与 XML 膨胀有关。我不知道根本原因,但作为解决方案,我决定按代码扩充列表项并按代码设置所有属性。
It ended up like this:
结果是这样的:
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;
}
回答by Javier Torón
In my case this warning prevented a button from showing up in API 21 devices. The button visibility was previously set to GONE.
就我而言,此警告阻止了按钮在 API 21 设备中显示。按钮可见性以前设置为 GONE。
The only workaround I got it was setting to INVISIBLE instead of GONE for API 21. It wasn't a real solution but it was acceptable for me.
我得到的唯一解决方法是将 API 21 设置为 INVISIBLE 而不是 GONE。这不是一个真正的解决方案,但对我来说是可以接受的。
I only post this because it can be useful from somebody.
我发布这个只是因为它可能对某人有用。
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
theButton.setVisibility(View.INVISIBLE);
}
else {
theButton.setVisibility(View.GONE);
}
回答by CoolMind
In my case (Samsung Galaxy S4, API 21) this happened in ListView with EditTexts. I have a listener for field validation. Something like:
在我的情况下(三星 Galaxy S4,API 21),这发生在带有 EditTexts 的 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);
}
}
});
After settinging focus in one of these EditTexts an above check is called. After that a TextView will change (the TextView contains an error message and lies over the EditText). Setting focus to the second or the third EditText led to permanent request of the first EditText and return to current. An applications runs in infinite loop of requests (focus edittext 1, unfocus edittext 1, focus 3, unfocus 3, focus 1, etc).
在这些 EditTexts 之一中设置焦点后,将调用上述检查。之后,TextView 将更改(TextView 包含一条错误消息并位于 EditText 之上)。将焦点设置到第二个或第三个 EditText 导致第一个 EditText 的永久请求并返回到当前。应用程序在请求的无限循环中运行(focus edittext 1、unfocus edittext 1、focus 3、unfocus 3、focus 1 等)。
I tried to set listView.setFastScrollEnabled(false). Also I tried a requestLayout() of some elements like in https://github.com/sephiroth74/HorizontalVariableListView/issues/93with no chances. Currently I made that TextView of fixed width and height in XML:
我试图设置 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"
.../>
After some experiments I noticed that a height of 20dp can be replaced with "wrap_content". But if a text is too long that divides into 2 lines, the application again catches in the infinite loop. So, android:singleLine="true"
will help. It is deprecated, but amazingly android:maxLines="1"
with android:lines="1"
don't help as they again request layout.
Eventually we have:
经过一些实验,我注意到 20dp 的高度可以替换为“wrap_content”。但是,如果文本太长而分成 2 行,应用程序将再次陷入无限循环。所以,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"/>
That's not a good solution, but at least it breaks the infinite loop.
这不是一个好的解决方案,但至少它打破了无限循环。
回答by ksarmalkar
This might happen if you are using some 3rd party extension of ListView. Replace that with standard ListView and check if it still throws the error.
如果您使用的是 ListView 的某些 3rd 方扩展,则可能会发生这种情况。用标准 ListView 替换它并检查它是否仍然抛出错误。
I had similar problem. Please check Android layout: running second layout passand my answer.
我有类似的问题。请检查Android 布局:运行第二个布局传递和我的答案。
回答by Ghasem Sadeghi
I had a problem with the same warning log :
我遇到了相同警告日志的问题:
requestLayout() improperly called by android.support.v7.widget.AppCompatTextView {...} during layout: running second layout pass
I was working with recylcerview and going to update it with new data.
我正在使用 recylcerview 并准备用新数据更新它。
对我有用的唯一解决方案如下:
Step(1). Remove current data :
第1步)。删除当前数据:
public void removeAll() {
items.clear(); //clear list
notifyDataSetChanged();
}
Step(2). When you want to populate the recyclerview with new data, first set a new LayoutManager to recyclerview again:
第2步)。当你想用新数据填充 recyclerview 时,首先再次设置一个新的 LayoutManager 到 recyclerview:
private void initRecycleView() {
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false));
}
Step(3). Update the recyclerview with new data. for example :
步骤(3)。使用新数据更新回收视图。例如 :
public void refreshData(List newItems) {
this.items = newItems;
notifyItemRangeChanged(0, items.size());
}
回答by Stefan Cizmar
I solved the problem like this:
我解决了这样的问题:
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);
issue is .setVisibility(View.GONE); , change to .setVisibility(View.VISIBLE);
问题是 .setVisibility(View.GONE); , 更改为 .setVisibility(View.VISIBLE);