看下效果:

  

  1 package org.qianyukun.core.views;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.SeekBar; public class VerticalSeekBar extends SeekBar
{
Drawable mThumb;
private boolean mIsDragging;
private float mTouchDownY;
private int mScaledTouchSlop;
private boolean isInScrollingContainer = false; public boolean isInScrollingContainer()
{
return isInScrollingContainer;
} public void setInScrollingContainer(boolean isInScrollingContainer)
{
this.isInScrollingContainer = isInScrollingContainer;
} /**
* On touch, this offset plus the scaled value from the position of the
* touch will form the progress value. Usually 0.
*/
float mTouchProgressOffset; public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } public VerticalSeekBar(Context context, AttributeSet attrs)
{
super(context, attrs);
} public VerticalSeekBar(Context context)
{
super(context);
} @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{ super.onSizeChanged(h, w, oldh, oldw); } @Override
protected synchronized void onMeasure(int widthMeasureSpec,
int heightMeasureSpec)
{
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
} @Override
protected synchronized void onDraw(Canvas canvas)
{
canvas.rotate(90);
canvas.translate(0, -getWidth());
super.onDraw(canvas);
} @Override
public boolean onTouchEvent(MotionEvent event)
{
if (!isEnabled())
{
return false;
} switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
if (isInScrollingContainer())
{
mTouchDownY = event.getY();
}
else
{
setPressed(true);
// System.out.println(event.getY());
invalidate();
onStartTrackingTouch();
trackTouchEvent(event);
attemptClaimDrag(); onSizeChanged(getWidth(), getHeight(), 0, 0);
}
break; case MotionEvent.ACTION_MOVE:
if (mIsDragging)
{
trackTouchEvent(event);
}
else
{
final float y = event.getY();
if (Math.abs(y - mTouchDownY) > mScaledTouchSlop)
{
System.out.println("mScaledTouchSlop "+mScaledTouchSlop);
setPressed(true);
invalidate();
onStartTrackingTouch();
trackTouchEvent(event);
attemptClaimDrag();
}
}
onSizeChanged(getWidth(), getHeight(), 0, 0);
break; case MotionEvent.ACTION_UP:
if (mIsDragging)
{
trackTouchEvent(event);
onStopTrackingTouch();
setPressed(false);
}
else
{
// Touch up when we never crossed the touch slop threshold
// should
// be interpreted as a tap-seek to that location.
onStartTrackingTouch();
trackTouchEvent(event);
onStopTrackingTouch();
}
onSizeChanged(getWidth(), getHeight(), 0, 0);
// 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;
}
return true; } private void trackTouchEvent(MotionEvent event)
{
final int height = getHeight();
final int top = getPaddingTop();
final int bottom = getPaddingBottom();
final int available = height - top - bottom; int y = (int) event.getY(); float scale;
float progress = 0; if (y > height - bottom)
{
scale = 1.0f;
}
else if (y < top)
{
scale = 0.0f;
}
else
{
scale = (float) (y - top) / (float) available;
progress = mTouchProgressOffset;
} final int max = getMax();
progress += scale * max; setProgress((int) progress); } /**
* This is called when the user has started touching this widget.
*/
void onStartTrackingTouch()
{
mIsDragging = true;
} /**
* This is called when the user either releases his touch or the touch is
* canceled.
*/
void onStopTrackingTouch()
{
mIsDragging = false;
} private void attemptClaimDrag()
{
ViewParent p = getParent();
if (p != null)
{
p.requestDisallowInterceptTouchEvent(true);
}
} @Override
public synchronized void setProgress(int progress)
{ super.setProgress(progress);
onSizeChanged(getWidth(), getHeight(), 0, 0); } @Override
public void setThumb(Drawable thumb) {
super.setThumb(thumb);
mThumb = thumb;
}
public Drawable getSeekBarThumb() {
return mThumb;
} }

最近在做PDF文档的浏览,文档右侧有一个垂直的透明的滑动块,来快速定位文档位置和显示当前页面的位置。

由于原生的seekbar是水平的,所以需要可自定义View了。虽然View的自定义这块,了解的不够深,但是够用了。

实现方式:继承SeekBar,在onDrow()中将画布旋转,然后平移到能够显示的位置。添加滑动事件。

 mPageSlider = new VerticalSeekBar(context);
mPageSlider.setThumb(getResources().getDrawable(
R.drawable.pdfseekbarthum));//添加thumb样式
mPageSlider.setProgressDrawable(getResources().getDrawable(
R.drawable.seek_progress));//添加进度条样式
mPageSlider.setBackgroundResource(R.color.toolbar);
mPageSlider.setThumbOffset(0);//这句比较重要,使thumb显示完整

记录每一行代码,滴水穿石!

垂直的seekbar的更多相关文章

  1. 垂直的SeekBar:VerticalSeekBar

    public class VerticalSeekBar extends AbsSeekBar { private Drawable mThumb; public interface OnSeekBa ...

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

    主要是继承 AbsSeekBar 然后修改下面这些方法 onProgressRefresh() //当进度条数据更新的时候,例如我们拖动滑动条的时候,这个方法被调用 setThumbPos() //这 ...

  3. 自定义垂直拖动的seekbar进度条

    系统自定义的seekbar为横向拖动的样式,需要纵向的时则需要自己定义,网上很多说了重写系统SeekBar中onDraw()的方法,但是我使用的时候不知道为什么拖动条和点偏离了,不在一条直线上,好气. ...

  4. android 基础控件(EditView、SeekBar等)的属性及使用方法

        android提供了大量的UI控件,本文将介绍TextView.ImageView.Button.EditView.ProgressBar.SeekBar.ScrollView.WebView ...

  5. Android SeekBar 和 draw9patch 的使用

    今天要使用一个SeekBar控件,其实我觉得Android默认样式已经很不错了,无奈设计不同意,而且SeekBar左右两边也有图片,默认样式和图片也确实不协调,因此这里使用图片自定义SeekBar样式 ...

  6. android 打造不同的Seekbar

    最近项目需要用到双向的seekbar,网上找了好多野不能达到要求,偶然一次机会看到了大众点评的例子,然后我最他做了优化,并对常用的seekbar做了总结. 向上两张图: 比如双向seekbar pub ...

  7. Android中使用SeekBar拖动条实现改变图片透明度

    场景 效果 注: 博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 将布局改为Lin ...

  8. videojs文档翻译-SeekBar

    SeekBar 拖动条和进度条的容器. 使用PlayProgressBar作为其栏. 构造函数 new SeekBar(player, optionsopt) 创造此类的实例 Parameters: ...

  9. 浏览器的兼容模式下的button中文字垂直方向不居中显示

    <button style="cursor:pointer;vertical-align: middle;" >删除</button> 这时候垂直不居中. ...

随机推荐

  1. linux硬盘分区格式化及挂载

    1.硬盘的接口类型 硬盘的接口一般分为两种,一种是IDE并行接口,一种是SATA串行接口, 在linux上面IDE接口的硬盘被识别为/dev/hd[a-z]这样的设备,其中hdc表示光驱设备,这是因为 ...

  2. 基于Node的PetShop,RESTful API以及认证

    前篇 - 基本认证,用户名密码 后篇 - OAuth2 认证 由于宠物店的业务发展需要,我们需要一种更加便捷的方式来管理日益增多的宠物和客户.最好的方法就是开发一个APP,我可以用这个APP来添加.更 ...

  3. 使用Tesseract OCR识别验证码

    1.下载Tessrac OCR,默认安装 2.把验证码code.jpg图片放在D盘 3.打开cmd,进入D盘,输入:tesseract  code.jpg result 4.进入D盘,生成了resul ...

  4. UVA10339 Watching Watches

    题目大意:有两个表,每天都会慢一点时间,给出每天慢得秒数,问下一次重合的时刻. 解题思路:时刻重合也就是说整整差了一周,一周是12小时,用12小时的秒数除以两个表的相差那就是需要多少天的时间后重合,知 ...

  5. SAP ST03N工作负载的后台作业定义

    ST03N可以把SAP的运行情况的统计数据展现出来,根据这些数据可以进行性能的分析. 1.登录到000集团,定义作业SAP_COLLECTOR_FOR_PERFMONITOR,周期每个小时执行.作业内 ...

  6. .Net(C#)Parallel"循环"的解释以及与循环的比较

    Parallel 类提供对并行循环和区域的支持. 许多个人计算机和工作站都有两个或四个内核(即 CPU),使多个线程能够同时执行. 在不久的将来,计算机预期会有更多的内核. 为了利用当今和未来的硬件, ...

  7. 【Unity3D游戏开发】Application.systemLanguage无法区分简体中文和繁体中文 (二六)

    游戏发布,语言本地化需要繁体中文和简体中文 iOS8版本之前没问题,iOS9上无法正常识别这两种语言 原因是在iOS9上,Unity通过Application.systemLanguage返回的简体中 ...

  8. change the walltime for currently running PBS job (qalter pbs)

    qalter jobid -l walltime=X e.g.qalter 377470.manager -l walltime=2222:00:00qalter: Unauthorized Requ ...

  9. linux 中的快捷键

    终端快捷键 tab=补全 ctrl+a=开始位置 ctrl+e=最后位置 ctrl+k=删除此处至末尾所有内容 ctrl+u=删除此处至开始所有内容 ctrl+d=删除当前字母 ctrl+w=删除此处 ...

  10. sql 语句 嵌套子查询 执行顺序分析

    --创建测试数据create table Student(S# varchar(10),Sname nvarchar(10),Sage datetime,Ssex nvarchar(10))inser ...