12

ノートアプリをキャッチ

このアプリのようにサークルメニューをやってみます。

「拡張」モードでは、このコンポーネントを次のように描画します。

<RelativeLayout android:id="@+id/bigCircle">
<!--color full borders-->
    <my.custom.component android:id="@+id/middleCircle">
    <!--circle for buttons-->
         <RelativeLayout android:id="@+id/smallCircle">
           <!--minus button-->
         </RelativeLayout>
    </my.custom.component>
</RelativeLayout>

onDrawメソッドでは、withといくつかの数学my.custom.componentを使用して円を8つの部分に分割します。 視覚的には、スクリーンショットに示されているとおりです。しかし、円の一部を押すと、何が起こっているのかをユーザーに示すために、この部分を別の色で再描画する必要があります。android.graphics.Pathandroid.graphics.Paint

たとえば、コンポーネントのキャンバスの一部をキャンバスの別の部分から切り離して再描画する方法android.graphics.Path
言い換えれば、onDrawメソッドでどの再描画キャンバスを実行する必要があるかを知っています。フォトショップでペイントされたドローアブルからビットマップを表示でき、「マルチスクリーンの問題」が発生することを知っています。どのユーザーが押したかを判断する方法を知っています。しかし、キャンバスの一部を選択して再描画する方法がわかりません。

4

1 に答える 1

20

ここでCatchの開発者。私があなたの問題を理解しているなら、あなたはあなたの円形メニューのセクションにハイライト/選択インジケーターを具体的に描く方法を理解するのに苦労しています。

それを実装する方法はたくさんありますが、(を使用して)あなたが傾倒しているのandroid.graphics.Pathは、私たちがそれをどのように行ったかです。キャプチャボタンのビュー階層には、選択範囲のハイライト色(アクティブな選択範囲がある場合)が描画れるキャンバスとして機能する要素があります。

レイアウトに同様のカスタムがある場合は、Viewこの動作をそのように複製できます。Pathまず、特定の円セグメントの選択を定義するが必要になります。を使用しPath.addArc(RectF, float, float)て、必要なピザスライス型のパスを取得できます。

private Path getPathForSegment(float startAngle, float sweep) {
    Point center = new Point(getWidth() / 2, getHeight() / 2);
    RectF rect = new RectF(0f, 0f, getWidth(), getHeight());
    Path selection = new Path();
    selection.addArc(rect, startAngle, sweep);
    selection.lineTo(center.x, center.y);
    selection.close();
    return selection;
}

上記はgetWidth()getHeight()囲んでいるカスタムビューオブジェクト用であるため、選択範囲が描画される円を含む境界ボックスを定義します。

次に、カスタムビューでonDraw(Canvas)、コードがセグメントの選択を描画する必要があると判断した場合は、次のようにします。

@Override
protected void onDraw(Canvas canvas) {
    // Assume one has the rest of these simple helper functions defined
    if (shouldDrawSelection()) {
        float startAngle = getStartAngleOfSelectedSegment();
        float sweep = getSweepAngle();
        Paint paint = getPaintStyleForSelectedSegment();
        Path path = getPathForSegment(startAngle, sweep);
        canvas.drawPath(path, paint);
    }

    // ...

    super.onDraw(canvas);
}

タッチを追跡しているコードの他の領域ではinvalidate()、カスタムビューを呼び出すだけで、入力または状態の変化に基づいて選択パスが再描画されます(または再描画されません)。

newでオブジェクトを使用しないようにすることをお勧めしますonDraw()。そうすれば、これらのビルディングブロック(Paths、Paintsなど)のほとんどを事前に(または最初の発生時に一度)構築して再利用できます。

これがあなたが求めていたものに近いことを願っています!

于 2012-10-29T21:23:11.007 に答える