目的
佈局文件
<span style="white-space:pre"> </span><com.android.mms.ui.TctUnReadIcon
android:id="@+id/unread_icon"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:visibility="gone"
/>
自定義控件的實現類
<pre name="code" class="java">public class TctUnReadIcon extends View {
private String mUnReadCount = "";
private Paint mTextPaint;
private Paint mCirclePaint;
private Rect mRectBound;
private int mScreenWidth;
private int mScreenHeight;
public TctUnReadIcon(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
//通過MessageUtils這個類我們可以得到手機屏幕的大小 ,這裏的480,800指的是開發時手機的屏幕分辨率,
//因爲通過paint.setTextSize()設置字體大小的時候,用的是px,而我們一般設置字體的時候用sp,dp ,這個在下面會講到
mScreenWidth = MessageUtils.getScreenWidth();
mScreenHeight = MessageUtils.getScreenHeight();
float ratioWidth = (float)mScreenWidth / 480;
float ratioHeight = (float)mScreenHeight / 800;
float RATIO = Math.min(ratioWidth, ratioHeight);
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTextSize((int)(15 * RATIO)); //這裏經過實際的調試實現的是15dp
mTextPaint.setColor(Color.WHITE);
mTextPaint.setStyle(Paint.Style.FILL);
mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCirclePaint.setColor(Color.RED);
mCirclePaint.setStyle(Paint.Style.FILL);
mRectBound = new Rect();
Log.d("yyyyy", " iconSize = " + ((int)(15 * RATIO)));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
Log.d("yyyyy", "width = " + getWidth() + " ,height = " + getHeight());
int circleRadius = Math.min(width, height) / 2;
//繪製圓
canvas.drawCircle(width / 2, height / 2, circleRadius , mCirclePaint);
//在圓上繪製數字
mTextPaint.getTextBounds(mUnReadCount, 0, mUnReadCount.length(),mRectBound);
canvas.drawText(mUnReadCount, width / 2 - mRectBound.width() / 2 - 1,
height / 2 + mRectBound.height() / 2, mTextPaint);
Log.d("yyyyy", "drawText width = " + (width / 2 - mRectBound.width() / 2) + " ," +
"height = " + (height / 2 + mRectBound.height() / 2) );
}
//設置中間顯示的數字
public void setmUnReadCount(String mUnReadCount) {
this.mUnReadCount = mUnReadCount;
mTextPaint.getTextBounds(mUnReadCount, 0, mUnReadCount.length(),mRectBound);
invalidate();
}
}
在上面用到了一個MessageUtil.java類,在這個類裏面,得到屏幕信息的操作,這樣增強了屏幕的適配性
public class MessageUtils {
private static int mScreenWidth;
private static int mScreenHeight;
public static void setScreenWidth(int screenWidth){
mScreenWidth = screenWidth ;
}
public static void setScreenHeight(int screenHeight){
mScreenHeight = screenHeight;
}
public static int getScreenWidth(){
return mScreenWidth;
}
public static int getScreenHeight(){
return mScreenHeight;
}
}
DisplayMetrics displayMetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int screenWidth = displayMetrics.widthPixels;
int screenHeight = displayMetrics.heightPixels;
MessageUtils.setScreenWidth(screenWidth);
MessageUtils.setScreenHeight(screenHeight);
然後,在這個控件顯示的頁面調用setmUnReadCount()方法,不然控件裏面的數字會顯示爲空
附錄學習資料
android中dip、dp、px、sp和屏幕密度
這裏要特別注意dip與屏幕密度有關,而屏幕密度又與具體的硬件有關,硬件設置不正確,有可能導致dip不能正常顯示。在屏幕密度爲160的顯示屏上,1dip=1px,有時候可能你的屏幕分辨率很大如480*800,但是屏幕密度沒有正確設置比如說還是160,那麼這個時候凡是使用dip的都會顯示異常,基本都是顯示過小。
dip的換算:
dip(value)=(int) (px(value)/1.5 + 0.5)
2. dp: 很簡單,和dip是一樣的。
3. px: pixels(像素),不同的設備不同的顯示屏顯示效果是相同的,這是絕對像素,是多少就永遠是多少不會改變。
4. sp: scaled pixels(放大像素). 主要用於字體顯示best for textsize。
5. dpi(dot per inch):屏幕每英寸打印點數,每英寸多少打印點,打印的時候對像素密度的表達
6. ppi(dot per pixels):屏幕上每英寸上的像素點數
7. density:density表示每英寸有多少個顯示點(邏輯值),它的單位是ppi
public static int dip2px(Context context, float dipValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(dipValue * scale + 0.5f);
}
public static int px2dip(Context context, float pxValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(pxValue / scale + 0.5f);
}