自訂View之大風車系列demo(一),大風車demo

來源:互聯網
上載者:User

自訂View之大風車系列demo(一),大風車demo

每次寫部落格最討厭寫部落格的開頭,不知道該寫些什麼,現在也是,感覺跟寫八百字作文似的。之所以會寫這一系列的demo是因為前天看網上的一個圖片轉圈的源碼的時候

突發奇想要不要自己也弄個耍耍,順便學習下view的相關知識!說幹就幹,當然自己寫的時候也不免參照寫別人得到代碼,畢竟自訂view與我的水平來說確實具有挑戰性,通過完成這一些列的小demo確實收穫頗多,雖然還有些許在我看來更牛逼的功能自己沒法實現,但自己的目的也算達到了。先囉嗦了這麼多,先說說大風車系列小demo的總體概況:一共五個版本,這也意味著此系列一共會寫四到五個簡短的小部落格,每個版本都是對上一個版本的修改或者功能的改進。特註:這是個代碼很少的demo,不過對於初學者來說確實能學到點東西,所以拿來分享,如果有大神看到這些沒什麼水平的部落格希望能留下自己對android相關知識的些許評價或者批評。總之歡迎批評指正吧,閑言少敘,進入主題:

大風車版本1.0)實現功能和思慮如下:

1)風車圖片隨著手指的轉動而轉動,轉動的速度固定

2)圖片的轉動肯定設計到了androidview的重繪過程,所以postInvalidate和invalidate兩個方法準備起來。

3)既然圖片隨著手指的移動而轉動,那麼肯定會在onTouchEvent對MotionEvent.action_move事件進行補貨然後處理

4)所需要的風車圖片素材如下:

5)風車的圖片寬和高一樣,是個正方形的圖片,需要計算出來該方正行的中心,以此中心為旋轉軸進行旋轉。

通過上面五個說明得出自訂的View代碼如下:

package rotation.demo.view;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.Paint;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;/** * verson 1.0 * 隨手指轉動而轉動的風車 * 轉動的思路 * 1)風車轉動的涉及到了圖片的重繪過程 * 2)監聽手指的move事件,當move事件被監聽到的時候調用相關方法來進行重繪 * 3)用矩陣變換來實現風車的轉動 * @author xiaobenxiong * */public class RotationView extends View{/**要轉動的圖片**/private Bitmap bitMap;/**風車每次轉動的弧度**/private  int rad = 30;/**圖片的寬度:在這裡提供的是正方形的圖片,所以寬度和高度是一樣的**/private int width = 0;/***圖片的高度:在這裡提供的是正方形的圖片,所以寬度和高度是一樣的**/private int height = 0;/**定義一個畫筆**/private Paint paint = new Paint();public RotationView(Context context, AttributeSet attrs) {super(context, attrs);}public RotationView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public RotationView(Context context) {super(context);}/** * 擷取圖片的寬和高 */public void initSize() {  width = bitMap.getWidth();  height = bitMap.getHeight();  postInvalidate();}public void setBitMap(Bitmap bitMap) {this.bitMap = bitMap;}        //一圖片的寬和高來設定自訂View的寬和高,由於是正方形寬和高是一樣的@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubsuper.onMeasure(widthMeasureSpec, heightMeasureSpec);setMeasuredDimension(width, width);}          /***           *實現onDraw方法把風車圖片繪製出來,同時繪製出來風車的旋轉效果,通過Matrix來控制          */         @Override    protected void onDraw(Canvas canvas) {        Matrix matrix = new Matrix();        // 設定轉軸位置        matrix.setTranslate((float)width / 2, (float)height / 2);        rad -=3;//每次旋轉的弧度增量為3當然,數字越大轉動越快        // 開始轉        matrix.preRotate(rad);        // 轉軸還原        matrix.preTranslate(-(float)width / 2, -(float)height / 2);                //繪製風車圖片        canvas.drawBitmap(bitMap, matrix,paint);                super.onDraw(canvas);    }@Overridepublic boolean onTouchEvent(MotionEvent event) {int action = event.getAction();switch (action) {case MotionEvent.ACTION_MOVE://隨著手指的move而不斷進行重繪,進而讓風車轉動起來                        postInvalidate();//調用方法進行重繪break;}return true;}  }

上面的代碼很簡單,主要對MotionEvent.ACTION_MOVE事件進行捕獲,並調用postInvalidate方法來實現重繪,在onDraw方法中通過Martix的變化來實現風車的旋轉效果。在這裡要注意:

1)onTouchEvent要返回true否則不會進行執行你在這個方法裡面寫的程式,具體原因見android事件攔截機制

在設定檔裡面使用如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#ffffffff"    >    <rotation.demo.view.RotationView         android:id="@+id/rotationView"        android:layout_height="wrap_content"        android:layout_width="wrap_content"        android:layout_centerInParent="true">    </rotation.demo.view.RotationView ></RelativeLayout>

public class MainActivity extends Activity {    @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);RotationView rotation = (RotationView)findViewById(R.id.rotationView);BitmapDrawable drawable = (BitmapDrawable) getResources().getDrawable(R.drawable.fengche);rotation.setBitMap(drawable.getBitmap());rotation.initSize();}}

經過運行會發現有個問題:不論是手指是順時針還是逆時針風車運動的方向總是逆時針,經過測試發現當matrix.preRotate中的三處逐步變大的時候

就是順時針轉動,如果主鍵變小的話就是逆時針,所以我簡單的添加了個兩個按鈕來選擇是否是逆時針順時針,當逆時針的時候讓rad變數遞減,順時針遞增就可以了。為此在RotationView裡面增加了clockWise這個布爾變數,通過點擊兩個按鈕的變數改變clockWise的值。如下:

onDraw方法的代碼改動如下:

private boolean clockWise = false;@Overrideprotected void onDraw(Canvas canvas) {Matrix matrix = new Matrix();// 設定轉軸位置matrix.setTranslate((float) width / 2, (float) height / 2);if(clockWise) {//如果是順時針rad+= 30;}else { rad-= 30;}// 開始轉matrix.preRotate(degree);// 轉軸還原matrix.preTranslate(-(float) width / 2, -(float) height / 2);// 將位置送到view的中心// matrix.postTranslate((float)(width) / 2, (float)(height) / 2);canvas.drawBitmap(bitMap, matrix, paint);super.onDraw(canvas);}

經過簡單的修改,版本2就這麼誕生了,當然版本2.0還有些問題,留給版本3解決,詳見自訂View之大風車系列demo(2)


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.