2017-08-08 114 views
0

這是之前詢問的question的後續操作。我使用了Android Parcelable插件從https://github.com/nekocode/android-parcelable-intellij-plugin-kotlin 繼bennyl的建議下,我改變了構造函數生成的代碼,以構造函數以kotlin派生類中的可分發構造函數

class ChessClock(context:Context) : TextView(context), Parcelable { 
    lateinit var player:String 
    constructor(context:Context, p:String, angle:Float) : this(context) { 
     player = p 
     rotation = angle 
    } 
} 

,這擺脫了我曾問起語法錯誤。我現在還有另一個我最初忽略的問題。

該插件生成writeToParcel驗證碼:

override fun writeToParcel(parcel: Parcel, flags: Int) { 
    parcel.writeString(player) 
    parcel.writeFloat(rotation) 
    parcel.writeLong(mTime) 
    parcel.writeInt(mState) 
} 

與此構造:

constructor(parcel: Parcel) :this() { 
    player = parcel.readString() 
    rotation = parcel.readFloat() 
    mTime = parcel.readLong() 
    mState = parcel.readInt() 
} 

(其實,我添加了旋轉的線,但是這不重要。)

現在,構造函數將不會編譯。 this加下劃線,我看到提示 enter image description here 我希望看到類似的東西,

constructor(parcel: Parcel) :this(context, parcel.readString(), parcel.readFloat()) { 
    mTime = parcel.readLong() 
    mState = parcel.readInt() 
} 

但如果我嘗試,我得到的消息,「超類構造函數被調用之前無法訪問上下文。」我對kotlin(和android)很新,我不明白這裏發生了什麼。我試過調用super,但它告訴我預計會調用主構造函數。我也嘗試調用TextView(),但它告訴我預計會撥打thissuper

我看不出有寫的背景下,以包裹的方式,(我不知道這意味着)

你能告訴我的代碼應當如何修改,更重要的是,你能解釋爲什麼嗎?

+0

'context'不是你的'構造函數(parcel:Parcel)的參數' – Les

回答

1

context需要提供以調用this(context,...)構造函數。但是,您無法將constructor(parcel: Parcel)更改爲constructor(context: Context, parcel: Parcel),因爲Parcelable需要`構造函數(包裹:包裹)

發生了什麼事情?你的班級派生自TextView,這需要Context實例化。您的主要constructor就是幹這個......

class ChessClock(context: Context) : TextView(context) ... 

文檔說...

如果類有一個主構造,基本類型可以(而且必須)來初始化就在那裏,用主構造函數的參數。

由於您已選擇使用主構造函數,因此基類必須由該構造函數初始化,並且輔助構造函數鏈必須從主類構造函數鏈中初始化。

constructor(context:Context, p:String, angle:Float) : this(context) ... 
    // notice how the secondary constructor has the context with which to 
    // call the primary constructor 

您所看到的錯誤是由於第二次級構造函數不提供一個背景下,這是調用(它調用了第一次要構造函數)構造函數。

constructor(parcel: Parcel) :this(context, parcel.readString(), parcel.readFloat()) ... 
    // compiler error because "context" has no source, there is no 
    // parameter "context" being supplied 

更重要,所述Parcel構造由Parcelable插件工具添加時其添加Parcelable接口繼承(see the example of a Parcelable implementation)。因此,CREATOR方法(所需的Parcelable.Creator接口)期望找到一個只需要一個Parcel的構造函數。您可能必須調整您的設計,因爲Context不可序列化,因此不應該(不能)放置在Parcel中。您可以查看CREATOR代碼並查看有關修改的內容,但我會建議進行設計更改。

「最佳實踐」是將業務邏輯與UI邏輯分開。在這裏,您已將您的ChessClock綁定到UI對象TextView。一個「ChessClock」的聲音對我來說就像UI,所以也許你需要一個ChessClockData類作爲Parcelable而不是Clock UI傳遞。

+1

感謝您的解釋。我一直在做更多的閱讀,在我看來,我應該一直在Google上搜索「在自定義視圖中保存狀態」。但是,您對設計更改的建議可能會更容易實施。無論如何,我將不得不保存遊戲的狀態。 – saulspatz

相關問題