当我在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()在绘制视图之前执行,例如在测量之前不执行。在这种特定情况下,这是一个不错的选择,但对于其他情况,您可能需要使用另一个事件。

08-16 22:40