Android 自定義星評空間示例代碼
沒事做用自定義view方式寫一個星評控件,雖說網(wǎng)上很多這個控件,但是這是自己寫的,在這里記錄一下。
首先需要自定義屬性
<declare-styleable name="Rate">
<!--屬性分別是:單個的寬,高,之間的距離,激活的數(shù)量,總數(shù)量,激活的drawable,沒有激活的drawable,是否可以選擇數(shù)量-->
<attr name="custom_rate_width" format="dimension"/>
<attr name="custom_rate_height" format="dimension"/>
<attr name="custom_rate_padding" format="dimension"/>
<attr name="custom_rate_active_size" format="integer"/>
<attr name="custom_rate_size" format="integer"/>
<attr name="custom_rate_active_drawable" format="reference"/>
<attr name="custom_rate_disactive_drawable" format="reference"/>
<attr name="custom_rate_touch" format="boolean"/>
</declare-styleable>
初始化代碼
protected void init(Context context, AttributeSet attrs) {
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.Rate);
int activeId = 0;
int disactiveId = 0;
if (array != null) {
size = array.getInt(R.styleable.Rate_custom_rate_size, 5);
activeSize = array.getInt(R.styleable.Rate_custom_rate_active_size, 3);
rateWidth = array.getDimensionPixelOffset(R.styleable.Rate_custom_rate_width, 0);
rateHeight = array.getDimensionPixelOffset(R.styleable.Rate_custom_rate_height, 0);
activeId = array.getResourceId(R.styleable.Rate_custom_rate_active_drawable, 0);
disactiveId = array.getResourceId(R.styleable.Rate_custom_rate_disactive_drawable, 0);
padding = array.getDimensionPixelOffset(R.styleable.Rate_custom_rate_padding, 0);
isTouch = array.getBoolean(R.styleable.Rate_custom_rate_touch, false);
array.recycle();
}
//如果沒有寬高就設(shè)置一個默認(rèn)值
if (rateHeight <= 0){
rateHeight = 80;
}
if (rateWidth <= 0){
rateWidth = 80;
}
if (activeId!=0){
activeBitmap = BitmapFactory.decodeResource(getResources(), activeId);
//如果沒有設(shè)置寬高時候
if (rateWidth <= 0) {
rateWidth = activeBitmap.getWidth();
}
//把圖片壓縮到設(shè)置的寬高
activeBitmap = Bitmap.createScaledBitmap(activeBitmap, (int) rateWidth, (int) rateHeight, false);
}
if (disactiveId != 0){
disactiveBitmap = BitmapFactory.decodeResource(getResources(), disactiveId);
if (rateHeight <= 0) {
rateHeight = activeBitmap.getHeight();
}
disactiveBitmap = Bitmap.createScaledBitmap(disactiveBitmap, (int) rateWidth, (int) rateHeight, false);
}
mPaint = new Paint();//初始化bitmap的畫筆
mPaint.setAntiAlias(true);
activPaint = new Paint();//初始化選中星星的畫筆
activPaint.setAntiAlias(true);
activPaint.setColor(Color.YELLOW);
disactivPaint = new Paint();//初始化未選中星星的畫筆
disactivPaint.setAntiAlias(true);
disactivPaint.setColor(Color.GRAY);
}
onMeasure方法設(shè)置View的寬高,如果設(shè)置的每一個星星控件的寬高大于實際view的寬高,就用星星空間的寬高作于view的寬高
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
//計算寬
if (widthMode == MeasureSpec.EXACTLY) {
//如果view的寬度小于設(shè)置size*星星的寬度,就用size * (int) (padding + rateWidth)做為控件的寬度度
if (widthSize < size * (int) (padding + rateWidth)) {
width = size * (int) (padding + rateWidth);
} else {
width = widthSize;
}
} else {
width = size * (int) (padding + rateWidth)-padding;
}
//計算高
if (heightMode == MeasureSpec.EXACTLY) {
//如果view的高度小于設(shè)置星星的高度,就用星星高度做為控件的高度
if (heightSize < rateHeight) {
height = (int) rateHeight + 5;
} else {
height = heightSize;
}
} else {
height = (int) rateHeight + 5;
}
setMeasuredDimension(width, height);
}
onDraw方法中繪制
//開始畫active
for (int i = 0; i < activeSize; i++) {
if (activeBitmap != null){
if (i == 0) {
canvas.drawBitmap(activeBitmap, rateWidth * i, (height - rateHeight) / 2, mPaint);
} else {
canvas.drawBitmap(activeBitmap, (rateWidth + padding) * i, (height - rateHeight) / 2, mPaint);
}
}else {
drawActivRate(i,canvas);
}
}
// //開始畫disactive
for (int i = activeSize; i < size; i++) {
if (disactiveBitmap != null){
if (i == 0) {
canvas.drawBitmap(disactiveBitmap, rateWidth * i, (height - rateHeight) / 2, mPaint);
} else {
canvas.drawBitmap(disactiveBitmap, (rateWidth + padding) * i, (height - rateHeight) / 2, mPaint);
}
}else {
drawDisActivRate(i,canvas);
}
}
上面用到兩個方法drawActivRate和drawDisActivRate,分別是在沒有設(shè)置活動中的星星和不在活動中星星的圖片的時候,繪制在活動和不在活動的默認(rèn)星星:
/**
* 繪制黃色的五角星(在活動的)
* */
private void drawActivRate(int position,Canvas canvas){
float radius = rateWidth/2;//根據(jù)每一個星星的位置繪製園,確定五角星五個點(diǎn)的位置
float angle = 360/5;
float centerX = (rateWidth+padding)*(position+1)-padding-radius;//獲取每一個星星空間的中心位置的X坐標(biāo)
float centerY =height/2;//獲取每一個星星空間的中心位置的y坐標(biāo)
Path mPath = new Path();
mPath.moveTo(centerX,centerY-radius);
mPath.lineTo(centerX+(float) Math.cos((angle*2-90)*Math.PI / 180)*radius,centerY+(float)Math.sin((angle*2-90)*Math.PI / 180)*radius);
mPath.lineTo( centerX-(float)Math.sin(angle*Math.PI / 180)*radius,centerY-(float)Math.cos(angle*Math.PI / 180)*radius);
mPath.lineTo( centerX+(float)Math.sin(angle*Math.PI / 180)*radius,centerY-(float)Math.cos(angle*Math.PI / 180)*radius);
mPath.lineTo( centerX-(float)Math.sin((angle*3-180)*Math.PI / 180)*radius,centerY+(float)Math.cos((angle*3-180)*Math.PI / 180)*radius);
// mPath.lineTo(centerX,centerY-radius);
mPath.close();
canvas.drawPath(mPath,activPaint);
}
/**
* 繪制灰色的五角星
* */
private void drawDisActivRate(int position,Canvas canvas){
float radius = rateWidth/2;
float angle = 360/5;
float centerX = (rateWidth+padding)*(position+1)-padding-radius;
float centerY =height/2;
Path mPath = new Path();
mPath.moveTo(centerX,centerY-radius);
mPath.lineTo(centerX+(float) Math.cos((angle*2-90)*Math.PI / 180)*radius,centerY+(float)Math.sin((angle*2-90)*Math.PI / 180)*radius);
mPath.lineTo( centerX-(float)Math.sin(angle*Math.PI / 180)*radius,centerY-(float)Math.cos(angle*Math.PI / 180)*radius);
mPath.lineTo( centerX+(float)Math.sin(angle*Math.PI / 180)*radius,centerY-(float)Math.cos(angle*Math.PI / 180)*radius);
mPath.lineTo( centerX-(float)Math.sin((angle*3-180)*Math.PI / 180)*radius,centerY+(float)Math.cos((angle*3-180)*Math.PI / 180)*radius);
// mPath.lineTo(centerX,centerY-radius);
mPath.close();
canvas.drawPath(mPath,disactivPaint);
}
最后在onTouchEvent方法中處理選中和未選中星星的處理
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isTouch){//如果不支持觸摸
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchX = event.getX();
touchY = event.getY();
for (int i = 0; i < size; i++) {
if (i == 0) {
if (0.0 < touchX && touchX < rateWidth+padding/2) {
activeSize = 1;
}
}else {
if ((rateWidth+padding)*i-padding/2<touchX&&touchX<(rateWidth+padding)*(i+1)-padding/2){
activeSize = i+1;
}
}
}
invalidate();
break;
case MotionEvent.ACTION_UP:
if ( null!= changeListener){
changeListener.change(activeSize);
}
break;
case MotionEvent.ACTION_MOVE:
touchX = event.getX();
touchY = event.getY();
for (int i = 0; i < size; i++) {
if (i == 0) {
if (0.0 < touchX && touchX < rateWidth+padding/2) {
activeSize = 1;
}
}else {
if ((rateWidth+padding)*i-padding/2<touchX&&touchX<(rateWidth+padding)*(i+1)-padding/2){
activeSize = i+1;
}
}
}
invalidate();
if (touchX<=0){
activeSize = 0;
}
break;
}
return true;
}
以上就是自定義view寫的星評控件,代碼中的注解已經(jīng)比較詳細(xì)了,就不多說了,
源碼地址
以上所述是小編給大家介紹的android自定義星評空間的實例代碼,希望對大家有所幫助!
相關(guān)文章
android尺子的自定義view——RulerView詳解
這篇文章主要介紹了android尺子的自定義view——RulerView詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03
Android中WebView圖片實現(xiàn)自適應(yīng)的方法
這篇文章主要介紹了Android中WebView圖片實現(xiàn)自適應(yīng)的方法,涉及Android操作圖片顯示的相關(guān)技巧,需要的朋友可以參考下2015-05-05
Android OpenGL ES實現(xiàn)簡單綠幕摳圖
這篇文章主要為大家介紹了Android OpenGL ES實現(xiàn)簡單綠幕摳圖示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
Android Studio連接手機(jī)設(shè)備教程
這篇文章主要為大家詳細(xì)介紹了Android Studio連接手機(jī)設(shè)備教程,非常完整的連接步驟,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-07-07

