全网整合营销服务商

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

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

Android自定义View实现等级滑动条的实例

 Android自定义View实现等级滑动条的实例

实现效果图:

思路:

首先绘制直线,然后等分直线绘制点;

绘制点的时候把X值存到集合中。

然后绘制背景图片,以及图片上的数字。

点击事件down的时候,换小图片为大图片。move的时候跟随手指移动。

up的时候根据此时的X计算最近的集合中的点,然后自动吸附回去。

1,自定义属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <declare-styleable name="BeautySeekBarView"> 
    <attr name="valueCountent" format="integer"/> 
     <attr name="padding" format="dimension"/>   
    <attr name="pointColor" format="color"/> 
    <attr name="lineColor" format="color"/>
    <attr name="smallPic" format="reference"/> 
    <attr name="bigPic" format="reference"/>  
  </declare-styleable> 
</resources>

然后获取属性:

 /** 
     * 获得我们所定义的自定义样式属性 
     */ 
    TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.BeautySeekBarView, defStyleAttr, 0);
    //等级数量即点的个数
    valueCountent=a.getInteger(R.styleable.BeautySeekBarView_valueCountent, 5);
    //点的颜色
    pointColor = a.getColor(R.styleable.BeautySeekBarView_pointColor, Color.WHITE); 
    //线的颜色
    lineColor = a.getColor(R.styleable.BeautySeekBarView_lineColor, Color.WHITE);
    //小图片
    smallPic=a.getResourceId(R.styleable.BeautySeekBarView_smallPic, R.drawable.ic_launcher);
    //滑动过程中的大图片
    bigPic=a.getResourceId(R.styleable.BeautySeekBarView_bigPic, R.drawable.ic_launcher);  
    //控件的内边距
    viewPadding=a.getDimensionPixelSize(R.styleable.BeautySeekBarView_padding, (int) TypedValue.applyDimension( 
            TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));

    a.recycle();    

2.绘制

@Override
  protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.onDraw(canvas);

    float PointX = 0;
    float PointY=getHeight()/2;   
    canvas.drawLine(0+getPaddingLeft(),PointY, getWidth()-getPaddingRight(), PointY, linePaint); //绘制直线

    int averageLength =(getWidth()-getPaddingLeft()-getPaddingRight())/(valueCountent-1);
    for(int i=0;i<valueCountent;i++){
      PointX=i*averageLength+getPaddingLeft();
      canvas.drawPoint(PointX, PointY, pointPaint);//绘制点

      if(pointList!=null && pointList.size()<valueCountent){
      pointList.add(PointX);//把每个点都放入集合中;
      }      
    }
    sePoolTH.release();
    canvas.drawBitmap(mBitmap, bitmapPointX-bitmapWidth/2, PointY-bitmapHeight/2, null);//绘制拖动的图片 
    canvas.drawText(""+index, bitmapPointX, (getHeight() - fontMetrics.ascent - fontMetrics.descent) / 2, textPaint); //绘制文字
  }

全部代码如下

import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.Semaphore;


import android.R.integer;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetricsInt;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;

public class BeautySeekBarView extends View {

  private Semaphore sePoolTH=new Semaphore(0);//信号量,解决并发问题

  private int valueCountent;//等级点的数量
  private int pointColor;
  private int lineColor;
  private Bitmap mBitmap;
  private int bitmapWidth;
  private int bitmapHeight;
  private float bitmapPointX;
  private ArrayList<Float> pointList;//储存画出的点的point值
  private HashMap<Float, Float> mHashMap;////把差值和listX当做键值对保存起来,便于后期找出
  private int index=1;//索引
  private float mListX;//移动后最小的点
  private int smallPic;
  private int bigPic;
  private int viewPadding; 

  private Paint pointPaint;
  private Paint linePaint;
  private Paint textPaint;
  private FontMetricsInt fontMetrics;


  public BeautySeekBarView(Context context) {
    this(context,null);   
  }
  public BeautySeekBarView(Context context, AttributeSet attrs) {
    this(context, attrs,0);   
  }
  public BeautySeekBarView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);        
     /** 
     * 获得我们所定义的自定义样式属性 
     */ 
    TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.BeautySeekBarView, defStyleAttr, 0);
    //等级数量即点的个数
    valueCountent=a.getInteger(R.styleable.BeautySeekBarView_valueCountent, 5);
    //点的颜色
    pointColor = a.getColor(R.styleable.BeautySeekBarView_pointColor, Color.WHITE); 
    //线的颜色
    lineColor = a.getColor(R.styleable.BeautySeekBarView_lineColor, Color.WHITE);
    //小图片
    smallPic=a.getResourceId(R.styleable.BeautySeekBarView_smallPic, R.drawable.ic_launcher);
    //滑动过程中的大图片
    bigPic=a.getResourceId(R.styleable.BeautySeekBarView_bigPic, R.drawable.ic_launcher);  
    //控件的内边距
    viewPadding=a.getDimensionPixelSize(R.styleable.BeautySeekBarView_padding, (int) TypedValue.applyDimension( 
            TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));

    a.recycle();    

    initData();//初始化数据 
    initPaint();//初始化画笔  
  }
  public void initData() {
//   valueCountent=7;
//   pointColor=Color.WHITE;
//   lineColor=Color.WHITE;     
//   setBackgroundColor(Color.BLACK);    
    setPadding(viewPadding, viewPadding, viewPadding, viewPadding);
    bitmapPointX=getPaddingLeft();
    mBitmap=BitmapFactory.decodeResource(getResources(), smallPic);
    bitmapWidth=mBitmap.getWidth();
    bitmapHeight=mBitmap.getHeight();
    pointList=new ArrayList<Float>();
    mHashMap=new HashMap<Float, Float>();
  }
  public void initPaint() {
    pointPaint=new Paint();
    pointPaint.setColor(pointColor);
    pointPaint.setStyle(Paint.Style.FILL);
    pointPaint.setStrokeWidth(10);
    pointPaint.setStrokeJoin(Paint.Join.ROUND);
    pointPaint.setStrokeCap(Paint.Cap.ROUND);
    pointPaint.setAntiAlias(true); 

    linePaint=new Paint();
    linePaint.setColor(lineColor);
    linePaint.setStyle(Paint.Style.STROKE);
    linePaint.setStrokeWidth(4);
    linePaint.setAntiAlias(true); 

    textPaint=new Paint();
    textPaint.setStrokeWidth(3);  
    textPaint.setTextSize(24);  
    textPaint.setColor(Color.WHITE); 
    textPaint.setTextAlign(Paint.Align.CENTER);    
    fontMetrics = textPaint.getFontMetricsInt(); 
    textPaint.setAntiAlias(true); 

  }

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  // TODO Auto-generated method stub
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

  @Override
  protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.onDraw(canvas);

    float PointX = 0;
    float PointY=getHeight()/2;   
    canvas.drawLine(0+getPaddingLeft(),PointY, getWidth()-getPaddingRight(), PointY, linePaint); //绘制直线

    int averageLength =(getWidth()-getPaddingLeft()-getPaddingRight())/(valueCountent-1);
    for(int i=0;i<valueCountent;i++){
      PointX=i*averageLength+getPaddingLeft();
      canvas.drawPoint(PointX, PointY, pointPaint);//绘制点

      if(pointList!=null && pointList.size()<valueCountent){
      pointList.add(PointX);//把每个点都放入集合中;
      }      
    }
    sePoolTH.release();
    canvas.drawBitmap(mBitmap, bitmapPointX-bitmapWidth/2, PointY-bitmapHeight/2, null);//绘制拖动的图片 
    canvas.drawText(""+index, bitmapPointX, (getHeight() - fontMetrics.ascent - fontMetrics.descent) / 2, textPaint); //绘制文字
  }

  long startTime = 0;
  @Override
  public boolean onTouchEvent(MotionEvent event) {       
        //获取手指的操作--》按下、移动、松开
        int action = event.getAction();
        switch (action) {
        case MotionEvent.ACTION_DOWN:  
          startTime=System.currentTimeMillis();
          mBitmap=BitmapFactory.decodeResource(getResources(), bigPic);
          bitmapWidth=mBitmap.getWidth();
          bitmapHeight=mBitmap.getHeight();
          textPaint.setTextSize(30); 
          //invalidate();
          break;       
        case MotionEvent.ACTION_MOVE:        
          long endTimeMove=System.currentTimeMillis();        
          if(endTimeMove-startTime>100){//如果按下,抬起时间过大才认为是拖动,要执行动画。
           bitmapPointX=event.getX();
           updateIndex(bitmapPointX);
           invalidate();
          }
          break;
        case MotionEvent.ACTION_UP:
          long endTime=System.currentTimeMillis();
          bitmapPointX=event.getX();
          mBitmap=BitmapFactory.decodeResource(getResources(),smallPic);
          bitmapWidth=mBitmap.getWidth();
          bitmapHeight=mBitmap.getHeight();
          textPaint.setTextSize(24);             
          if(endTime-startTime>200){//如果按下,抬起时间过大才认为是拖动,要执行动画。
          updateBitmapUI(bitmapPointX);
          }else{           
            bitmapPointX=updateIndex(bitmapPointX);
            invalidate();
          }
          startTime = 0;
          break;
        }
        return true;
  }
  //更新索引
  public float updateIndex(float pointX){
    float lastValue=100000;
    float currentValue=0;
    float minValue=0;
     for(float listX:pointList){
       currentValue= Math.abs(pointX-listX);
       mHashMap.put(currentValue, listX);//把差值和listX当做键值对保存起来,便于后期找出
       minValue=Math.min(lastValue,currentValue);
       lastValue=minValue;
      }      
    if(mHashMap.containsKey(minValue)){
      mListX=mHashMap.get(minValue);
    }else{
      Log.e("BeautySeekBarView", "updateBitmapUI--->mHashMap.containsKey(minValue) is null");
      return -1;
    } 
    if(pointList.contains(mListX)){
    index=pointList.indexOf(mListX)+1;
    if(mListener!=null){
      mListener.getIndex(index);
    }
    }else{
      Log.e("BeautySeekBarView", "updateBitmapUI--->pointList.contains(mListX) is null");
        return -1;
    }
    return mListX;
  }

  //当手指抬起后更新Bitmap的位置
  private void updateBitmapUI(float PointX2) {
    mListX=updateIndex(PointX2);
    //执行动画   
    ValueAnimator anim = ValueAnimator.ofFloat(PointX2, mListX);
    anim.setDuration(50);
    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        bitmapPointX =(Float) animation.getAnimatedValue();
        invalidate();
      }
    });
    anim.start();
  }

  //设置等级点的数量
  public void pointValueCountent(int countent){
    if(countent<2){
      valueCountent=2;
    }else{
      valueCountent=countent;
    }
    invalidate();
  }

  //设置默认位置
  public void setPointLocation(final int location){
    new Thread(new Runnable() {

      @Override
      public void run() {       
         try {
            sePoolTH.acquire();
          } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }    
          if(location>0&&pointList!=null&& !pointList.isEmpty()){
            bitmapPointX=pointList.get(location-1);
            postInvalidate();
          }

      }
    }).start();

  }

  //提供接口回调,获取索引
  private indexListener mListener=null;
  public interface indexListener{
    void getIndex(int index);
  }
  public void setIndexListener(indexListener listener){
    mListener=listener;
  }

}

外部调用:

XML:

 <com.example.hello.BeautySeekBarView 
    android:id="@+id/myView"
    android:layout_centerVertical="true"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    ws:padding="20dp"     
    ws:valueCountent="6"   
    ws:pointColor="#FFFFFF"
    ws:lineColor="#FFFFFF"
    ws:smallPic="@drawable/beauty_seekbar_point"
    ws:bigPic="@drawable/beauty_seekbar_point_big"/>

Java:

@Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.activity_main);

   initView(); 

   beautySeekBarView.setPointLocation(2) ;
    //

  }

  private void initView() {
  mTextView=(TextView) findViewById(R.id.tv);
  beautySeekBarView=(BeautySeekBarView) findViewById(R.id.myView);
  beautySeekBarView.setIndexListener(new indexListener() {  
    @Override
    public void getIndex(int index) {
      mTextView.setText("index="+index); 
    }
  });
  }

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# Android  # 等级滑动条的实现  # Android自定义View实现滑动条  # Android应用开发SharedPreferences存储数据的使用方法  # android TextView设置中文字体加粗实现方法  # android调试工具DDMS的使用详解  # Android Bitmap详细介绍  # Android的Activity跳转动画各种效果整理  # android listview优化几种写法详细介绍  # 解决Android SDK下载和更新失败的方法详解  # Android SQLite数据库增删改查操作的使用详解  # 自定义  # 拖动  # 按下  # 过大  # 键值  # 过程中  # 后期  # 信号量  # 大图片  # 希望能  # 谢谢大家  # 画出  # 回调  # 为大  # getPaddingLeft  # getWidth  # linePaint  # getPaddingRight  # averageLength  # amp 


相关文章: 制作表格网站有哪些,线上表格怎么弄?  建站之星ASP如何实现CMS高效搭建与安全管理?  番禺网站制作公司哪家值得合作,番禺图书馆新馆开放了吗?  h5在线制作网站电脑版下载,h5网页制作软件?  如何快速选择适合个人网站的云服务器配置?  如何配置IIS站点权限与局域网访问?  深圳网站制作培训,深圳哪些招聘网站比较好?  建站org新手必看:2024最新搭建流程与模板选择技巧  我的世界制作壁纸网站下载,手机怎么换我的世界壁纸?  建站ABC备案流程中有哪些关键注意事项?  如何快速建站并高效导出源代码?  香港网站服务器数量如何影响SEO优化效果?  高端智能建站公司优选:品牌定制与SEO优化一站式服务  如何通过PHP快速构建高效问答网站功能?  如何通过建站之星自助学习解决操作问题?  怀化网站制作公司,怀化新生儿上户网上办理流程?  如何快速搭建虚拟主机网站?新手必看指南  如何使用Golang table-driven基准测试_多组数据测量函数效率  如何通过虚拟主机快速搭建个人网站?  如何实现建站之星域名转发设置?  如何在Golang中处理模块冲突_解决依赖版本不兼容问题  正规网站制作公司有哪些,目前国内哪家网页网站制作设计公司比较专业靠谱?口碑好?  企业微网站怎么做,公司网站和公众号有什么区别?  建站VPS推荐:2025年高性能服务器配置指南  网站制作培训多少钱一个月,网站优化seo培训课程有哪些?  合肥做个网站多少钱,合肥本地有没有比较靠谱的交友平台?  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  如何获取免费开源的自助建站系统源码?  家庭服务器如何搭建个人网站?  如何通过山东自助建站平台快速注册域名?  金*站制作公司有哪些,金华教育集团官网?  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  如何生成腾讯云建站专用兑换码?  如何制作算命网站,怎么注册算命网站?  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  如何选择网络建站服务器?高效建站必看指南  专业网站制作服务公司,有哪些网站可以免费发布招聘信息?  建站之星24小时客服电话如何获取?  赚钱网站制作软件,建一个网站怎样才能赚钱?是如何盈利的?  网页设计网站制作软件,microsoft office哪个可以创建网页?  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  公众号网站制作网页,微信公众号怎么制作?  微信小程序 input输入框控件详解及实例(多种示例)  php条件判断怎么写_ifelse和switchcase的使用区别【对比】  武汉网站制作费用多少,在武汉武昌,建面100平方左右的房子,想装暖气片,费用大概是多少啊?  建站之星安装模板失败:服务器环境不兼容?  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  建站之星如何助力企业快速打造五合一网站?  北京的网站制作公司有哪些,哪个视频网站最好?  如何破解联通资金短缺导致的基站建设难题? 

您的项目需求

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