2016-10-15 2 views
1

私はアンドロイドアプリケーション用のカスタムボタンを実装しています。私はAndroid開発のこの側面では比較的新しいので、私はそれについて困っています。カスタムビューはAndroidで描画されません

あり、カスタムの属性:クラスの

<resources> 
<declare-styleable name="CircleButton"> 
    <attr name="stroke_width" format="dimension"/> 
</declare-styleable> 

コード:

class CircleButton (context: Context, 
       attrs: AttributeSet) : View(context, attrs) { 

val paint: Paint = Paint() 

init { 
    var a = context.theme.obtainStyledAttributes(attrs, R.styleable.CircleButton, 0, 0) 
    paint.color = Color.RED 
    try { 
     paint.strokeWidth = a.getDimension(R.styleable.CircleButton_stroke_width, 3f) 
    } finally { 
     a.recycle() 
    } 
} 

var centerX = x + width/2 
var centerY = y + height/2 
var radius = width/2 


override fun onDraw(canvas: Canvas) { 
    super.onDraw(canvas) 
    canvas.drawCircle(centerX.toFloat(), centerY.toFloat(), radius.toFloat(), paint) 
} 

override fun onMeasure(w : Int, h : Int) { 
    setMeasuredDimension(w, w) 
} 

それはKotlinですが、私はそれがすべてのそれとは明らかだと思います。しかし、とにかく、必要に応じてJavaコードを提供することができます。

レイアウトXMLがあります:私は、アプリケーションを実行すると

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" xmlns:custom="http://schemas.android.com/apk/res-auto" 
    android:paddingLeft="0dp" 
    android:paddingRight="0dp" 
    android:paddingTop="0dp" 
    android:paddingBottom="@dimen/activity_vertical_margin"> 

<com.prox1mity.myapplication.CircleButton 
    android:layout_width="250dp" 
    android:layout_height="300dp" 
    android:layout_centerInParent="true" 
    custom:stroke_width="3dp" 
/> 

、私はonDrawメソッドが正常に動作しないことを意味している、唯一の白い画面を参照してください。しかし、円の描画を変更してキャンバスに色を塗りつぶすだけの場合は、canvas.drawColor()で大丈夫です。ビューは完全に塗りつぶされています。それで私のPaintクラスや私の間違った座標系の不自由が考えられます。ビューの中心に中心を持つサークルを正しく描くにはどうすればいいですか?

+0

ええと、私はKotlinに慣れていませんが、コードを正しく実行しているならば、あなたは 'centerX'計算から' x'を、そして 'centerY'から' y'を削除します。つまり、 'var centerX = width/2'、' var centerY = height/2'です。 –

+0

まあ、うまくいきません。 –

+1

ああ、そうです。あなたはそれらの計算をそこでやりたくはありません。そこで、 'View'は0次元を持ちます。それらの計算を 'onSizeChanged()'メソッドに移してください。また、簡単なテストをしたい場合は 'onDraw()'にしてください。 –

答えて

0
var centerX = x + width/2 
var centerY = y + height/2 
var radius = width/2 

このコードは、インスタンスの初期化時に評価されます。そして、この時点でwidth = 0とheight = 0です。ビューはまだ測定されていないためです。

あなたはonDrawLog.d(...)またはブレークポイントを追加することができますし、radius = 0

迅速検査のために、あなたがonDrawを変更することができていることがわかります。たぶん、あなたはこれを最適化することができます

override fun onDraw(canvas: Canvas) { 
    super.onDraw(canvas) 

    val centerX = width/2 
    val centerY = height/2 
    val radius = width/2 
    canvas.drawCircle(centerX.toFloat(), centerY.toFloat(), radius.toFloat(), paint) 
} 

コード。 onDrawで割り当てを行うことはあまり良い考えではありません。あなたは説明hereを見つけることができます。

関連する問題