編輯:關於Android編程
圓角控件常用於頭像,按鈕,圖標等,用途十分廣泛,而且常常配合board使用。
在IOS中,UIVIew的CALayer層已經提供了圓角和board的方法,所以圓角控件的制作非常簡單,只需要類似以下簡單代碼即可實現:
view.layer.cornerRadius = 20; view.layer.borderColor = [UIColor yellowColor].CGColor; view.layer.borderWidth = 10; view.clipsToBounds = YES;
<com.me.obo.circleboardimage.circleview.roundimageview android:layout_width="80dp" android:layout_height="80dp" android:src="@drawable/head" attr:border_width="3dp" attr:corner_y="40dp" attr:corner_x="40dp" attr:border_color="#FFFFFF"></com.me.obo.circleboardimage.circleview.roundimageview>
下面就介紹如何實現這樣一個RoundImageView
在Android中,遮罩功能非常強大,可以用於生成兩張圖片相互截取的結果。
具體參數和遮罩的效果可以見鏈接: Android 實現遮罩
在RoundImageView中,遮罩用於清除控件外圈的內容,從而獲取到圓角的效果。這裡的思路是先獲取到控件本身所繪制的圖片,之後獲取圓角矩形遮罩圖片,然後兩個圖片采用DST_IN遮罩模式來截取中間的遮罩效果,即:
代碼實現如下:
// 獲取imageview原先的圖片 super.onDraw(mDestCanvas); // 創建矩形,表示圓角矩形 if (mRoundRectClip == null) { mRoundRectClip = new RectF(mBorderValue, mBorderValue, getWidth() - mBorderValue, getHeight() - mBorderValue); } // 繪制圓角矩形 mSrcCanvas.drawRoundRect(mRoundRectClip,mCornerXValue,mCornerYValue,mNomalPaint); // 使用遮罩畫筆扣除原圖中的圓角矩形外面的部分 mDestCanvas.drawBitmap(mSrcBitmap,0,0,mPaintClip);
在獲取到遮罩處理的圖片之後,為其添加board將會變得容易,也就是在外圈繪制出一個帶有寬度的圓即可。
代碼實現如下:
// 創建board的矩形 if (mRoundRectBorder == null) { mRoundRectBorder = new RectF(mBorderValue / 2, mBorderValue / 2, getWidth() - mBorderValue / 2, getHeight() - mBorderValue / 2); } // 繪制board mDestCanvas.drawRoundRect(mRoundRectBorder, mCornerXValue, mCornerYValue, mPaintBoard);
整個RoundImageView完整的代碼如下:
package com.me.obo.circleboardimage.circleview; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.RectF; import android.util.AttributeSet; import android.widget.ImageView; import com.me.obo.circleboardimage.R; /** * Created by obo on 16/5/11. * Email:[email protected] * Git:https://github.com/OboBear * Blog:http://blog.csdn.net/leilba */ public class RoundImageView extends ImageView { private float mCornerXValue ; private float mCornerYValue ; private float mBorderValue ; private int mBorderColor ; public RoundImageView(Context context, AttributeSet attrs) { super(context, attrs); // 獲取自定義參數 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView); // board顏色 mBorderColor = typedArray.getColor(R.styleable.RoundImageView_border_color,Color.argb(0,0,0,0)); // 獲取X方向曲率 mCornerXValue = typedArray.getDimension(R.styleable.RoundImageView_corner_x,0); // 獲取Y方向曲率 mCornerYValue = typedArray.getDimension(R.styleable.RoundImageView_corner_y,0); // board寬 mBorderValue = typedArray.getDimension(R.styleable.RoundImageView_border_width,0); // 用完需要recycle typedArray.recycle(); initPaints(); } private void initPaints() { // 創建普通畫筆 if (mNomalPaint == null) { mNomalPaint = new Paint(); } // 創建遮罩畫筆 if (mPaintClip == null) { mPaintClip = new Paint(); mPaintClip.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); mPaintClip.setAntiAlias(true); } // 創建board的畫筆 if (mPaintBoard == null) { mPaintBoard = new Paint(); mPaintBoard.setColor(mBorderColor); mPaintBoard.setStyle(Paint.Style.STROKE); mPaintBoard.setStrokeWidth(mBorderValue); } } Bitmap mDestBitmap; Bitmap mSrcBitmap; Canvas mDestCanvas; Canvas mSrcCanvas; Paint mPaintClip; Paint mNomalPaint; Paint mPaintBoard; RectF mRoundRectClip; RectF mRoundRectBorder; @Override protected void onDraw(Canvas canvas) { // 創建遮罩圖片和畫布 if (mDestBitmap == null) { mDestBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); mSrcBitmap = Bitmap.createBitmap(getWidth(),getHeight(), Bitmap.Config.ARGB_8888); mDestCanvas = new Canvas(mDestBitmap); mSrcCanvas = new Canvas(mSrcBitmap); } // 獲取imageview原先的圖片 super.onDraw(mDestCanvas); // 創建矩形,表示圓角矩形 if (mRoundRectClip == null) { mRoundRectClip = new RectF(mBorderValue, mBorderValue, getWidth() - mBorderValue, getHeight() - mBorderValue); } // 繪制圓角矩形 mSrcCanvas.drawRoundRect(mRoundRectClip,mCornerXValue,mCornerYValue,mNomalPaint); // 使用遮罩畫筆扣除原圖中的圓角矩形外面的部分 mDestCanvas.drawBitmap(mSrcBitmap,0,0,mPaintClip); // 創建board的矩形 if (mRoundRectBorder == null) { mRoundRectBorder = new RectF(mBorderValue / 2, mBorderValue / 2, getWidth() - mBorderValue / 2, getHeight() - mBorderValue / 2); } // 繪制board mDestCanvas.drawRoundRect(mRoundRectBorder, mCornerXValue, mCornerYValue, mPaintBoard); // 繪制最終的圓角帶有board的圖 canvas.drawBitmap(mDestBitmap,0,0,mNomalPaint); } }
可能有人要問,圓角彎曲度和board的參數是如何傳遞到RoundImageView裡的。實際上,這裡采用了自定義Attribute的方式,該操作需要到res/values 目錄下創建 attr.xml 文件,在裡面寫上自定義的參數名稱以及類型:
<resources> <declare-styleable name="RoundImageView"> <attr name="border_width" format="dimension"> <attr name="border_color" format="color"> <attr name="corner_x" format="dimension"> <attr name="corner_y" format="dimension"> </attr></attr></attr></attr></declare-styleable> </resources>
public RoundImageView(Context context, AttributeSet attrs) { super(context, attrs); // 獲取自定義參數 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView); // board顏色 mBorderColor = typedArray.getColor(R.styleable.RoundImageView_border_color,Color.argb(0,0,0,0)); // 獲取X方向曲率 mCornerXValue = typedArray.getDimension(R.styleable.RoundImageView_corner_x,0); // 獲取Y方向曲率 mCornerYValue = typedArray.getDimension(R.styleable.RoundImageView_corner_y,0); // board寬 mBorderValue = typedArray.getDimension(R.styleable.RoundImageView_border_width,0); // 用完需要recycle typedArray.recycle(); initPaints(); }
xmlns:attr="http://schemas.android.com/apk/res-auto"最後,在layout裡面調用RoundImageView的代碼非常簡潔:
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:attr="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/darker_gray" android:orientation="vertical"> <com.me.obo.circleboardimage.circleview.roundimageview android:layout_width="80dp" android:layout_height="80dp" android:src="@drawable/head" attr:border_width="3dp" attr:corner_y="40dp" attr:corner_x="40dp" attr:border_color="#FFFFFF"> <com.me.obo.circleboardimage.circleview.roundimageview android:layout_width="180dp" android:layout_height="180dp" android:src="@drawable/head" attr:border_width="2dp" attr:corner_y="40dp" attr:corner_x="40dp" attr:border_color="#FF0000" android:scaletype="fitXY"> </com.me.obo.circleboardimage.circleview.roundimageview></com.me.obo.circleboardimage.circleview.roundimageview></linearlayout>效果如下:
概述首先,應該了解的幾個問題:1)Android平台網絡相關API接口a) java.net.*(標准Java接口) java.net.*提供與聯網有關的類,包
Android平台api沒有特意為換膚提供一套簡便的機制,這可能是外國的軟件更注重功能和易用,不流行換膚。系統不提供直接支持,只能自行研究。 換膚,可以認為是動態替換資源
整個布局將觸發的方法如下:點擊TextView1 時,執行循環一次後。最後方法將不再向下傳遞。直接交個 Activity執行04-28 16:22:09.509: I/S
在上一篇教程中,主要介紹了如何把OSG源代碼編譯成為能夠在Android項目下使用的函數庫。在這一篇教程中,我將針對如何在自己的Android項目中配置OSG函數庫進行詳