在自定义复合控件中使用时,Inflater 静默失败
Inflater silently fails when used in a custom compound control
当我在 xml 中使用自定义复合视图时,它工作得很好。但是当我尝试在代码中创建它时,它显示空白 space.In 这种情况,似乎 inflation 从未完成,因为 OnFinishInflate()
没有被调用。日志中没有关于此的消息。
这里是复合控件:
public class AdvancedColorPickerView extends LinearLayout {
//data...
public AdvancedColorPickerView(Context context) {
super(context);
init(context);
}
public AdvancedColorPickerView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public AdvancedColorPickerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.pdf_advanced_color_picker, this);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
// NEVER EXECUTED when the view is programmatically created
// some code doing stuff with the views...
}
//more code...
}
布局:
<?xml version="1.0" encoding="utf-8"?>
<merge>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="@+id/pdf_color_tab_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<view class = "com.package.ui.AdvancedColorPickerView$NoTouchViewPager"
android:id="@+id/pdf_color_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</merge>
我应该怎么做才能以编程方式成功创建此视图?
编辑:
布局,视图可以正常工作:
<com.package.ui.AdvancedColorPickerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
编辑 2:
我用来以编程方式创建复合视图的代码:
AdvancedColorPickerView advancedColorPicker = new AdvancedColorPickerView(parent.getContext());
advancedColorPicker.setLayoutParams(new AdvancedColorPickerView.LayoutParams(AdvancedColorPickerView.LayoutParams.MATCH_PARENT, AdvancedColorPickerView.LayoutParams.MATCH_PARENT));
advancedColorPicker.setColor(getColor());
advancedColorPicker.setOnColorSelectListener(new AdvancedColorPickerView.OnColorSelectListener() {
@Override
public void onColorSelected(int color) {
//some code
}
});
然后在某个时候我将此视图与其他视图一起添加到容器中并显示它。但我想这并不重要,因为充气机的问题出现在上面代码的第一行。
这是文档告诉我们的关于 onFinishInflate()
的内容:
Finalize inflating a view from XML. This is called as the last phase
of inflation, after all child views have been added.
声明该方法仅在从 XML 膨胀时调用。
我希望创建复合视图,当输入 init()
时,将膨胀包含的视图,在完成时调用它们的 onFinishInflate()
方法,然后调用复合视图的 onFinishInflate()
。但是,当以编程方式创建视图时,后者永远不会发生,因为它永远不会被膨胀。没有 XML 带有参数来膨胀复合视图本身,它是构造的。包含的视图是要显式膨胀的视图(在 init()
中)并且它们的 onFinishInflate()
方法按预期调用。所以 inflation 实际上并没有失败。
通过创建函数 build()
解决了问题,该函数包含我最初打算在 onFinishInflate()
中使用的所有代码。现在我从 onFinishInflate()
调用 build()
,当复合控件从 XML 膨胀时发生,一次从 onAttachedToWindow()
调用,它处理以编程方式处理视图的场景创建。 build()
我正在检查,确保代码没有被调用两次。
代码如下:
public class AdvancedColorPickerView extends LinearLayout {
//data...
public AdvancedColorPickerView(Context context) {
super(context);
init(context);
}
public AdvancedColorPickerView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public AdvancedColorPickerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.pdf_advanced_color_picker, this);
}
private int isBuilt;
private void build()
{
if(isBuilt)
return;
isBuilt = true;
// some code doing stuff with the views...
return;
}
@Override
protected void onAttachedToWindow()
{
super.onAttachedToWindow();
build();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
build();
}
//more code...
}
请注意,onAttachedToWindow()
仅保证在绘制视图之前执行,而不是在测量之前执行。在这种特定情况下,这是一个不错的选择,但对于其他情况,您可能希望使用其他事件。
当我在 xml 中使用自定义复合视图时,它工作得很好。但是当我尝试在代码中创建它时,它显示空白 space.In 这种情况,似乎 inflation 从未完成,因为 OnFinishInflate()
没有被调用。日志中没有关于此的消息。
这里是复合控件:
public class AdvancedColorPickerView extends LinearLayout {
//data...
public AdvancedColorPickerView(Context context) {
super(context);
init(context);
}
public AdvancedColorPickerView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public AdvancedColorPickerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.pdf_advanced_color_picker, this);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
// NEVER EXECUTED when the view is programmatically created
// some code doing stuff with the views...
}
//more code...
}
布局:
<?xml version="1.0" encoding="utf-8"?>
<merge>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="@+id/pdf_color_tab_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<view class = "com.package.ui.AdvancedColorPickerView$NoTouchViewPager"
android:id="@+id/pdf_color_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</merge>
我应该怎么做才能以编程方式成功创建此视图?
编辑:
布局,视图可以正常工作:
<com.package.ui.AdvancedColorPickerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
编辑 2: 我用来以编程方式创建复合视图的代码:
AdvancedColorPickerView advancedColorPicker = new AdvancedColorPickerView(parent.getContext());
advancedColorPicker.setLayoutParams(new AdvancedColorPickerView.LayoutParams(AdvancedColorPickerView.LayoutParams.MATCH_PARENT, AdvancedColorPickerView.LayoutParams.MATCH_PARENT));
advancedColorPicker.setColor(getColor());
advancedColorPicker.setOnColorSelectListener(new AdvancedColorPickerView.OnColorSelectListener() {
@Override
public void onColorSelected(int color) {
//some code
}
});
然后在某个时候我将此视图与其他视图一起添加到容器中并显示它。但我想这并不重要,因为充气机的问题出现在上面代码的第一行。
这是文档告诉我们的关于 onFinishInflate()
的内容:
Finalize inflating a view from XML. This is called as the last phase of inflation, after all child views have been added.
声明该方法仅在从 XML 膨胀时调用。
我希望创建复合视图,当输入 init()
时,将膨胀包含的视图,在完成时调用它们的 onFinishInflate()
方法,然后调用复合视图的 onFinishInflate()
。但是,当以编程方式创建视图时,后者永远不会发生,因为它永远不会被膨胀。没有 XML 带有参数来膨胀复合视图本身,它是构造的。包含的视图是要显式膨胀的视图(在 init()
中)并且它们的 onFinishInflate()
方法按预期调用。所以 inflation 实际上并没有失败。
通过创建函数 build()
解决了问题,该函数包含我最初打算在 onFinishInflate()
中使用的所有代码。现在我从 onFinishInflate()
调用 build()
,当复合控件从 XML 膨胀时发生,一次从 onAttachedToWindow()
调用,它处理以编程方式处理视图的场景创建。 build()
我正在检查,确保代码没有被调用两次。
代码如下:
public class AdvancedColorPickerView extends LinearLayout {
//data...
public AdvancedColorPickerView(Context context) {
super(context);
init(context);
}
public AdvancedColorPickerView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public AdvancedColorPickerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.pdf_advanced_color_picker, this);
}
private int isBuilt;
private void build()
{
if(isBuilt)
return;
isBuilt = true;
// some code doing stuff with the views...
return;
}
@Override
protected void onAttachedToWindow()
{
super.onAttachedToWindow();
build();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
build();
}
//more code...
}
请注意,onAttachedToWindow()
仅保证在绘制视图之前执行,而不是在测量之前执行。在这种特定情况下,这是一个不错的选择,但对于其他情况,您可能希望使用其他事件。