それでは、結果をご覧ください。
クールなエフェクト、リッチなアニメーション、爆発的なエフェクト
ドーン
I. デザイン思考
時計コントロールの醜いデザインはもう見飽きました!現実の振り子時計の丸い文字盤デザインと、電子時計のデジタル表示の文字盤デザインを抽象化し、「丸」「デジタル表示」「時間の経過感」などの言葉を抽出し、最終的なUIデザインに融合させました。丸」「デジタル表示」「時間の経過感」などの言葉を抽出し、その言葉の特徴を融合させ、最終的なUIデザインに落とし込むことで、かっこいいUIコントロールが誕生しました!
時計ディスクをトグルして時計を調整し、時間の経過とともに、トグルディスクも自動的に元の位置に戻ることができ、相互作用の論理は自然でスムーズです。
静寂」、「夜」、「月光」、「純粋」など、より多くの意味合いを反映させるために、さまざまなテーマカラーを設定できます。「など。コントロールのデザイン自体は非常にスケーラブルです。
II.実施方法
デザインのアイデアが明確になって、それを実現する方法を考えなければなりません。誰か、スローガンに乗ってください。
誰もいません。
私よりも。
よく分かっています。
実現
クラスデザイン
あなたがUI図から観察することができるように、クロックコントロールは、4つの大きなダイヤル、すなわち午前と午後のダイヤル、時間ダイヤル、分ダイヤル、および秒ダイヤルで構成されています。アイデアの実装では、まずディスクコントロールの親クラスDiskViewの抽象化を検討し、ダイヤルの残りの部分は、DiskViewから継承することができます。ダイヤルの様々な、そして最後にそれらのすべてを組み立てるためにViewGroupを使用することができます。
DiskView は基本クラスとして、アニメーション、ドラッグ、クリック、その他のインタラクションのロジックを引き受ける必要があり、文字盤の半径、文字盤の回転角度などのパブリックプロパティも持っています。
public class DiskView extends View {
private static final String TAG = "DiskView";
Context mContext;
/**
* ディスク半径
*/
int mRadius = 0;
/**
* 最初の指のプレスの座標
*/
float startX, startY;
/**
* 現在の指のプレスポイントの座標
*/
float curX, curY;
/**
* 指が初めて押される位置と、最初の位置との間の角度。
*/
int startDegree;
/**
* 指が押される位置と初期位置との角度。
*/
int curDegree;
/**
* 初期位置に対するディスクの現在位置の角度、初期位置の角度は0度である。
*/
int degree = 0;
/**
* 指を離した後、元の状態に戻す必要があるか?
*/
boolean isNeedReturn = true;
ValueAnimator animator;
}
UI
座標と角度が決まったら、次は描画を考えます。canvas graphics drawing apiを使って描画し、各図形の位置を計算し、対応する色を与えます。円の中心を中心にrotateメソッドを呼び出し、ある角度でテキストを描画します。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//
mPaint.setColor(diskColor);
canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
//
mPaint.setColor(numColor);
Rect bounds = new Rect();
for (int i = 0; i < 60; i++) {
if (i == minute) {
mPaint.setColor(selectNumColor);
} else {
mPaint.setColor(numColor);
}
if (i % 10 != 0) {
if (i % 5 == 0) {
canvas.drawCircle(mRadius, 2 * mRadius - textHeight * 3 / 2, DisplayUtils.sp2px(mContext, 20) / 4, mPaint);
} else {
canvas.drawCircle(mRadius, 2 * mRadius - textHeight * 3 / 2, DisplayUtils.sp2px(mContext, 20) / 6, mPaint);
}
} else {
mPaint.getTextBounds(i + "", 0, (i + "").length(), bounds);
textHeight = bounds.height();
canvas.drawText(i + "", mRadius - bounds.width() / 2, mRadius * 2 - bounds.height(), mPaint);
}
canvas.rotate(-6, mRadius, mRadius);
}
}
インタラクション・ロジック
コントロールのインタラクションロジックのほとんどは、それぞれonTouchEventのコールバックで処理され、ユーザーのクリック、移動、リフトアクションは、ターゲットを絞った処理を行うには、キーのコアは、各ケースのディスクの角度を計算することであり、その後、アニメーターを介して良好な対応する値を計算するために、リアルタイムのインターフェイスをリフレッシュすることができます。注意しなければならないのは、ユーザーの始点が円盤の限界を超えないことです。
@Override
public boolean onTouchEvent(MotionEvent event) {
curX = event.getX();
curY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
startDegree = computeCurrentAngle(curX, curY);
//出発点はディスクの境界を越えてはならない
if (Math.sqrt(
(startX - mRadius) * (startX - mRadius) + (startY - mRadius) * (startY - mRadius)
) > mRadius) {
startDegree = 0;
}
break;
case MotionEvent.ACTION_MOVE:
//出発点はディスクの境界を越えてはならない
if (Math.sqrt(
(startX - mRadius) * (startX - mRadius) + (startY - mRadius) * (startY - mRadius)
) > mRadius) {
return false;
}
curDegree = computeCurrentAngle(curX, curY);
postInvalidate();
break;
case MotionEvent.ACTION_UP:
if (Math.sqrt(
(startX - mRadius) * (startX - mRadius) + (startY - mRadius) * (startY - mRadius)
) > mRadius) {
return false;
}
int tmpDegree = degree;//指で押す前のディスクの角度
degree = degree + curDegree - startDegree;
if (Math.abs(degree) > 360) {
degree %= 360;
}
startDegree = 0;
curDegree = 0;
startX = 0;
startY = 0;
//ポジションに戻る必要があるかどうか
if (isNeedReturn) {
animator = ValueAnimator.ofInt(degree, tmpDegree);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
degree = (int) animation.getAnimatedValue();
postInvalidate();
}
});
animator.setDuration(200);
animator.setInterpolator(new DecelerateInterpolator());
animator.start();
}
break;
}
return true;
}
III.あとがき
Androidの開発において重要なカスタムコントロールの開発は、各APIをいかにうまく活用して機能を実現するかという側面もあれば、トップダウンでいかに設計するかという側面もあります。開発において最も重要なことは、どのように実現するか、どのように設計するかを構想することではなく、ユーザーのニーズを発見し、逆にどのような機能を持たせるべきかというニーズから、機能的な観点から、どのようにクリエイティブな設計を行うかを検討し、最終的にユーザーに提示することです。そうすることで、より良い製品を作ることができるのです。
ギティのコントロール




