以正确的方式以编程方式实例化自定义视图

Instantiate custom view programmatically the right way

我有一个名为 EventItemView 的自定义视图,我在 和 XML 文件以及自定义适配器(扩展 RecyclerView.Adapter 并用在 RecyclerView) 中。我的问题是它在我的 RecyclerView 中的出现很奇怪,但在我的 XML 文件中却没有:

  1. 使用XML
  2. 声明
  3. 在我的适配器中动态实例化

而且我相信这是由于我在我的适配器中实例化视图的方式,通过执行 new EventItemView(context) 而不是向它传递额外的参数 AttributeSet, int, int 可能需要它来呈现 XML版本。问题是我不知道如何将它们放入我的适配器中。

这是自定义视图声明:

EventItemView.java

public class EventItemView extends FrameLayout {
    public EventItemView(Context context) {
        this(context, null);
    }

    public EventItemView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public EventItemView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr, 0);
        init(context, attrs, defStyleAttr, 0);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public EventItemView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs, defStyleAttr, defStyleRes);
    }

    protected void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        eventItem = new EventItem();

        inflate(context, R.layout.view_event_item, this);
        ButterKnife.bind(this);

        TypedArray values = context.getTheme().obtainStyledAttributes(attrs, R.styleable.EventItemView, defStyleAttr, defStyleRes);

        try {
            setSubtitle(values.getString(R.styleable.EventItemView_subtitle));
            ...
        }
        finally {
            values.recycle();
        }
    }
}

layout/view_event_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@drawable/selector_item_event"
    android:clickable="true"
    android:gravity="center"
    android:layout_height="72dp"
    android:layout_width="match_parent"
    android:orientation="horizontal"
    android:padding="16dp">

    ...

</LinearLayout>

然后在 1) activity.xml 文件中使用此视图:

<com.app.package.view.EventItemView
    android:id="@+id/current_event_view"
    android:layout_height="wrap_content"
    android:layout_width="match_parent" />

和 2) 在 Adapter.java 中:

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    EventItemView itemView = new EventItemView(context);

    return new ViewHolder(itemView);
}

如何使用相关的 attrsdefStyleAttrdefStyleRes 构造函数参数正确实例化我的自定义视图?或者,也许视图出于完全不同的原因以奇怪的方式表现?

您需要先调用 measure(),然后再调用 layout()

实例化的自定义视图不知道它需要膨胀到的大小,因此您需要通过这些调用传递它。

通过更改解决了我的问题

public class EventItemView extends FrameLayout

public class EventItemView extends RelativeLayout

我只是不明白为什么。