編輯:關於Android編程
最近一直在做即時通訊,當然少不了發圖片了, 既然要發圖片,我連忙打開qq,看看qq發圖片是個什麼效果,看起來確實不錯,我就照著qq仿寫了一個,其中選擇圖片時,圖片的右上角有一個標記選了多少張圖片的數字,我一時興起就想自定義一個view來實現這種效果,雖然可以通過定義一個selector然後定義shape給textView去設置這個背景來實現,後面會提及一下,但是這種效果我想通過自定義控件來實現,先看一張效果圖。

第一種方式:通過selector的方式:photo_selector.xml
tv = (TextView) findViewById(R.id.tv_point);
public void click1(View v) {
tv.setEnabled(true);
tv.setText("4");
}
public void click2(View v) {
tv.setEnabled(false);
tv.setText("");
}
然後是兩個按鈕,點擊一個讓其選中,還有一個讓其不選中,到這裡基本效果是實現了,當給設置監聽事件時,發現當按下就不能再按下了,如果我想點擊自身TextView也能實現選擇和不選,貌似這種方式就不好使了
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (tv.isEnabled()) {
tv.setEnabled(false);
}else {
tv.setEnabled(true);
}
}
});
第二種方式:自定義View
效果圖如下:

①自定義屬性:
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NumberSelectView);
mBackgroundColorNormal = typedArray.getColor(R.styleable.NumberSelectView_backgroundColorNormal, Color.parseColor("#33000000"));
mBackgroundColorSelect = typedArray.getColor(R.styleable.NumberSelectView_getBackgroundColorSelect, Color.parseColor("#ff5f62"));
mTextColor = typedArray.getColor(R.styleable.NumberSelectView_textColor, Color.parseColor("#FFFFFF"));
mStrokeColor = typedArray.getColor(R.styleable.NumberSelectView_strokeColor, Color.parseColor("#66FFFFFF"));
mStrokeWidth = typedArray.getDimension(R.styleable.NumberSelectView_strokeWidth, UIUtils.dp2px(context, 2.0f));
mSolidRadius = typedArray.getDimension(R.styleable.NumberSelectView_solidRadius, UIUtils.dp2px(context, 15.0f));
mTextSize = typedArray.getDimension(R.styleable.NumberSelectView_textSize, UIUtils.sp2px(context, 14.0f));
text = typedArray.getString(R.styleable.NumberSelectView_text);
typedArray.recycle();//回收很重要
attr.xml
②重新onMeasure方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int exceptWidth = (int) ((mSolidRadius + mStrokeWidth) * 2) + getPaddingLeft() + getPaddingRight();
int exceptHight = (int) ((mSolidRadius + mStrokeWidth) * 2) + getPaddingTop() + getPaddingBottom();
widthMeasureSpec = MeasureSpec.makeMeasureSpec(exceptWidth, MeasureSpec.EXACTLY);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(exceptHight,MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
③重寫onDraw方法
@Override
protected void onDraw(Canvas canvas) {
drawCircle(canvas);//畫實心圓
drawRing(canvas);//畫圓環
drawText(canvas);//畫文本
}
(1)drawCircle方法
private void drawCircle(Canvas canvas) {
if (!isSelected) {
canvas.drawCircle(mCenterX, mCenterY, mSolidRadius, mSolidPaint);
} else {
mSolidPaint.setColor(mBackgroundColorSelect);
canvas.drawCircle(mCenterX, mCenterY, mSolidRadius, mSolidPaint);
mSolidPaint.setColor(mBackgroundColorNormal);
}
}
(2)drawRing方法
private void drawRing(Canvas canvas) {
RectF rectF = new RectF();
rectF.top = mCenterY - mRingRadius;
rectF.bottom = mCenterY + mRingRadius;
rectF.left = mCenterX - mRingRadius;
rectF.right = mCenterX + mRingRadius;
canvas.drawArc(rectF, 0, 360, false, mStrokePaint);
}
(3)drawText方法
private void drawText(Canvas canvas) {
Rect bounds = new Rect();
mTextPaint.getTextBounds(text, 0, text.length(), bounds);
float x = (getMeasuredWidth() - bounds.width()) / 2;
float y = (getMeasuredHeight() + bounds.height()) /2;
if (isSelected) {
canvas.drawText(text, x, y, mTextPaint);
} else {
canvas.drawText("", x, y, mTextPaint);
}
}
初始化方法
/**
* 初始化操作
*/
private void init() {
if(TextUtils.isEmpty(text)){
text = "1";
}
mRingRadius = mSolidRadius + mStrokeWidth / 2;
setClickable(true);
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(listener != null){
listener.onClick(isSelected);
}
toggle();
}
});
mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mStrokePaint.setColor(mStrokeColor);
mStrokePaint.setStyle(Paint.Style.STROKE);
mStrokePaint.setStrokeWidth(mStrokeWidth);
mSolidPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mSolidPaint.setColor(mBackgroundColorNormal);
mSolidPaint.setStyle(Paint.Style.FILL);
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(mTextColor);
mTextPaint.setTextSize(mTextSize);
}
package com.cool.numberselectview;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/**
* Created by cool on 2016/9/27.
*/
public class NumberSelectView extends View {
private int mBackgroundColorNormal;
private int mBackgroundColorSelect;
private int mTextColor;
private int mStrokeColor;
private float mStrokeWidth;
private float mSolidRadius;//實心圓半徑
private float mRingRadius;//圓環半徑
private float mTextSize;
private int mCenterX;//圓心x坐標
private int mCenterY;//圓心y坐標
private Paint mStrokePaint;//圓環畫筆
private Paint mSolidPaint;//背景填充畫筆
private Paint mTextPaint;//文字畫筆
private String text;//要畫的數字
private boolean isSelected;//是否已經被選上
private OnOnStateChangeListener listener;
public void setOnStateChangeListener(OnOnStateChangeListener listener) {
this.listener = listener;
}
public interface OnOnStateChangeListener {
void onClick(boolean isSelected);
}
public NumberSelectView(Context context) {
this(context, null);
}
public NumberSelectView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public NumberSelectView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NumberSelectView);
mBackgroundColorNormal = typedArray.getColor(R.styleable.NumberSelectView_backgroundColorNormal, Color.parseColor("#33000000"));
mBackgroundColorSelect = typedArray.getColor(R.styleable.NumberSelectView_getBackgroundColorSelect, Color.parseColor("#ff5f62"));
mTextColor = typedArray.getColor(R.styleable.NumberSelectView_textColor, Color.parseColor("#FFFFFF"));
mStrokeColor = typedArray.getColor(R.styleable.NumberSelectView_strokeColor, Color.parseColor("#66FFFFFF"));
mStrokeWidth = typedArray.getDimension(R.styleable.NumberSelectView_strokeWidth, UIUtils.dp2px(context, 2.0f));
mSolidRadius = typedArray.getDimension(R.styleable.NumberSelectView_solidRadius, UIUtils.dp2px(context, 15.0f));
mTextSize = typedArray.getDimension(R.styleable.NumberSelectView_textSize, UIUtils.sp2px(context, 14.0f));
text = typedArray.getString(R.styleable.NumberSelectView_text);
typedArray.recycle();//回收很重要
init();
}
/**
* 初始化操作
*/
private void init() {
if(TextUtils.isEmpty(text)){
text = "1";
}
mRingRadius = mSolidRadius + mStrokeWidth / 2;
setClickable(true);
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(listener != null){
listener.onClick(isSelected);
}
toggle();
}
});
mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mStrokePaint.setColor(mStrokeColor);
mStrokePaint.setStyle(Paint.Style.STROKE);
mStrokePaint.setStrokeWidth(mStrokeWidth);
mSolidPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mSolidPaint.setColor(mBackgroundColorNormal);
mSolidPaint.setStyle(Paint.Style.FILL);
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(mTextColor);
mTextPaint.setTextSize(mTextSize);
}
@Override
protected void onDraw(Canvas canvas) {
drawCircle(canvas);//畫實心圓
drawRing(canvas);//畫圓環
drawText(canvas);//畫文本
}
private void drawText(Canvas canvas) {
Rect bounds = new Rect();
mTextPaint.getTextBounds(text, 0, text.length(), bounds);
float x = (getMeasuredWidth() - bounds.width()) / 2;
float y = (getMeasuredHeight() + bounds.height()) /2;
if (isSelected) {
canvas.drawText(text, x, y, mTextPaint);
} else {
canvas.drawText("", x, y, mTextPaint);
}
}
private void drawRing(Canvas canvas) {
RectF rectF = new RectF();
rectF.top = mCenterY - mRingRadius;
rectF.bottom = mCenterY + mRingRadius;
rectF.left = mCenterX - mRingRadius;
rectF.right = mCenterX + mRingRadius;
canvas.drawArc(rectF, 0, 360, false, mStrokePaint);
}
private void drawCircle(Canvas canvas) {
if (!isSelected) {
canvas.drawCircle(mCenterX, mCenterY, mSolidRadius, mSolidPaint);
} else {
mSolidPaint.setColor(mBackgroundColorSelect);
canvas.drawCircle(mCenterX, mCenterY, mSolidRadius, mSolidPaint);
mSolidPaint.setColor(mBackgroundColorNormal);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int exceptWidth = (int) ((mSolidRadius + mStrokeWidth) * 2) + getPaddingLeft() + getPaddingRight();
int exceptHight = (int) ((mSolidRadius + mStrokeWidth) * 2) + getPaddingTop() + getPaddingBottom();
widthMeasureSpec = MeasureSpec.makeMeasureSpec(exceptWidth, MeasureSpec.EXACTLY);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(exceptHight,MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCenterX = w / 2;//獲取圓心x坐標
mCenterY = h / 2;//獲取圓心y坐標
}
private void toggle() {
isSelected = !isSelected;
invalidate();
}
public void setViewText(String text,boolean isViewClick) {
this.text = text;
if(!isViewClick){
if (TextUtils.isEmpty(text)) {
isSelected = false;
} else {
isSelected = true;
}
}
invalidate();
}
public String getViewText(){
return text;
}
public boolean isViewSelected() {
return isSelected;
}
}
【Android UI】ListView的使用和簡單優化
ListView是每個app中都要使用的,所以今天我來總結下ListView的使用和一些簡單的優化。先看下運行效果:一、創建數據庫為了模擬數據,這裡將數據保存數據庫中,順
在Ubuntu上搭建Android開發環境(Android Studio)
五一放假,閒著沒事,裝了最新的ubutun16.04,然後打算順道把android開發環境移植到ubuntu上來體驗一下。 1.首先下載了Android stu
Android ViewPager使用方法
public class TvControlActivity extends Activity { private TvControlActivity tvCont
分別用ToolBar和自定義導航欄實現沉浸式狀態欄
一、ToolBar1、在build.gradle中添加依賴,例如:compile com.android.support:appcompat-v7:23.4.02、去掉應