1. 程式人生 > >android-順時逆時旋轉的儀表盤控制元件

android-順時逆時旋轉的儀表盤控制元件

在一次專案需求中,第一次接觸到了儀表盤,先來說下需求吧:定時獲取資料然後根據資料動態改變指標位置。今天我在這裡分享我自己寫的一個儀表盤控制元件,這裡我就不定時獲取,而是定時使用隨機數得到一個值。

先來看看效果截圖

demo

我的佈局很簡單,就三個控制元件,一個錶盤,一個指標,一箇中間的文字。在佈局上為了方便,我使用了居於水平居中。這樣三個控制元件都會疊在一起,形成上面圖片的效果。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <ImageView
        android:id="@+id/panelimage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:src="@drawable/temperature_bg" />

    <ImageView
        android:id="@+id/needle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:src="@drawable/pointer" />

    <TextView
        android:id="@+id/degreeID"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="85dp"
        android:background="@drawable/small_semicircle"
        android:textSize="30sp"
        android:gravity="center" />

</RelativeLayout>

佈局看完了,最重要是實現,從網路上獲取回來值,再把這個值顯示在TextView中,並且對指標經行控制,通過動畫實現旋轉過程。這裡我用Random()方法來設定這個值。

在初始化時new一個timer,每1秒觸發一次,傳送訊息到handler觸發隨機函式產生隨機數

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.tmptest);

		// 指標
		needleView = (ImageView) findViewById(R.id.needle);
		// 錶盤讀數
		showText = (TextView) findViewById(R.id.degreeID);

		// 定時器,1秒啟動一次
		Timer timer = new Timer();
		timer.schedule(mTimerTask, 0, 1000);

	}

	// TimerTask
        private TimerTask mTimerTask = new TimerTask() {

		public void run() {
			Message message1 = new Message();
			message1.what = 1;
			thandler.sendMessage(message1);
		}

	};

	private Handler thandler = new Handler() {

		public void handleMessage(Message msg1) {

			// 產生隨機數0-40
			Random random = new Random();
			int a = -20 + random.nextInt(61);

			// 設定最高值
			maxDegree = Float.parseFloat(String.valueOf(a + 20));
			// 開始轉動
			mTimer = new Timer();
			// 設定每10毫秒轉動一下
			mTimer.schedule(new NeedleTask(), 0, 10);
			showText.setText(String.valueOf(a));
			flag = true;
		}

	};

thandler裡我們再new了一個timer來對指標進行控制,通過animation動畫來實現指標的跳轉

	private class NeedleTask extends TimerTask {
		@Override
		public void run() {
			if (degree <= maxDegree * (3.0f)) {
				mHandler.sendEmptyMessage(0);
			}
			if (degree >= maxDegree * (3.0f) && flag == true) {
				mHandler2.sendEmptyMessage(0);
			}
		}
	}

	// 順時
	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			// 設定儀表盤指標轉動動畫
			// 儀表盤最大是180度

			if (degree >= maxDegree * (3.0f)) {
				mTimer.cancel();
			} else {
				degree += 5.0f;
				// 設定轉動動畫
				animation = new RotateAnimation(degree, maxDegree * (3.0f),
						Animation.RELATIVE_TO_SELF, 0.5f,
						Animation.RELATIVE_TO_SELF, 0.5f);
			}

			// 設定動畫時間5毫秒
			animation.setDuration(5);
			animation.setFillAfter(true);
			needleView.startAnimation(animation);
			flag = false;

		}
	};

	// 逆時
	private Handler mHandler2 = new Handler() {
		@Override
		public void handleMessage(Message msg) { // 設定儀表盤指標轉動動畫
			// 儀表盤最大是180度,這個是自己測出來的
			if (degree <= maxDegree * (3.0f)) {
				mTimer.cancel();
			} else {
				degree += -5.0f;
				animation = new RotateAnimation(degree, maxDegree * (3.0f),
						Animation.RELATIVE_TO_SELF, 0.5f,
						Animation.RELATIVE_TO_SELF, 0.5f);
			}
			// 設定動畫時間5毫秒
			animation.setDuration(5);
			animation.setFillAfter(true);
			needleView.startAnimation(animation);
			flag = true;
		}
	};

大致思路就是這樣,不過這裡還有問題,在某些情況下會出現指標卡住沒有跳轉的情況,懶得完善。
demo下載