android-順時逆時旋轉的儀表盤控制元件
阿新 • • 發佈:2019-01-26
在一次專案需求中,第一次接觸到了儀表盤,先來說下需求吧:定時獲取資料然後根據資料動態改變指標位置。今天我在這裡分享我自己寫的一個儀表盤控制元件,這裡我就不定時獲取,而是定時使用隨機數得到一個值。
先來看看效果截圖
我的佈局很簡單,就三個控制元件,一個錶盤,一個指標,一箇中間的文字。在佈局上為了方便,我使用了居於水平居中。這樣三個控制元件都會疊在一起,形成上面圖片的效果。
<?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下載