自定义会员等级控件

来源:互联网 发布:数据库简单案例 编辑:程序博客网 时间:2024/04/29 19:06

最近需要做一个类似于淘宝平台会员等级的动态效果 度娘并没有给出想要的东西,于是乎,自己动手做了一个

先上效果图

这里写图片描述
先谈谈主要的思路
1.先把需要的图标画在屏幕的指定位置,当然,这个需要自己去计算和调节

2.让他动起来并且不会有卡顿的感觉 这个问题很简单,在Activity中new 一个线程 每隔40ms时间发送一个Message,message里面包含需要移动距离,并且调用View的postInvalidate()方法,重新绘制View,在Handler里面判断控件的位置,在指定范围内去改变控件的位置即可!

3.至于颜色的更换 我的做法是在底层防止有颜色的背景图,上面放置同样大小的灰色图片,不停去改变灰色图片的位置即可。

好,接下来上代码
当然 图片文件需要各位自己去添加 并且我在这里有去计算屏幕的像素密度。后面贴出来

下面是控件的代码 继承View 所有代码都是在 onDraw方法中 当然,你也可以把计算的部分放在onMeasure方法里面

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import com.azt.common.utils.CommonUtil;

public class MyLevelView extends View {

private Context context;//总长度 ,各个等级的对应长度,当前位置private int totalLength, levelLength, currentLength;//private int totalLevel = 5, cunrrentLevel;public final static int LEVEL0 = 208, LEVEL1 = 552, LEVEL2 = 828, LEVEL3 = 1104, LEVEL4 = 1380, LEVEL5 = 1656;private float level0, level1, level2, level3, level4, level5;//等级图标位置private float gradeY;//文字位置private float textY = 0;//头像照片位置private float headY = 0;//等级图标位置private float gradeX;private final static String STR_LEVEL0 = "0", STR_LEVEL1 = "300", STR_LEVEL2 = "1300", STR_LEVEL3 = "3300", STR_LEVEL4 = "8300", STR_LEVEL5 = "18300";public int level = 0;private Bitmap headImage;private float denistyX, denistyY;private Paint paint = new Paint();public MyLevelView(Context context) {    this(context, null);}public MyLevelView(Context context, AttributeSet attrs) {    this(context, attrs, 0);}public MyLevelView(Context context, AttributeSet attrs, int defStyleAttr) {    super(context, attrs, defStyleAttr);    this.context = context;    denistyX = CommonUtil.getAdapterRatio((Activity) context)[0];    denistyY = CommonUtil.getAdapterRatio((Activity) context)[1];    level0 =  (LEVEL0 * denistyX);    level1 =  (LEVEL1 * denistyX);    level2 =  (LEVEL2 * denistyX);    level3 =  (LEVEL3 * denistyX);    level4 =  (LEVEL4 * denistyX);    level5 =  (LEVEL5 * denistyX);    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade0_ash);    gradeY = 140 * denistyY - bitmap.getHeight() / 2;    textY = 140*denistyY + bitmap.getHeight()/2 + 25 * denistyY;    gradeX = bitmap.getWidth() / 2;    bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.circular_pink);    headY = 140*denistyY - bitmap.getHeight()/2;   // HJToast.showDebugShort("   denisty -->> " + denistyX + "   " + denistyY+"  "+textY+"  "+headY);    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyLevelView, 0, 0);    totalLength = (int) (a.getInteger(R.styleable.MyLevelView_total_length, 1930) * denistyY);    levelLength = (int) (a.getInteger(R.styleable.MyLevelView_level_length, 0) * denistyY);    a.recycle();}public void setLevelLength(int levelLength) {    this.levelLength = levelLength;}public void setCurrentLength(int cunrrentLevel) {    this.currentLength = cunrrentLevel;}public void setTotalLength(int totalLength) {    this.totalLevel = totalLength;}public void setHeadImage(Bitmap bitmap) {    this.headImage = bitmap;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    super.onMeasure(widthMeasureSpec, heightMeasureSpec);}@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.level_bg_color);    canvas.drawBitmap(CommonUtil.zoomImg(bitmap, (int) (1930 * denistyX), (int) (20 * denistyY)), 0, 130 * denistyY, paint);    bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.level_bg);    canvas.drawBitmap(CommonUtil.zoomImg(bitmap, (int) (1930 * denistyX), (int) (20 * denistyY)), currentLength * denistyX, 130 * denistyY, paint);    if (currentLength < LEVEL0) {        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade0_ash);        canvas.drawBitmap(bitmap, level0, gradeY, paint);        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade1_ash);        canvas.drawBitmap(bitmap, level1, gradeY, paint);        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade2_ash);        canvas.drawBitmap(bitmap, level2, gradeY, paint);        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade3_ash);        canvas.drawBitmap(bitmap, level3, gradeY, paint);        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade4_ash);        canvas.drawBitmap(bitmap, level4, gradeY, paint);        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade5_ash);        canvas.drawBitmap(bitmap, level5, gradeY, paint);    } else {        if (currentLength >= LEVEL0) {            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade0_tail);        } else {            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade0_ash);        }        canvas.drawBitmap(bitmap, level0, gradeY, paint);        if (currentLength >= LEVEL1) {            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade1_tail);        } else {            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade1_ash);        }        canvas.drawBitmap(bitmap, level1, gradeY, paint);        if (currentLength >= LEVEL2) {            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade2_tail);        } else {            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade2_ash);        }        canvas.drawBitmap(bitmap, level2, gradeY, paint);        if (currentLength >= LEVEL3) {            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade3_tail);        } else {            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade3_ash);        }        canvas.drawBitmap(bitmap, level3, gradeY, paint);        if (currentLength >= LEVEL4) {            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade4_tail);        } else {            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade4_ash);        }        canvas.drawBitmap(bitmap, level4, gradeY, paint);        if (currentLength >= LEVEL5) {            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade5_tail);        } else {            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade5_ash);        }        canvas.drawBitmap(bitmap, level5, gradeY, paint);    }    paint.setColor(getResources().getColor(R.color.text_color));    paint.setTextSize(24*denistyX);    canvas.drawText(STR_LEVEL0, level0 + gradeX - paint.measureText(STR_LEVEL0)/2, textY, paint);    canvas.drawText(STR_LEVEL1, level1 + gradeX - paint.measureText(STR_LEVEL1)/2, textY, paint);    canvas.drawText(STR_LEVEL2, level2 + gradeX - paint.measureText(STR_LEVEL2)/2, textY, paint);    canvas.drawText(STR_LEVEL3, level3 + gradeX - paint.measureText(STR_LEVEL3)/2, textY, paint);    canvas.drawText(STR_LEVEL4, level4 + gradeX - paint.measureText(STR_LEVEL4)/2, textY, paint);    canvas.drawText(STR_LEVEL5, level5 + gradeX - paint.measureText(STR_LEVEL5)/2, textY, paint);    if (levelLength>=LEVEL0 && levelLength < LEVEL1){        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.circular_brown);        level = LEVEL0;    } else if (levelLength >= LEVEL1 && levelLength < LEVEL2) {        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.circular_coppery);        level = LEVEL1;    } else if (levelLength >= LEVEL2 && levelLength < LEVEL3) {        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.circular_yellow);        level = LEVEL2;    } else if (levelLength >= LEVEL3 && levelLength < LEVEL4) {        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.circular_orange);        level = LEVEL3;    } else if (levelLength >= LEVEL4 && levelLength < LEVEL5) {        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.circular_red);        level = LEVEL4;    } else if (levelLength >= LEVEL5) {        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.circular_pink);        level = LEVEL5;    }    canvas.drawBitmap(bitmap, (level - 80) * denistyX, headY, paint);    if (headImage != null) {        canvas.drawBitmap(headImage, (level - 72) * denistyX, headY + 8 * denistyY, paint);    }    switch (level) {        case LEVEL0:            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade0);            break;        case LEVEL1:            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade1);            break;        case LEVEL2:            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade2);            break;        case LEVEL3:            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade3);            break;        case LEVEL4:            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade4);            break;        case LEVEL5:            bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.grade5);            break;    }    canvas.drawBitmap(bitmap, (level - 80) * denistyX,155 * denistyY, paint);}

}
接下来是 Activity的代码 因为不是Demo 只能贴出部分关键代码
Handler 的部分

Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (myLevelView.level*denistyX - 340*denistyX > 0 && length*denistyX <= myLevelView.level*denistyX - 340*denistyX) {
LogUtils.e(myLevelView.level*denistyX+” “+length);
scrollView.smoothScrollBy((int)(10*denistyX),0);
}
}
};
计算经验值的等级和绘制的距离

 private void caculateLevelLength(int expirense){    if (expirense>=0 && expirense<300){        levelLength = MyLevelView.LEVEL0 + expirense*276/300;    }else if (expirense>=300 && expirense<1300){        levelLength = MyLevelView.LEVEL1 + (expirense-300)*276/1000;    } else if (expirense>=1300 && expirense<3300){        levelLength = MyLevelView.LEVEL2 + (expirense-1300)*276/2000;    }else if (expirense>=3300 && expirense<6300){        levelLength = MyLevelView.LEVEL3 + (expirense-3300)*276/3000;    }else if (expirense>=8300 && expirense<9300){        levelLength = MyLevelView.LEVEL4 + (expirense-8300)*276/3000;    }else if (expirense>=18300){        levelLength = MyLevelView.LEVEL5 + (expirense-18300)*276/1000;    }

Thread的代码

new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
Thread.sleep(40);
length += 10;
if (length >= levelLength) {
length = levelLength;
}
myLevelView.setCurrentLength(length);
myLevelView.postInvalidate();
handler.sendEmptyMessage(0);
if (length == levelLength) {
break;
}
}
} catch (Exception e) {
LogUtils.e(e.getMessage());
}
}
}).start();

基本上主要代码就在这里 ,按照上面的三个步骤。应该不难完成接下来的代码。

在这里说明一个问题,众所周知的安卓适配的问题,在1280*720 dpi = 320的时候是没有问题的,放在1920*1080 dpi=480的时候图片就严重变形了
其实这个问题并不难解决
方法1
在drawable 文件夹下mdpi hdpi xhdpi xxhdpi四个文件夹下放置对应的图片资源,系统会通过不同dpi拿不同的图片 。这个在模拟器上很难发现
方法2
在hdpi文件夹下面放置一套资源文件 ,但是在canvas.drawBitmap()之前把bitmap按照屏幕像素密度等比例放大就可以了。

布局文件在外层放置一个横向的HorizontalScrollView 调用他的smoothScrollBy()方法就可以动起来了
这里就不贴了
还有就是自定义属性,这个可以自己百度下
我这里有两个total_length level_length 大家可以尽情改造

以上就是所有。
对了,还有计算屏幕像素的代码一并给大家参考
/**
* 获得不同分辨率宽高比系数
*
* @param activity
* @return
*/
public static float[] getAdapterRatio(Activity activity) {
DisplayMetrics metric = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metric);
float widthRatio = (float) metric.widthPixels / 720f;
float heightRatio = (float) metric.heightPixels / 1280f;
return new float[]{widthRatio, heightRatio};
}
写的不对的地方欢迎大家指正。。。后续还有会项目里面遇到的各种问题,在闲暇的时候会动手发出来。

1 0
原创粉丝点击