当我在xml中使用自定义复合视图时,它工作得很好。但是当我尝试在代码中创建它时,它会显示空白空间。在这种情况下,由于未调用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()
的内容:
完成从XML扩展视图的工作。这称为最后阶段
在添加了所有儿童视图之后的通货膨胀率。
声明仅在从XML扩展时才调用该方法。
我希望在输入init()
时创建compund视图将膨胀所包含的视图,完成后调用其onFinishInflate()
方法,然后再调用复合视图的onFinishInflate()
。但是,以编程方式创建视图时,后者永远不会发生,因为它绝不会膨胀。没有XML,它的参数可以使复合视图本身膨胀。包含的视图是要显式放大的视图(在init()
中),并且按预期方式调用其onFinishInflate()
方法。因此,通胀实际上并没有失败。
通过创建函数build()
来解决该问题,该函数包含我最初打算在onFinishInflate()
中使用的所有代码。现在,我从build()
调用onFinishInflate()
,这是从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()
在绘制视图之前执行,例如在测量之前不执行。在这种特定情况下,这是一个不错的选择,但对于其他情况,您可能需要使用另一个事件。