"在Android 4.3上错误地调用了'requestLayout()"错误

San*_*jay 26 android textview android-custom-view android-layout

我有一个简单的自定义TextView,在其构造函数中设置自定义字体,如下面的代码

public class MyTextView extends TextView {

    @Inject CustomTypeface customTypeface;

    public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        RoboGuice.injectMembers(context, this);
        setTypeface(customTypeface.getTypeface(context, attrs));
        setPaintFlags(getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
    }
}
Run Code Online (Sandbox Code Playgroud)

从Gingerbread到JB 4.2都可以正常工作.但是当我在Android 4.3手机上显示自定义textview时,adb logcat充斥着以下消息.

10-05 16:09:15.225: WARN/View(9864): requestLayout() improperly called by com.cmp.views.MyTextView{42441b00 V.ED.... ......ID 18,218-456,270 #7f060085 app:id/summary} during layout: running second layout pass
10-05 16:09:15.225: WARN/View(9864): requestLayout() improperly called by com.cmp.views.MyTextView{423753d0 V.ED.... ......ID 26,176-742,278 #7f060085 app:id/summary} during layout: running second layout pass
Run Code Online (Sandbox Code Playgroud)

我注意到,它确实减慢了UI的速度.有什么想法为什么会在4.3上发生?

感谢您的帮助.

Phi*_*hil 6

我发现我的应用程序中发生了这个错误.虽然在您提供的代码中找不到这种情况(如果您在代码中的其他位置执行此操作可能会有所帮助),但它有望帮助其他人解决这个不可能跟踪的问题.

我有一条线(当然不是我添加的):

myView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
        //this would then make a call to update another view's layout.
    }
});
Run Code Online (Sandbox Code Playgroud)

在我的应用程序中,我不需要任何监听器,因此删除整个块解决了这个问题.对于那些需要这样的东西的人,记得在布局改变后删除监听器(在这个回调中).


Pau*_*sma 2

查看Android源码,这个问题有更详细的描述:

requestLayout()在布局期间被调用。如果请求视图上没有设置布局请求标志,则没有问题。如果某些请求仍然待处理,那么我们需要清除这些标志并执行完整的请求/测量/布局传递来处理这种情况。

看来这个问题可能与Roboguice有关;请参阅问题#88。建议的解决方案是使用@InjectView:

您现在可以从视图类内部使用@InjectView。只需在填充视图后调用 Injector.injectMembers() 即可:

public class InjectedView extends FrameLayout {

    @InjectView(R.id.view1) View v;

    public InjectedView(Context context) {
        super(context);
        final View child = new View(context);
        child.setId(R.id.view1);
        addView(child);

        RoboGuice.getInjector(context).injectMembers(this);
    }
}
Run Code Online (Sandbox Code Playgroud)

也许您应该考虑RoboGuice.injectMembers(context, this)使用 @InjectView 注释迁移到 View 对象的声明。

  • 我根本不使用 Roboguice,只是在 onCreate 中设置字体。对于我的情况为什么会发生这种情况有什么想法,或者有什么解决方法吗? (2认同)