AnalogClockを作ってみる。
この間の続きで、今度はアナログ時計を作ってみた。
AnalogClockView.javaを作る
package com.example.analogclock; import java.util.Calendar; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.view.View; public class AnalogClockView extends View { private int centerX = 0; private int centerY = 0; private int handLength = 0; private HandPoint sec; private HandPoint min; private HandPoint hour; public AnalogClockView(Context context) { super(context); sec = new HandPoint(centerX, centerY); min = new HandPoint(centerX, centerY); hour = new HandPoint(centerX, centerY); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); getTodayNow(); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.WHITE); canvas.drawLine(centerX, centerY, sec.X(), sec.Y(), paint); paint.setColor(Color.BLUE); canvas.drawLine(centerX, centerY, min.X(), min.Y(), paint); paint.setColor(Color.RED); canvas.drawLine(centerX, centerY, hour.X(), hour.Y(), paint); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); centerX = w / 2; centerY = h / 2; handLength = Math.min(centerX, centerY); } private void getTodayNow(){ Calendar cal = Calendar.getInstance(); double ss = (double)cal.getTime().getSeconds(); double mm = (double)cal.getTime().getMinutes(); double hh = (double)cal.getTime().getHours(); double secAng = 2.0 * Math.PI * ss / 60.0; double minAng = 2.0 * Math.PI * (mm + ss/60.0)/60.0; double hourAng = 2.0 * Math.PI * (hh+mm/60.0)/12.0; sec.setPoint((int)(centerX+Math.sin(secAng)*handLength*0.7), (int)(centerY-Math.cos(secAng)*handLength*0.7)); min.setPoint((int)(centerX+Math.sin(minAng)*handLength*0.9), (int)(centerY-Math.cos(minAng)*handLength*0.9)); hour.setPoint((int)(centerX+Math.sin(hourAng)*handLength*0.5), (int)(centerY-Math.cos(hourAng)*handLength*0.5)); } }
座標位置を保存するだけのクラスも作った(C#でいうプロパティみたいなので書けないのか?Javaは)。
package com.example.analogclock; public class HandPoint { private int posx; private int posy; public int X() { return posx; } public int Y() { return posy; } public void setPoint(int _x, int _y) { posx = _x; posy = _y; } public HandPoint(int _x, int _y) { posx = _x; posy = _y; } }
で、これをAnalogClockのActivityから、定期実行で呼ぶ。
package com.example.analogclock; import android.app.Activity; import android.os.Bundle; import android.os.Handler; public class AnalogClock extends Activity { private Handler handler = new Handler(); private Runnable runnable; private static long CLOCK_INTERVAL=1000; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final AnalogClockView view = new AnalogClockView(getApplication()); setContentView(view); runnable = new Runnable(){ @Override public void run(){ view.invalidate(); handler.postDelayed(this, CLOCK_INTERVAL); } }; handler.postDelayed(runnable, CLOCK_INTERVAL); } }
view.invalidate();が味噌だな。view.onDraw();とかしちゃいけない。
ダサいけど、とりあえず動く。
時計を動かしたいだけなら
実は、SDKのコンポーネントの中に時計のコンポーネントもあるので、ただ時計を画面上で動かしたいだけなら、実はこんなことをしなくても良い。
ただ、res/layout/main.xmlを記述するだけ。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <AnalogClock android:id="@+id/AnalogClock01" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <DigitalClock android:text="@+id/DigitalClock01" android:id="@+id/DigitalClock01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="48sp"/> </LinearLayout>