亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

利用Android中BitmapShader制作自帶邊框的圓形頭像

 更新時(shí)間:2016年09月12日 09:46:41   投稿:daisy  
這篇文章給大家介紹了一下如何利用BitmapShader制作圓形頭像,可以自定義要顯示的圖片,邊框顏色和邊框?qū)挾鹊?,有需要的朋友們可以參考借鑒。

效果如下:

BitmapShader 的簡單介紹

關(guān)于 Shader是什么,Shader的種類有哪幾種以及如何使用不屬于本文范疇,對(duì)這方面不是很了解的同學(xué),建議先去學(xué)習(xí)一下 Shader 的基本使用。

BitmapShader主要的作用就是 通過Paint對(duì)象,對(duì) 畫布進(jìn)行指定的Bitmap填充,實(shí)現(xiàn)一系列效果,可以有以下三種模式進(jìn)行選擇

      1.CLAMP - 拉伸,這里拉伸的是圖片的最后一個(gè)元素,不斷地重復(fù),這個(gè)效果,在圖片比較小,而所要畫的面積比較大的時(shí)候會(huì)比較明顯。

      2.REPEAT - 重復(fù),橫向縱向不斷地重復(fù),不同于上一模式,這種模式在圖片比較小不能滿足要求是,會(huì)在橫向縱向不斷重復(fù)繪制圖形。

      3.MIRROR - 翻轉(zhuǎn),這種模式和 REPEAT 是類似的,只不過這里的重復(fù)是翻轉(zhuǎn)著重復(fù),和折紙的效果差不多。

而我們將要使用的是 CLAMP 模式,因?yàn)橹灰覀儗?duì)圖形的大小進(jìn)行控制,就可以避免圖像進(jìn)行拉伸。

具體實(shí)現(xiàn)介紹

為了自定義 圖像,邊框?qū)挾群皖伾?,我們首先?res/values 目錄下,新建一個(gè) attrs.xml文件,里面要書寫的內(nèi)容如下所示

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <declare-styleable name="MyCustomView">
  <attr name="mborder_color" format="color"></attr>
  <attr name="mborder_width" format="dimension"></attr>
  <attr name="msrc" format="reference"></attr>
 </declare-styleable>
</resources>

當(dāng)然,在這里還可以添加一些其他的特性。既然定義了我們想要使用的特性,那么我們就要在自定義View里面 解析這些屬性并且加以利用,解析過程如下所示

 TypedArray type = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView);
 mBorderColor = type.getColor(R.styleable.MyCustomView_mborder_color,0);
 mDrawable = type.getDrawable(R.styleable.MyCustomView_msrc);

 //將獲得的 Drawable 轉(zhuǎn)換成 Bitmap
 BitmapDrawable bitmapDrawable = (BitmapDrawable) mDrawable;
 mBitmap = bitmapDrawable.getBitmap();

 mBorderWidth = type.getDimensionPixelSize(R.styleable.MyCustomView_mborder_width, 2);

值得注意的是 mSrc 屬性的解析,由于獲得是 Drawable 對(duì)象,所以我們需要將其轉(zhuǎn)換為 Bitmap 對(duì)象。

下面就利用我們獲得的 Bitmap 對(duì)象進(jìn)行圓形頭像的繪制,對(duì) BitmapShader Paint 的初始化如下所示

  mSrcBitmap = Bitmap.createScaledBitmap(mBitmap, mWidth, mHeight, false);
  mShader = new BitmapShader(mSrcBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
  mPaint = new Paint();
  mPaint.setShader(mShader);
  mRadius = (mWidth - mBorderWidth * 2 - 4) / 2;
  mCircleX = (mWidth) / 2;
  mCircleY = (mHeight) / 2;

mSrcBitmap是對(duì)獲得的圖像進(jìn)行適當(dāng)?shù)目s小或者放大,以適應(yīng)我們對(duì)圖形的要求,而這里的 mWidth mHeight 又是什么呢?實(shí)際上就是我們在 定義視圖在 layout_width layout_height中傳遞進(jìn)來的值,不過在這里我對(duì)他們進(jìn)行了處理,也就是選取最小值操作,這樣的話就可以避免由于寬大于高或者高大于寬而造成圖像填充不滿指定區(qū)域的現(xiàn)象。值得注意的是,自定義視圖,需要對(duì) wrap_content 進(jìn)行特殊處理,否則系統(tǒng)對(duì)該屬性的視圖不予以顯示。至于如何進(jìn)行處理,可以看看本例的源碼,很簡單,相信很多人一看就知道或者說早就了然于胸。

還有一點(diǎn)需要強(qiáng)調(diào)的是這里的 mRadius ,也就是將要繪制的圓的半徑,為什么要減去邊框的寬度 乘 2 呢? 要知道,我們的圓是根據(jù) 視圖指定的寬度或者高度來畫的,如果我們所畫 的圓恰好是指定視圖的內(nèi)切圓,那么邊框放在哪里呢?它肯定要被畫在視圖的外面,那樣我們就看不到完整的邊框了。所以,這么減去的意義在于為邊框騰出空間。

經(jīng)過以上操作,我們就已經(jīng)將圓形頭像繪制出來了,下面來繪制邊框,其實(shí)非常簡單,我只不過是又定義了一個(gè)  Paint 對(duì)象,并且利用它畫了一個(gè)圓而已,畫筆的初始化操作如下所示

  mBorderPaint = new Paint();
  mBorderPaint.setStyle(Paint.Style.STROKE);
  mBorderPaint.setStrokeWidth(mBorderWidth);
  mBorderPaint.setColor(mBorderColor);
  mBorderPaint.setStrokeCap(Paint.Cap.ROUND);

好了,下面就可以在onDraw()函數(shù)中,進(jìn)行繪制了,如下所示

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  canvas.drawCircle(mCircleX, mCircleY, mRadius, mPaint);
  canvas.drawCircle(mCircleX, mCircleY, mRadius, mBorderPaint);
 }

這樣,整個(gè)效果就算實(shí)現(xiàn)完畢了。下面來看看如何使用

 <com.example.hwaphon.patheffecttest.MyView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_marginBottom="16dp"
   android:layout_marginRight="8dp"
   app:mborder_color="@android:color/holo_green_light"
   app:mborder_width="4dp"
   app:msrc="@drawable/myview_test"/>

注意,一定要在容器中加上這么一句

具體實(shí)現(xiàn)的核心代碼

package com.example.hwaphon.patheffecttest;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by Hwaphon on 2016/5/12.
 */
public class MyView extends View {

 private Bitmap mBitmap;
 private Drawable mDrawable;
 private Bitmap mSrcBitmap;

 private BitmapShader mShader;
 private Paint mPaint;

 private int mWidth, mHeight;

 private int mRadius;
 private int mCircleX, mCircleY;

 private int mBorderColor;
 private Paint mBorderPaint;
 private int mBorderWidth;

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

 public MyView(Context context, AttributeSet attrs) {
  super(context, attrs);
  TypedArray type = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView);
  mBorderColor = type.getColor(R.styleable.MyCustomView_mborder_color,0);
  mDrawable = type.getDrawable(R.styleable.MyCustomView_msrc);

  //將獲得的 Drawable 轉(zhuǎn)換成 Bitmap
  BitmapDrawable bitmapDrawable = (BitmapDrawable) mDrawable;
  mBitmap = bitmapDrawable.getBitmap();

  mBorderWidth = type.getDimensionPixelSize(R.styleable.MyCustomView_mborder_width, 2);
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  mWidth = measureWidth(widthMeasureSpec);
  mHeight = measureHeight(heightMeasureSpec);
  int temp = mWidth > mHeight ? mHeight : mWidth;
  mWidth = mHeight = temp;
  initView();
  setMeasuredDimension(mWidth, mHeight);
 }

 private int measureHeight(int heightMeasureSpec) {
  int size = MeasureSpec.getSize(heightMeasureSpec);
  int sizeMode = MeasureSpec.getMode(heightMeasureSpec);
  int result = 0;
  if (sizeMode == MeasureSpec.EXACTLY) {
   result = size;
  } else {
   result = 200;
   if (sizeMode == MeasureSpec.AT_MOST) {
    result = Math.min(result, size);
   }
  }
  return result;
 }

 private int measureWidth(int widthMeasureSpec) {
  int size = MeasureSpec.getSize(widthMeasureSpec);
  int sizeMode = MeasureSpec.getMode(widthMeasureSpec);
  int result = 0;
  if (sizeMode == MeasureSpec.EXACTLY) {
   result = size;
  } else {
   result = 200;
   if (sizeMode == MeasureSpec.AT_MOST) {
    result = Math.min(result, size);
   }
  }
  return result;
 }

 private void initView() {

  mSrcBitmap = Bitmap.createScaledBitmap(mBitmap, mWidth, mHeight, false);
  mShader = new BitmapShader(mSrcBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
  mPaint = new Paint();
  mPaint.setShader(mShader);
  mRadius = (mWidth - mBorderWidth * 2) / 2;
  mCircleX = (mWidth) / 2;
  mCircleY = (mHeight) / 2;

  mBorderPaint = new Paint();
  mBorderPaint.setStyle(Paint.Style.STROKE);
  mBorderPaint.setStrokeWidth(mBorderWidth);
  mBorderPaint.setColor(mBorderColor);
  mBorderPaint.setStrokeJoin(Paint.Join.ROUND);
  mBorderPaint.setStrokeCap(Paint.Cap.ROUND);
 }

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  canvas.drawCircle(mCircleX, mCircleY, mRadius, mPaint);
  canvas.drawCircle(mCircleX, mCircleY, mRadius, mBorderPaint);
 }
}

總結(jié)

以上就是Android利用BitmapShader制作自帶邊框圓形頭像的全部內(nèi)容,希望這篇文章對(duì)大家開發(fā)Android的時(shí)候能有所幫助,如果有疑問大家可以留言交流。

相關(guān)文章

最新評(píng)論