热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

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

这篇文章主要介绍了Android自定义View实现等级滑动条的实例的相关资料,需要的朋友可以参考下

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

实现效果图:

思路:

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

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

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

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

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

1,自定义属性

<&#63;xml version="1.0" encoding="utf-8"&#63;>

    
     
        
     
    
     
      
   

然后获取属性:

 /** 
     * 获得我们所定义的自定义样式属性 
     */ 
    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

全部代码如下

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 pointList;//储存画出的点的point值
  private HashMap 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();
    mHashMap=new HashMap();
  }
  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;i100){//如果按下,抬起时间过大才认为是拖动,要执行动画。
           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:

 

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 listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文讲述了如何通过代码在Android中更改Recycler视图项的背景颜色。通过在onBindViewHolder方法中设置条件判断,可以实现根据条件改变背景颜色的效果。同时,还介绍了如何修改底部边框颜色以及提供了RecyclerView Fragment layout.xml和项目布局文件的示例代码。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文讨论了在Spring 3.1中,数据源未能自动连接到@Configuration类的错误原因,并提供了解决方法。作者发现了错误的原因,并在代码中手动定义了PersistenceAnnotationBeanPostProcessor。作者删除了该定义后,问题得到解决。此外,作者还指出了默认的PersistenceAnnotationBeanPostProcessor的注册方式,并提供了自定义该bean定义的方法。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
author-avatar
peaxcwxzl_372248
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有