在Android(Xamarin)子类定义中链接构造函数

在Android(Xamarin)子类定义中链接构造函数,android,xamarin.android,Android,Xamarin.android,为了尽量减少重复代码,我想在自定义GridView中使用构造函数链接 下面的定义在每个构造函数中调用Init()方法: public class GridView2 : GridView { //public GridView2(IntPtr jRef, JniHandleOwnership jTransfer) : base(jRef, jTransfer) { } public GridView2(Context context)

为了尽量减少重复代码,我想在自定义
GridView
中使用构造函数链接

下面的定义在每个构造函数中调用
Init()
方法:

public class GridView2 : GridView        
{
    //public GridView2(IntPtr jRef, JniHandleOwnership jTransfer) : base(jRef, jTransfer) { }        

    public GridView2(Context context) 
        : base(context)
    {
        Init();
    }

    public GridView2(Context context, IAttributeSet attrs) 
        : base(context, attrs)
    {
        Init(); 
    }

    public GridView2(Context context, IAttributeSet attrs, int defaultStyleAttr) 
        : base(context, attrs, defaultStyleAttr)
    {
        Init(); 
    }

    public GridView2(Context context, IAttributeSet attrs, int defaultStyleAttr, int defStyleRes) 
        : base(context, attrs, defaultStyleAttr, defStyleRes)
    {
        Init();
    }

    private void Init()
    {
        // ...
    }
}
我希望通过使用构造函数链接来避免这种情况。但是,这样做会导致对API的依赖,我不确定这样做是否值得?

此依赖关系发生在下面的第二个构造函数中

public class GridView2 : GridView        
{
    //public GridView2(IntPtr jRef, JniHandleOwnership jTransfer) : base(jRef, jTransfer) { }        

    public GridView2(Context context) 
        : this(context, null) { }
    // dependency API. defStyleAttr could change
    public GridView2(Context context, IAttributeSet attrs) 
        : this(context, attrs, Android.Resource.Attribute.GridViewStyle) { }
    public GridView2(Context context, IAttributeSet attrs, int defaultStyleAttr) 
        : this(context, attrs, defaultStyleAttr,0) { }
    public GridView2(Context context, IAttributeSet attrs, int defaultStyleAttr, int defStyleRes) 
        : base(context, attrs, defaultStyleAttr, defStyleRes)
    {
        Init();
    }

    private void Init()
    {
        // ...
    }
}
这是由于Android本身是如何定义这个构造函数的

public class GridView extends AbsListView {

    public GridView(Context context) {
        this(context, null);
    }

    // hardcoded value for defStyleAttr
    public GridView(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.gridViewStyle);
    }

    public GridView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public GridView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        // ...
    }   
}
我希望通过使用构造函数链接来避免这种情况。然而,这样做会导致对API的依赖,我不确定这种便利是否值得

即使您使用
publicGridView2(上下文):base(上下文)
创建
GridView2
实例。仍然应用gridview默认样式,因为
这(context,attrs,R.attr.gridViewStyle)GridView
源代码中的构造函数链,仍然调用了code>


因此,您正确地应用了构造函数链。

我关心的是
语句中的Android.Resource.Attribute.GridViewStyle硬编码值的
GridView2(上下文上下文上下文,IATributteSet属性)
b/c。如果Android实现更改并使用,比如R.attr.gridViewStyleNew,
GridView2
将中断。我更喜欢
GridView2
中链接的语法简洁性,但如果在所有自定义视图中都一致使用,依赖性会增加,一旦中断,就会设置更多故障排除和代码更改。这是一个我不确定是否值得冒的风险。你所说的安卓系统实施变更是什么意思
Android.Resource.Attrubute.GridViewStyle
是一个Android系统资源。它总是在那里。如果你指的是Android系统的定制,那么,修改这个名称是错误的,因为它会影响所有利用这个系统资源的现有应用程序。还有基类(GridView)构造函数链的问题。如果该实现发生了变化(例如,链被删除,因此它们各自有自己的实现),那么代码就有另一个中断的机会。同样,系统自定义更改
GridView
的实现是错误的,因为这将导致所有现有应用中断,它利用了
GridView
。这就是android应用程序有android API级别限制的原因。如果你真的想创建一个完全独立于android系统的
GridView
。您需要在应用程序中创建自己的
GridView 2
实现(而不是从原始
GridView
派生)以及自己的样式资源。我使用第一个选项,因为第二个选项中的链本身通过阻止调用基构造函数为每个构造函数创建依赖关系。如果任何基本构造函数的实现发生更改,那么GridView2将中断。。。即使它是开源的,并且堆栈并行运行,模仿也不同于消费(子类化)。即使在原始Java(Dalvik)中,我也不认为出于同样的原因我会模仿基类。