完全自定義控件-自定義雷達掃描控件(學習Shader、Matrix)

自定義雷達掃描控件

效果展示

效果圖

涉及知識點

Shader類

在Android中,提供了Shader類專門用來渲染圖像以及一些幾何圖形。

  • 使用Shader類進行圖像渲染時,首先需要構建Shader對象,然后通過Paint的setShader()方法來設置渲染對象,最后將這個Paint對象繪制到屏幕上即可。
  • Shader類包括了5個直接子類
    • BitmapShader 圖像渲染
    • ComposeShader 混合渲染
    • LinearGradient 線性渲染
    • RadialGradient 環形渲染
    • SweepGradient 梯度渲染
      SweepGradient也稱為掃描渲染,是指在某一中心以x軸正方向逆時針旋轉一周而形成的掃描效果的渲染形式。
      //坐標(cx,cy)決定了中心點的位置,會繞著該中心點進行360度旋轉。color0表示的是起點的顏色位置,color1表示的是終點的顏色位置。
      public SweepGradient(float cx, float cy, int[] colors, float[] positions)
      public SweepGradient(float cx, float cy, int color0, int color1)
    </li> </ul>

    圖像渲染的詳細介紹

    Matrix類

    Matrix是一個矩陣,主要功能是坐標映射,數值轉換。

    • Matrix類有四種基本變換
      • 平移 setTranslate(); 平移意味著在x軸和y軸上簡單地移動圖像。
      • 縮放 setScale(); 它采用兩個浮點數作為參數,分別表示在每個軸上所產生的縮放量。
      • 旋轉 setRotate(); 它采用一個浮點數表示旋轉的角度。圍繞默認點(0,0),正數將順時針旋轉圖像,而負數將逆時針旋轉圖像,其中默認點是圖像的左上角。
      • 錯切 setSkew(); 對于錯切變換,在數學上又稱為Shear mapping(可譯為“剪切變換”)或者Transvection(縮并),它是一種比較特殊的線性變換。
      </li> </ul>

      Matrix原理

      實現思路

      1. 新建RadarView4類繼承View
      2. 重寫onDraw()方法,畫四個無鋸齒空心圓環,兩條直線
      3. 畫以最大圓為半徑的實心漸變圓
      4. 創建矩陣,旋轉畫布,重繪,并用Handler實現循環

      1. 初始化數據

      public RadarView4(Context context) {
              this(context, null);
          }

      public RadarView4(Context context, AttributeSet attrs) {
          this(context, attrs, 0);
      }
      
      public RadarView4(Context context, AttributeSet attrs, int defStyleAttr) {
          super(context, attrs, defStyleAttr);
      
          //為了避免在onDraw中重復創建對象,所以將一些初始化工作放入構造方法中來做
          init();
      
          //提交計劃任務馬上執行
          mHandler.post(run);
      }
      
      private void init() {
          //創建圓環畫筆
          mCirclePaint = new Paint();
          mCirclePaint.setColor(Color.GRAY);
          //設置畫筆的寬度
          mCirclePaint.setStrokeWidth(3);
          //設置抗鋸齒模式
          mCirclePaint.setAntiAlias(true);
          //設置畫筆風格
          mCirclePaint.setStyle(Paint.Style.STROKE);
      
          //創建掃描線畫筆
          mShaderPaint = new Paint();
          mShaderPaint.setAntiAlias(true);
          //設置畫筆風格為填充模式
          mShaderPaint.setStyle(Paint.Style.FILL);
      }</code></pre> 
      

      2. 開始繪制

      protected void onDraw(Canvas canvas) {
              super.onDraw(canvas);
              w = getMeasuredWidth();//獲取view的寬度
              h = getMeasuredHeight();//獲取view的高度
      
              //以中點為圓心
              canvas.drawCircle(w / 2, h / 2, w / 12, mCirclePaint);
              canvas.drawCircle(w / 2, h / 2, w / 6, mCirclePaint);
              canvas.drawCircle(w / 2, h / 2, w / 4, mCirclePaint);
              canvas.drawCircle(w / 2, h / 2, w / 3, mCirclePaint);
              //畫兩條直線
              canvas.drawLine(w / 2 - w / 3, h / 2, w / 2 + w / 3, h / 2, mCirclePaint);
              canvas.drawLine(w / 2, h / 2 - w / 3, w / 2, h / 2 + w / 3, mCirclePaint);
      
              //避免重復創建對象
              if (mShader == null)
                  //新建掃描渲染,掃描邊由透明->紅色進行漸變
                  mShader = new SweepGradient(w / 2, h / 2, Color.TRANSPARENT, getResources().getColor(R.color.RED));
      
              //設置渲染對象
              mShaderPaint.setShader(mShader);
              //指定畫布的當前矩陣
              canvas.concat(mMatrix);
              //畫一個掃描圖像
              canvas.drawCircle(w / 2, h / 2, w / 3, mShaderPaint);
          }

      3.通過Handler循環繪制實現轉動

      private Handler mHandler = new Handler();
      Runnable run = new Runnable() {
      
        @Override
         public void run() {
            start++;
            mMatrix = new Matrix();
            //為矩陣設置旋轉坐標
            mMatrix.setRotate(start, w / 2, h / 2);
            //刷新ui
            postInvalidate();
            //如果到了360度,則重新開始
            start = start == 360 ? 0 : start;
            //延遲執行
            postDelayed(this, 10);
          }
      };

      這里是 項目地址

      參考

      http://blog.csdn.net/itjianghuxiaoxiong/article/details/50207009

      http://www.jianshu.com/p/4918034e3f0e#

      http://blog.csdn.net/sahadev_/article/details/50432764

       

      來自:http://www.jianshu.com/p/954982ad3385

       

 本文由用戶 elply1988 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!