没事做用自定义view方式写一个星评控件,虽说网上很多这个控件,但是这是自己写的,在这里记录一下。
首先需要自定义属性
初始化代码
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(); } //如果没有宽高就设置一个默认值 if (rateHeight <= 0){ rateHeight = 80; } if (rateWidth <= 0){ rateWidth = 80; } if (activeId!=0){ activeBitmap = BitmapFactory.decodeResource(getResources(), activeId); //如果没有设置宽高时候 if (rateWidth <= 0) { rateWidth = activeBitmap.getWidth(); } //把图片压缩到设置的宽高 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方法设置View的宽高,如果设置的每一个星星控件的宽高大于实际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的宽度小于设置size*星星的宽度,就用size * (int) (padding + rateWidth)做为控件的宽度度 if (widthSize
onDraw方法中绘制
//开始画active for (int i = 0; i
上面用到两个方法drawActivRate和drawDisActivRate,分别是在没有设置活动中的星星和不在活动中星星的图片的时候,绘制在活动和不在活动的默认星星:
/** * 绘制黄色的五角星(在活动的) * */ private void drawActivRate(int position,Canvas canvas){ float radius = rateWidth/2;//根據每一個星星的位置繪製園,確定五角星五個點的位置 float angle = 360/5; float centerX = (rateWidth+padding)*(position+1)-padding-radius;//獲取每一個星星空間的中心位置的X坐標 float centerY =height/2;//獲取每一個星星空間的中心位置的y坐標 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
以上就是自定义view写的星评控件,代码中的注解已经比较详细了,就不多说了,
源码地址
以上所述是小编给大家介绍的android自定义星评空间的实例代码,希望对大家有所帮助!