欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android自定义控件RatingBar调整字体大小

程序员文章站 2023-11-11 08:46:52
项目需要,做一个可以调整字体大小的控件,能在滑动或点击时改变选中的位置,效果图如下: 这是一个类似于ratingbar的控件,然而配置ratingbar的样式难以实现...

项目需要,做一个可以调整字体大小的控件,能在滑动或点击时改变选中的位置,效果图如下:

Android自定义控件RatingBar调整字体大小

这是一个类似于ratingbar的控件,然而配置ratingbar的样式难以实现这样的效果,如选中的图案和上面的文字对齐。因此,有必要写一个自定义view来实现。

思路如下:

  • 新建一个textratingbar继承view类
  • 在ondraw()方法中绘制元素:文字、横线、短竖线和圆形标记
  • 重写onmeasure()方法,控制整体大小和边界
  • 在ontouchevent()方法中处理action_down和action_move事件,调用invalidate()方法引起view的重绘,以更新视图
  • 定义一个用户选中某个字体的回调接口,以通知外部处理,比如去设置字体大小。

textratingbar类代码如下:

package cc.rome753.demo.view;

import android.content.context;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.paint;
import android.util.attributeset;
import android.util.log;
import android.view.motionevent;
import android.view.view;

/**
 * created by rome753 on 2017/3/10
 */

public class textratingbar extends view{

 //paddingleft
 private int mleft;
 //paddingtop
 private int mtop;
 //当前rating
 private int mrating;
 //总raring数
 private int mcount;
 //rating文字
 private string[] texts = {"小","中","大","超大"};
 //相邻raring的距离
 private int munitsize;
 //bar到底部的距离
 private int myoffset;
 //小竖条的一半长度
 private int mmarksize;

 paint paint = new paint();

 public textratingbar(context context) {
  this(context, null);
 }

 public textratingbar(context context, attributeset attrs) {
  this(context, attrs, 0);
 }

 public textratingbar(context context, attributeset attrs, int defstyleattr) {
  super(context, attrs, defstyleattr);
  mcount = 4;
  mrating = 0;
  mmarksize = 3;
 }

 @override
 protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
  super.onmeasure(widthmeasurespec, heightmeasurespec);
  log.i("test", getmeasuredwidth() + " " + getmeasuredheight());
  mleft = (getpaddingleft()+getpaddingright())/2;
  mtop = getpaddingtop();
  int barwidth = getmeasuredwidth() - 2 * mleft;
  munitsize = barwidth/(mcount - 1);
  myoffset = getmeasuredheight() - getpaddingbottom();
 }

 @override
 protected void ondraw(canvas canvas) {
  paint.setstrokewidth(2);
  paint.setcolor(color.red);
  canvas.drawline(mleft,myoffset,mleft+mrating*munitsize,myoffset,paint);
  for(int i=0;i<mcount;i++){
   paint.setcolor(color.red);
   canvas.drawline(mleft+i*munitsize,myoffset-mmarksize,mleft+i*munitsize,myoffset+mmarksize,paint);
   paint.setcolor(mrating == i ? color.red : color.black);
   paint.settextsize(30);
   paint.settextalign(paint.align.center);
   canvas.drawtext(texts[i],mleft+i*munitsize,mtop,paint);
  }
  paint.setcolor(color.gray);
  canvas.drawline(mleft+mrating*munitsize,myoffset,mleft+(mcount-1)*munitsize,myoffset,paint);
  canvas.drawcircle(mleft+mrating*munitsize,myoffset,10,paint);

 }

 @override
 public boolean ontouchevent(motionevent event) {
  if(event.getaction() == motionevent.action_down || event.getaction() == motionevent.action_move){
   float x = event.getx();
   for(int i=0;i<mcount;i++){
    float distance = mleft+i*munitsize - x;
    if(math.abs(distance) < 100){
     setrating(i);
     if(onratinglistener != null){
      onratinglistener.onrating(mrating);
     }
     break;
    }
   }
  }
  return true;
 }

 public void setrating(int rating) {
  mrating = rating;
  invalidate();
 }

 private onratinglistener onratinglistener;

 public void setonratinglistener(onratinglistener onratinglistener) {
  this.onratinglistener = onratinglistener;
 }

 interface onratinglistener{
  void onrating(int rating);
 }
}


几个要点:

  • ondraw()中的绘制要注意周围的预留空间,防止最左边的字体只显示一半,或滑动条下面没有一点空白的预留空间,导致用户不好划。因此在计算每一个绘制坐标时额外加上这些。
  • 触摸事件是判断当前触摸点离哪个rating点最近,要加上左右临界值math.abs(distance),用户点击或划动在distance范围内就算发生了onrating()事件。

没有用到自定义属性,使用时直接放到布局中,周围加上padding就行了。

 <cc.rome753.demo.view.textratingbar
  android:paddingtop="20dp"
  android:paddingleft="40dp"
  android:paddingright="40dp"
  android:paddingbottom="35dp"
  android:layout_width="match_parent"
  android:layout_height="70dp" />

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。