全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Android 自定义星评空间示例代码

没事做用自定义view方式写一个星评控件,虽说网上很多这个控件,但是这是自己写的,在这里记录一下。

首先需要自定义属性

<declare-styleable name="Rate">
    <!--属性分别是:单个的宽,高,之间的距离,激活的数量,总数量,激活的drawable,没有激活的drawable,是否可以选择数量-->
    <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();
    }
    //如果没有宽高就设置一个默认值
    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 < size * (int) (padding + rateWidth)) {
        width = size * (int) (padding + rateWidth);
      } else {
        width = widthSize;
      }
    } else {
      width = size * (int) (padding + rateWidth)-padding;
    }
    //计算高
    if (heightMode == MeasureSpec.EXACTLY) {
      //如果view的高度小于设置星星的高度,就用星星高度做为控件的高度
      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,分别是在没有设置活动中的星星和不在活动中星星的图片的时候,绘制在活动和不在活动的默认星星:

/**
   * 绘制黄色的五角星(在活动的)
   * */
  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 < 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写的星评控件,代码中的注解已经比较详细了,就不多说了,

源码地址

以上所述是小编给大家介绍的android自定义星评空间的实例代码,希望对大家有所帮助!


# Android  # 自定义星评空间  # Android RatingBar星星评分控件实例代码  # Android UI控件RatingBar实现自定义星星评分效果  # Android自定义星星评分控件  # 自定义  # 就用  # 如果没有  # 这是  # 是在  # 在这里  # 活动中  # 说了  # 不多  # 给大家  # 不支持  # 可以选择  # 所述  # 小编  # 默认值  # 网上  # Rate_custom_rate_width  # rateWidth  # Rate_custom_rate_height  # Rate_custom_rate_active_drawable 


相关文章: 如何在IIS管理器中快速创建并配置网站?  邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?  ,石家庄四十八中学官网?  建站主机无法访问?如何排查域名与服务器问题  魔方云NAT建站如何实现端口转发?  c# F# 的 MailboxProcessor 和 C# 的 Actor 模型  建站与域名管理如何高效结合?  中山网站制作网页,中山新生登记系统登记流程?  香港服务器选型指南:免备案配置与高效建站方案解析  建站之家VIP精选网站模板与SEO优化教程整合指南  建站IDE高效指南:快速搭建+SEO优化+自适应模板全解析  东莞市网站制作公司有哪些,东莞找工作用什么网站好?  大型企业网站制作流程,做网站需要注册公司吗?  制作电商网页,电商供应链怎么做?  建站之星北京办公室:智能建站系统与小程序生成方案解析  免费制作海报的网站,哪位做平面的朋友告诉我用什么软件做海报比较好?ps还是cd还是ai这几个软件我都会些我是做网页的?  如何有效防御Web建站篡改攻击?  小捣蛋自助建站系统:数据分析与安全设置双核驱动网站优化  内网网站制作软件,内网的网站如何发布到外网?  自助网站制作软件,个人如何自助建网站?  成都网站制作价格表,现在成都广电的单独网络宽带有多少的,资费是什么情况呢?  建站之星ASP如何实现CMS高效搭建与安全管理?  网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?  如何在Ubuntu系统下快速搭建WordPress个人网站?  制作旅游网站html,怎样注册旅游网站?  css网站制作参考文献有哪些,易聊怎么注册?  ,交易猫的商品怎么发布到网站上去?  PHP 500报错的快速解决方法  Android滚轮选择时间控件使用详解  如何通过服务器快速搭建网站?完整步骤解析  商务网站制作工程师,从哪几个方面把握电子商务网站主页和页面的特色设计?  相册网站制作软件,图片上的网址怎么复制?  制作门户网站的参考文献在哪,小说网站怎么建立?  高性能网站服务器部署指南:稳定运行与安全配置优化方案  网站制作报价单模板图片,小松挖机官方网站报价?  标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?  购物网站制作公司有哪些,哪个购物网站比较好?  湖州网站制作公司有哪些,浙江中蓝新能源公司官网?  大同网页,大同瑞慈医院官网?  可靠的网站设计制作软件,做网站设计需要什么样的电脑配置?  Swift中switch语句区间和元组模式匹配  详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)  香港服务器租用每月最低只需15元?  如何在IIS中新建站点并配置端口与IP地址?  微信h5制作网站有哪些,免费微信H5页面制作工具?  香港服务器网站卡顿?如何解决网络延迟与负载问题?  内部网站制作流程,如何建立公司内部网站?  建站之星体验版:智能建站系统+响应式设计,多端适配快速建站  广州网站建站公司选择指南:建站流程与SEO优化关键词解析  已有域名能否直接搭建网站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。