android 垂直 SeekBar 源代码(VerticalSeekBar)

Android实现自定义的垂直SeekBar 然而,默认的SeekBar只支持水平方向的滑动,如果我们需要实现一个垂直方向的SeekBar,就需要进行一些自定义。在这个示例中,我们将垂直SeekBar放置在一个垂直方向的LinearLayout中,并设置了一些基本属性,如ID、宽度、高度和最大值。首先,我们需要创建一个自定义的垂直SeekBar类,继承自SeekBar。方法:用于绘制SeekBar,在绘制之前对画布进行旋转和平移操作,使SeekBar在垂直方向上正确显示。方法:用于测量SeekBar的尺寸,将宽度和高度进行交换,以实现垂直方向的滑动。 阅读详情

搬家后的博客链接: IT客栈 www.itkezhan.org


这几天需要用到垂直的 seekbar 但是android 包下翻了一下。发现没有,只能自己修改源码。


主要是继承 AbsSeekBar 然后修改下面这些方法


onProgressRefresh() //当进度条数据更新的时候,例如我们拖动滑动条的时候,这个方法被调用

setThumbPos() //这个方法是设置Thumb的位置

onDraw() //这个是负责画界面

onSizeChanged() //更新画布尺寸

onTouchEvent() //当触摸屏幕的时候被调用

trackTouchEvent() //当拖动滑动条的时候,这个被调用


还有就是添加一个接口这个接口是SeekBar 的一个内部接口 public interface OnSeekBarChangeListener

里面有三个方法:

public void onProgressChanged(VerticalSeekBar vBar, int progress,boolean fromUser);
public void onStartTrackingTouch(VerticalSeekBar vBar);
public void onStopTrackingTouch(VerticalSeekBar vBar);

这个接口主要是为外部提供监听。多说无益,大家看源代码明白一点。


import java.lang.reflect.Field;
import java.lang.reflect.Method;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsSeekBar;
import android.widget.SeekBar;


public class VerticalSeekBar extends AbsSeekBar { 

	private int height = -1;
	private int width = -1;
	public interface OnSeekBarChangeListener
	{
		public void onProgressChanged(VerticalSeekBar vBar, int progress,boolean fromUser);
		public void onStartTrackingTouch(VerticalSeekBar vBar);
		public void onStopTrackingTouch(VerticalSeekBar vBar);
	}
	
	private OnSeekBarChangeListener mOnSeekBarChangeListener;
	public VerticalSeekBar(Context context)
	{
		this(context, null);
	}
	
	public VerticalSeekBar(Context context, AttributeSet attrs)
	{
		this(context, attrs, android.R.attr.seekBarStyle);
	}
	
	public VerticalSeekBar(Context context, AttributeSet attrs, int defstyle)
	{
		super(context, attrs, defstyle);
	}
	
	public void setOnSeekBarChangeListener(OnSeekBarChangeListener l)
	{
		mOnSeekBarChangeListener = l;
	}
	
	void onStartTrackingTouch()
	{
		if (mOnSeekBarChangeListener != null)
		{
			mOnSeekBarChangeListener.onStartTrackingTouch(this);
		}
	}
	
	void onStopTrackingTouch()
	{
		if (mOnSeekBarChangeListener != null)
		{
			mOnSeekBarChangeListener.onStopTrackingTouch(this);
		}
	}
	
	void onProgressRefresh(float scale, boolean fromUser)
	{
		Drawable thumb = null;
		try
		{
			Field mThumb_f = this.getClass().getSuperclass().getDeclaredField("mThumb");
			mThumb_f.setAccessible(true);
			thumb = (Drawable)mThumb_f.get(this);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

		setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE);
		
		invalidate();
		
        if (mOnSeekBarChangeListener != null) {
            mOnSeekBarChangeListener.onProgressChanged(this, getProgress(), fromUser);
        }
	}
	
	private void setThumbPos(int w, Drawable thumb, float scale, int gap)
	{
		int available = 0;
		try
		{

			int up = getPaddingTop();
			int bottom = getPaddingBottom();
			
			available = getHeight() - up - bottom;
	        int thumbWidth = thumb.getIntrinsicWidth();
	        int thumbHeight = thumb.getIntrinsicHeight();
	        available -= thumbWidth;
	        
	        //The extra space for the thumb to move on the track
	        available += getThumbOffset() * 2;
	        
	        int thumbPos = (int) (scale * available);

	        int topBound, bottomBound;
	        if (gap == Integer.MIN_VALUE) {
	            Rect oldBounds = thumb.getBounds();
	            topBound = oldBounds.top;
	            bottomBound = oldBounds.bottom;
	        } else {
	            topBound = gap;
	            bottomBound = gap + thumbHeight;
	        }
	        // Canvas will be translated, so 0,0 is where we start drawing
	        thumb.setBounds(thumbPos, topBound, thumbPos + thumbWidth, bottomBound);	
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

	}
	
	 protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
	 {     
		 width = 30;
         height = View.MeasureSpec.getSize(heightMeasureSpec);
 
         this.setMeasuredDimension(width, height); 
	 } 
	
	protected void onDraw(Canvas c)
	{
		c.rotate(-90);
		c.translate(-height,0); 
		super.onDraw(c);
	}
	
	protected void onSizeChanged(int w, int h, int oldw, int oldh)
	{     
        super.onSizeChanged(h, w, oldw, oldh); 
	} 
	
    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
    	
    	boolean mIsUserSeekable=true;
		try
		{
	    	Field mIsUserSeekable_f = this.getClass().getSuperclass().getDeclaredField("mIsUserSeekable");
	    	mIsUserSeekable_f.setAccessible(true);

			mIsUserSeekable = mIsUserSeekable_f.getBoolean(this);
		}
		catch (Exception e1)
		{
			e1.printStackTrace();
		}
    	
        if (!mIsUserSeekable || !isEnabled()) {
            return false;
        }
        
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                setPressed(true);
                onStartTrackingTouch();
                trackTouchEvent(event);
                break;
                
            case MotionEvent.ACTION_MOVE:
                trackTouchEvent(event);
                Method attemptClaimDrag;
				try
				{
					attemptClaimDrag = this.getClass().getSuperclass().getDeclaredMethod("attemptClaimDrag");
					attemptClaimDrag.setAccessible(true);
	                attemptClaimDrag.invoke(this);
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
                break;
                
            case MotionEvent.ACTION_UP:
                trackTouchEvent(event);
                onStopTrackingTouch();
                setPressed(false);
                // ProgressBar doesn't know to repaint the thumb drawable
                // in its inactive state when the touch stops (because the
                // value has not apparently changed)
                invalidate();
                break;
                
            case MotionEvent.ACTION_CANCEL:
                onStopTrackingTouch();
                setPressed(false);
                invalidate(); // see above explanation
                break;
        }
        return true;
    }
    
    protected void trackTouchEvent(MotionEvent event)
    {
    	
        final int height = getHeight();
        final int available = height - getPaddingLeft() - getPaddingRight();
        int y = (int)(height - event.getY());
        float scale;
        float progress = 0;
        if (y < getPaddingLeft()) {
            scale = 0.0f;
        } else if (y > height - getPaddingRight()) {
            scale = 1.0f;
        } else {
            scale = (float)(y - getPaddingLeft()) / (float)available;
            float mTouchProgressOffset = 0.0f;
            try
            {
            	Field mTouchProgressOffset_f = this.getClass().getSuperclass().getDeclaredField("mTouchProgressOffset");
            	mTouchProgressOffset_f.setAccessible(true);
            	mTouchProgressOffset = mTouchProgressOffset_f.getFloat(this);
            }
            catch(Exception e)
            {
    			e.printStackTrace();
            }
            progress = mTouchProgressOffset;
        }
        
        final int max = getMax();
        progress += scale * max;
        
        try
        {
        	Method setProgress = this.getClass().getSuperclass().getSuperclass().getDeclaredMethod("setProgress", int.class,boolean.class);
        	setProgress.setAccessible(true);
        	setProgress.invoke(this, (int)progress, true);
        }
        catch(Exception e)
        {
			e.printStackTrace();
        }
    }
}


一个运行的截图


转载请注明出处,祝新年快乐。

本文链接:

http://blog.youkuaiyun.com/failure01/article/details/8577675

参考文档链接:

http://www.eoeandroid.com/thread-430-1-1.html

http://blog.youkuaiyun.com/saintswordsman/article/details/5248233

Android实现垂直进度条VerticalSeekBar 主要为大家详细介绍了Android实现垂直进度条VerticalSeekBar的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 立即下载

相关推荐

[Spawn service failed. Exiting] ROS2运行turtlebot3_gazebo例程卡住_报错

[Spawn service failed. Exiting] ROS2运行turtlebot3_gazebo例程卡住_报错

Feizhai2的博客 4862

直播视频系统源码,Android滑动模块 SeekBar

直播视频系统源码,Android滑动模块 SeekBar <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"

云豹网络科技 348

【项目分享】RailTracker: 火车票务数据采集与分析

从12306使用爬虫爬取火车站及车次信息、火车票价 通过本项目,我们将带领访问者手把手完成火车票数据采集、数据清洗、数据集成、可视化的一整个流程!

zhushatong的博客 3345

android 快速实现 垂直SeekBar(VerticalSeekBar)

【代码】android 快速实现 垂直SeekBar(VerticalSeekBar)

OneN的博客 1739

STM32H723串口接收全为0 & CAN错误中断问题

STM32H723串口接收全为0 和 叠加的导致CAN错误问题

weixin_38743772的博客 3916

SAP Group Reporting入门指南(8)--业务操作

关于资产负债表类的匹配,系统预设了SGR01和SGR02两个方法,主要区别在于数据的来源范围,SGR01取自ACDOCA和ACDOCU,如果是0F类型的就会直接显示日记账分录(期间是000的除外,这类凭证是年结结转的,系统不再跨年追溯),如果是其他类型就显示合并分录。这里是我觉得SAP还需要优化的地方。基于ICMR的抵消任务中通常将抵销差异细分为交易差异、货币换算差异和其他差异,这在基于重分类抵消任务是无法实现的,基于重分类抵消只知道一个差异总额,很难从合并抵消凭证看出差异的来源,也没有审计线索可言。

bflyfish的博客 276

Android 垂直seekbar

android系统自带的拖动条(seekbar)只有横向,这里分享一个垂直的seekbar。 原理很简单,就是在绘制的时候将拖动条(seekbar) package com.chy.view; import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; im

司马懿的西山居 2764

uniapp - 最新详细实现web-view网页与安卓苹果App端之间互相通信功能,苹果app/安卓app平台与内嵌webview组件内的网页进行相互传值,内置网页与app双向实时通信,详细示例代码

uni-app,Android安卓,苹果ios,app,内嵌webview,第三方H5网页,app和web-view通信传值,web-view引入的页面向App主应用传递数据,App端与webview端相互通信,App端和H5端webview之间的通信,uniapp实现webview和APP之间的传值通信,如何互相传递对象数据,数据传递了接收不到,web-view页面向app内发送消息,监听传递的参数,uni-app和web-view页面相互传参,报错怎么办,跨域,屏幕空白出错,数据交互,解决手机物理返回按

🏆 前端领域优质创作者 4741

android 垂直 SeekBar 源代码(VerticalSeekBar)[转]

主要是继承 AbsSeekBar 然后修改下面这些方法 onProgressRefresh() //当进度条数据更新的时候,例如我们拖动滑动条的时候,这个方法被调用 setThumbPos() //这个方法是设置Thumb的位置 onDraw() //这个是负责画界面 onSizeChanged() //更新画布尺寸 onTouchEvent() //当触摸屏幕的时候被调用 track...

weixin_30505043的博客 123

AI辅助Android开发:从传统到智能化的技术演进

AI辅助开发的核心在于利用算法模型自动化或优化传统任务。在Android开发中,AI可应用于需求分析、设计、编码、测试和维护各阶段。需求分析:AI工具如基于NLP的模型(例如GPT系列)可解析用户需求文档,自动生成用户故事和原型设计。假设产品需求为“开发一个航班查询应用”,AI能提取关键词,输出UML图或伪代码。代码生成:使用AI代码助手(如GitHub Copilot),工程师输入自然语言描述,AI生成Java/Kotlin代码片段。

郑伟强dev的专栏 137

实用指南:制作通用的INCA和CANape兼容A2L文件

A2L(ASAM MCD-2 Measurement and Calibration Data)文件是描述ECU(电子控制单元)测量和校准数据的标准文件格式。在标定工作中,A2L文件扮演着极为重要的角色,它定义了测量通道、校准参数等关键信息,为工程师提供了统一的描述方式。INCA和CANape是两种常见的汽车电子系统标定工具,分别由ETAS和Vector公司开发。它们在汽车电子系统的开发和调试过程中发挥着重要作用,提供了丰富的标定功能和用户友好的界面。

一直在水些技术小文 2924

Android竖式SeekBar实现及demo

转载请注明出处,谢谢http://blog.youkuaiyun.com/metalseed/article/details/8014758      by---MetalSeed VerticalSeekBar demo 网上介绍较多,但完整的java代码较少,所以直接上源码咯~ demo:(其中穿插了蓝牙demo,但是VerticalSeekBar的布局设置,及设置监听还是比较清晰的,个人觉

MetalSeed 3998

【华为OD机试真题】439、精准核酸检测 | 机试真题+思路参考+代码解析 (C++、Java、Py、C语言、JS)

题目描述 >为了达到新冠疫情精准防控的需要,为了避免全员核酸检测带来的浪费,需要精准圈定可能被感染的人群现在根据传染病流调以及大数据分析,得到了每个人之间在时间、空间上是否存在轨迹的交叉。现在给定一组确诊人品编号(X1 X2 X3.....n)在所有人当中,找出哪些人票要进行核酸检测,输出需要进行核酸检测的人数。(注意:确诊病例自身不需要再做核酸检) >  需要进行核酸检测的人,是病毒传播链条上的所有人员,即有可能通过确诊病例所能传播到的所有人   例如:A是确诊病例,A和B有接触、B和

KJ.JK 1434

libquic深度解析:从TCP+TLS+SPDY到现代网络传输的革命

libquic是一个基于UDP的多路复用流传输协议实现,旨在通过革新性设计解决传统TCP+TLS+SPDY组合的性能瓶颈。作为从Chromium项目提取的开源库,它提供了低延迟、高可靠性的网络传输能力,已成为现代网络应用的关键基础设施。 ## 为什么需要QUIC?传统TCP+TLS+SPDY的痛点 传统网络传输依赖TCP+TLS+SPDY的组合,但这种架构存在难以克服的局限: - **连接建

gitblog_00502的博客 518

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Android自定义垂直 SeekBar

android 本身只有一个水平的 seekbar,开发需要使用垂直的seekbar就只能自己实现了,好在可以直接继承水平seekbar,修改几个重载事件即可。onDraw事件中旋转画布,由水平变垂直。measure事件中重新计算控件尺寸,对换宽高值。切记加上尺寸变更时的事件,变更对换宽高值。最后重载一下滑动事件,重新计算progress值。以上即可实现垂直的seekbar,但我在实际使用时,发现显示不出来,拉大尺寸发现本身是有显示出来的,但是位置什么的都不对,感觉内部padding值很大。自定义外观解决。

曲幽 5106

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Android VerticalSeekBar竖直进度条的使用及问题总结

注:下文中SettingItemView源代码(由于涉及信息安全,个人私密博客,与本文总结的进度条并没有多少关联,仅供自己review) 需求简单描述: 在项目中有多个自定义的卡片SettingItemView(也是一个自定义View),其中一个卡片中要使用到一个竖直的进度条。 我们这边要实现的,就是设计一个自定义的竖直进度条,并且只在这一个卡片中显示出来。 这边需要 (1)自定义一个VerticalSeekBar.java文件 (2)在values文件中的color.xml和attrs.xml中添加(1)

ambitionLlll的博客 1402

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

优雅实现垂直SeekBar:不继承Seekbar、不自定义View

实现竖直SeekBar,目前大抵有如下3种方案: 方案一:通过继承View自定义实现,如:继承View自定义实现VerticalSeekBar 方案二:通过继承SeekBar重载方法内部旋转实现,如:继承SeekBar重载方法内部旋转实现 方案三:对于API 11和更高版本,通过rotation属性在XML中指定旋转270°实现,如:使用seekbar的XML属性(android:rotation="270")获得垂直效果 看标题我们就知道,本文采用的方案三,不继承SeekBar

让学习编程变得生动有趣~ 3841

Android 垂直拖动条,垂直SeekBar实现

自定义垂直SeekBar及样式

Benlve的博客 2815

竖直的seekbar

<br /><br />public class VerticalSeekBar extends AbsSeekBar {<br />    private Drawable mThumb;<br />    private int height;<br />    private int width;<br />    public interface OnSeekBarChangeListener {<br />        void onProgressChanged(VerticalSeekBar

lili1985516的专栏 2132

Android拖动条(SeekBar)简单源码剖析

写在开始之前 在Android的色彩处理中,我们通常用三个角度来描述一个图像: 色调: 图像的颜色 饱和度:颜色的纯度,从0(灰)到100%(饱和)来进行描述 亮度:颜色的相对明暗程度 在上面三个属性中,饱和度和亮度为0会使得图片看起来是纯黑色。(记住这一点) 本篇源码分析的原因就是来自这个问题。 正文 在Android开发的过程中,大家

qq_35598366的博客 1398

一起Talk Android吧(第四百六十回:SeekBar源代码分析)

本章回中主要分析了SeekBar的源代码,并且得出了相关的结论,请大家参考。

talk_8的专栏 619

自定义竖着的SeekBar

一、由于android只定义了横着的SeekBar,所以竖着的SeekBar要由我们自己自定义,现在我来谈谈我自己自定义竖着的SeekBar的做法 竖着的SeekBar有分方向向上和向下,不过代码的区别不是很大,下面会细讲。 步骤: 1、首先要新建一个类来继承AbsSeekBar,类里面再自定义一个监听器接口,比如:OnSeekBarChangeListener(这个名字可以自己定义,我这样

shenyuemei的专栏 8692

java安卓开发进度条_Android实现垂直进度条VerticalSeekBar

本文实例为大家分享了android实现垂直进度条的具体代码,供大家参考,具体内容如下水平的进度条见多了,总会想见个垂直的进度条开开眼。今天咱就试试。要说原理也简单,就是把宽高倒置,其他的理论上都不需要动,发现问题再补补也就行了。官方提供官方是提供了垂直进度条的例子源码的,位置在android-sdk-windows\sources\android-23\com\android\example\rs...

weixin_28961565的博客 732

android 上拖拉底部,Android拖动条(SeekBar)简单源码剖析

写在开始之前在Android的色彩处理中,我们通常用三个角度来描述一个图像:色调: 图像的颜色饱和度:颜色的纯度,从0(灰)到100%(饱和)来进行描述亮度:颜色的相对明暗程度在上面三个属性中,饱和度和亮度为0会使得图片看起来是纯黑色。(记住这一点)本篇源码分析的原因就是来自这个问题。正文在Android开发的过程中,大家有可能都使用过SeekBar这个控件,比如拖动视频进度条、音频进度条等。不管...

weixin_39946767的博客 352

Android DiscreteSeekBar使用简介,一个带气泡的SeekBar github源码

效果: as引入: dependencies { compile 'org.adw.library:discrete-seekbar:1.0.1' } 使用说明: 将控件放入xml中: <org.adw.library.widgets.discreteseekbar.DiscreteSeekBar android:layout_width="match_parent" android:layout_height="wrap_conte.

农村打工仔的博客 634
上一篇: Android开发 MeasureSpec介绍
下一篇: android mimeType 表
failure01
博客等级 码龄15年 18粉丝 31原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值