AndroidのView
ドキュメント によると、View(Context)
はコードから構築されたときに使用されView(Context, AttributeSet)
、View(Context, AttributeSet, int)
(API レベル 21 以降View(Context, AttributeSet, int, int)
) はView
XML からインフレートされたときに使用されます。
XML コンストラクターはすべて同じコンストラクターを呼び出すだけで、ほとんどの引数を持つコンストラクターが実際の実装を持つ唯一のコンストラクターであるため、Scala でデフォルトの引数を使用できます。一方、「コード コンストラクター」は別の実装を持っている可能性があるため、実際には Scala からも呼び出した方がよいでしょう。
次の実装が解決策になる可能性があります。
private trait MyViewTrait extends View {
// implementation
}
class MyView(context: Context, attrs: AttributeSet, defStyle: Int = 0)
extends View(context, attrs, defStyle) with MyViewTrait {}
object MyView {
def apply(context: Context) = new View(context) with MyViewTrait
}
「コードコンストラクター」は、次のように使用できます。
var myView = MyView(context)
(実際のコンストラクターではありません)。
そして、もう1つは次のようになります。
var myView2 = new MyView(context, attrs)
var myView3 = new MyView(context, attrs, defStyle)
これは、SDK が期待する方法です。
同様に、API レベル 21 以降では、次のclass
ように定義できます。
class MyView(context: Context, attrs: AttributeSet, defStyle: Int = 0, defStyleRes: Int = 0)
extends View(context, attrs, defStyle, defStyleRes) with MyViewTrait {}
4 番目のコンストラクターは次のように使用できます。
var myView4 = new MyView(context, attrs, defStyle, defStyleRes)
アップデート:
からのように でprotected
メソッドを呼び出そうとすると、少し複雑になります。Java 保護メソッドは、特性から呼び出すことはできません。回避策は、 と の実装にアクセサーを実装することです。View
setMeasuredDimension(int, int)
trait
class
object
private trait MyViewTrait extends View {
protected def setMeasuredDimensionAccessor(w: Int, h: Int): Unit
def callingSetMeasuredDimensionAccessor(): Unit = {
setMeasuredDimensionAccessor(1, 2)
}
}
class MyView(context: Context, attrs: AttributeSet, defStyle: Int = 0)
extends View(context, attrs, defStyle) with MyViewTrait {
override protected def setMeasuredDimensionAccessor(w: Int, h: Int) =
setMeasuredDimension(w, h)
}
object MyView {
def apply(context: Context) = new View(context) with MyViewTrait {
override protected def setMeasuredDimensionAccessor(w: Int, h: Int) =
setMeasuredDimension(w, h)
}
}