2

我有一个自定义控件,它作为继承RelativeLayout 的其他复合控件(BaseControl)的基础。此 BaseControl 旨在简化在每个控件上扩展 XML 并在此之后对其进行初始化。一切都在构造函数中完成:

abstract class BaseControl extends RelativeLayout {

    public BaseControl(Context context) {
        super(context);
        this.baseInitializeControl(context, null);
    }

    public BaseControl(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.baseInitializeControl(context, attrs);
    }

    public BaseControl(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.baseInitializeControl(context, attrs);
    }

    private void baseInitializeControl(Context context, AttributeSet attrs) {
        int layoutId = this.getControlLayoutId();
        if(layoutId != 0) {
            LayoutInflater inflater = LayoutInflater.from(getContext());
            inflater.inflate(layoutId, this);
        }

        this.initializeControl(context, attrs);
    }

    protected abstract int getControlLayoutId();
    protected abstract void initializeControl(Context context, AttributeSet attrs);
}

实际的问题是我将 OnItemClickedListener 设置为控件的内部 ListView 但它不响应任何点击,这是我在抽象 BaseControl 类之前没有的问题。我在 onFinishInflate 中调用 ListView 的 setOnItemClickedListener 方法解决了这个问题。

所以我有CustomList1和CustomList2,都继承了BaseControl。在 CustomList1 我有:

@Override
protected int getControlLayoutId() {
    return R.layout.custom_list_1;
}

@Override
protected void initializeControl(Context context, AttributeSet attrs) {
    this.mListView = this.findTypedViewById(R.id.listView);

    CustomAdapter adapter = new CustomAdapter(getContext());
    this.mListView.setAdapter(adapter);
}

@Override
protected void onFinishInflate() {
    super.onFinishInflate();

    this.mListView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parentView, View childView, int position, long id) {
            HistoryGroupList.this.onListItemClicked(parentView, childView, position, id);
        }
    });
}

private void onListItemClicked(AdapterView<?> parentView, View childView, int position, long id) {
    CustomAdapter adapter = (CustomAdapter) this.mListView.getAdapter();
    CustomData data = adapter.getItem(position);

    CustomList2 list = new CustomList2(getContext(), data); // CustomList2 should query more data here.

    this.addView(list); // The new View is added in front of the current one
}

到目前为止一切顺利,第一个 CustomList 响应单击的项目,创建一个新控件(其中包含第二个列表视图)并将其显示在前面。

第二个控件 (CustomList2) 几乎是相同的代码,它只在 getControlLayoutId() 中返回不同的 id,在 onListItemClicked(...) 中显示一个 Toast,并使用其构造函数的第二个参数来创建不同的适配器。问题是这第二个控件没有执行 onFinishInflate(),尽管它正在膨胀 BaseControl 中的 xml。如果我将此控件作为 XML 标记添加到另一个布局中,则 onFinishInflate() 方法将正常执行。

你知道为什么这个方法没有被执行吗?或者也许是解决 setOnItemClickedListener 方法问题的解决方法。

谢谢!麦克风

4

2 回答 2

0

在创建监听器后尝试调用 super.onFinishInflate()。这似乎很奇怪,但我从过去的经验中注意到,有时该方法会在超级调用之后终止。

@Override
protected void onFinishInflate() {
    this.mListView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parentView, View childView, int position, long id) {
            HistoryGroupList.this.onListItemClicked(parentView, childView, position, id);
        }
    });

    super.onFinishInflate();    
}
于 2012-08-08T18:44:30.960 回答
-1

类似的问题只是setOnItemClickListener在调用Inflate(对我来说很好)之后提出的。

于 2016-02-22T20:01:58.347 回答