iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android自定义View实现等级滑动条的实例
  • 455
分享到

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

viewAndroid 2022-06-06 01:06:15 455人浏览 泡泡鱼
摘要

 Android自定义View实现等级滑动条的实例 实现效果图: 思路: 首先绘制直线,然后等分直线绘制点; 绘制点的时候把X值存到集合中。 然后绘制背

 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应用开发SharedPreferences存储数据的使用方法android TextView设置中文字体加粗实现方法android调试工具DDMS的使用详解Android Bitmap详细介绍Android的Activity跳转动画各种效果整理android listview优化几种写法详细介绍解决Android SDK下载和更新失败的方法详解Android sqlite数据库增删改查操作的使用详解


--结束END--

本文标题: Android自定义View实现等级滑动条的实例

本文链接: https://www.lsjlt.com/news/21711.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android自定义view实现滑动解锁效果
    本文实例为大家分享了Android自定义view实现滑动解锁的具体代码,供大家参考,具体内容如下 1. 需求如下: 近期需要做一个类似屏幕滑动解锁的功能,右划开始,左划暂停。 2. ...
    99+
    2024-04-02
  • Android自定义view实现侧滑栏详解
    目录前言需求效果图编写代码主要问题前言 上一篇文章学了下自定义View的onDraw函数及自定义属性,做出来的滚动选择控件还算不错,就是逻辑复杂了一些。这篇文章打算利用自定义view...
    99+
    2022-11-13
    Android侧滑栏 Android自定义view 自定义view侧滑栏
  • Android自定义View实现竖向滑动回弹效果
    本文实例为大家分享了Android自定义View实现滑动回弹的具体代码,供大家参考,具体内容如下 前言 Android 页面滑动的时候的回弹效果 一、关键代码 public clas...
    99+
    2024-04-02
  • 如何在Android中利用View实现一个等级滑动条功能
    这篇文章将为大家详细讲解有关如何在Android中利用View实现一个等级滑动条功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。思路: 首先绘制直线,然后等分直线绘制点; 绘制点...
    99+
    2023-05-31
    android view roi
  • Android自定义view实现滑动解锁九宫格控件
    目录前言需求效果图前言 上一篇文章用贝塞尔曲线画了一个看起来不错的小红点功能,技术上没什么难度,主要就是数学上的计算。这篇文章也差不多,模仿了一个常用的滑动解锁的九宫格控件。 需求 ...
    99+
    2023-02-09
    Android滑动解锁九宫格 Android滑动解锁 Android九宫格控件
  • Android自定义View实现圆形进度条
    本文实例为大家分享了Android自定义View实现圆形进度条的具体代码,供大家参考,具体内容如下 原理非常简单,在自定义View的基础上使用Canvas的drawCircle画两个...
    99+
    2024-04-02
  • Android深入探究自定义View之嵌套滑动的实现
    本文主要探讨以下几个问题: 嵌套滑动设计目的 嵌套滑动的实现 嵌套滑动与事件分发机制 嵌套滑动设计目的 不知道大家有没有注意过淘宝APP首页的二级联动,滑...
    99+
    2024-04-02
  • Android自定义View实现气泡动画
    本文实例为大家分享了Android自定义View实现气泡动画的具体代码,供大家参考,具体内容如下 一、前言 最近有需求制作一个水壶的气泡动画,首先在网上查找了一番,找到了一个文章:A...
    99+
    2024-04-02
  • Android自定义view实现左滑删除的RecyclerView详解
    目录概述需求编写代码I编写代码II编写代码III优化总结概述 最近安卓自定义view的知识看的很熟,但是却很久没动手了,这几天用kotlin手撕了原先一个左滑删除的RecyclerV...
    99+
    2022-11-13
    Android RecyclerView Android 左滑删除RecyclerView
  • android自定义view实现圆周运动
    本文实例为大家分享了android自定义view实现圆周运动的具体代码,供大家参考,具体内容如下 思想 自定义Animation,自己定义半径,相当于原来控件的位置为(0,0),按...
    99+
    2024-04-02
  • Android怎么自定义View实现竖向滑动回弹效果
    这篇文章主要介绍“Android怎么自定义View实现竖向滑动回弹效果”,在日常操作中,相信很多人在Android怎么自定义View实现竖向滑动回弹效果问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Andro...
    99+
    2023-06-30
  • Android自定义滑动验证条的示例代码
    本文介绍了Android自定义滑动验证条的示例代码,分享给大家,具体如下:*注:不知道为什么,h6的标签在这里没用了,所以我也只能用Markdown的语法来写了项目地址:https://github.com/994866755/handso...
    99+
    2023-05-30
    android 滑动验证条 roi
  • Android自定义view实现列表内左滑删除Item
    目录前言需求运行效果编写代码主要问题动态生成TextView将TextView对齐到当前容器右端滑动出界问题滑动开始判定后续订正前言 上一篇文章自定义了一个左滑删除的Recycler...
    99+
    2023-02-09
    Android列表内左滑删除Item Android自定义view左滑删除Item
  • Android怎么自定义View实现圆形进度条
    本文小编为大家详细介绍“Android怎么自定义View实现圆形进度条”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android怎么自定义View实现圆形进度条”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。原...
    99+
    2023-07-02
  • Android如何自定View实现滑动验证效果
    本篇内容主要讲解“Android如何自定View实现滑动验证效果”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android如何自定View实现滑动验证效果”吧!效果图自定义属性代码<xm...
    99+
    2023-06-22
  • Android自定View实现滑动验证效果的代码
    效果图 自定义属性代码 <?xml version="1.0" encoding="utf-8"?> <resources> &...
    99+
    2024-04-02
  • Android自定义view实现圆环进度条效果
    本文实例为大家分享了Android自定义view实现圆环进度条效果的具体代码,供大家参考,具体内容如下 一、实现效果图 二、核心代码 自定义view的属性 <xml vers...
    99+
    2024-04-02
  • Android自定义view实现圆形进度条效果
    Android中实现进度条有很多种方式,自定义进度条一般是继承progressBar或继承view来实现,本篇中讲解的是第二种方式。 先上效果图: 实现圆形进度条总体来说并不难,还...
    99+
    2024-04-02
  • Android自定义View实现拖动自动吸边效果
    本文实例为大家分享了Android自定义View实现拖动自动吸边的具体代码,供大家参考,具体内容如下 自定义View,一是为了满足设计需求,二是开发者进阶的标志之一。随心所欲就是我等...
    99+
    2024-04-02
  • Android自定义View实现圆形加载进度条
    本文实例为大家分享了Android自定义View实现圆形加载进度条的具体代码,供大家参考,具体内容如下 效果图 话不多说,咱们直接看代码 首先第一种: 1、创建自定义View类 p...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作