文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android中怎么自定义一个垂直拖动seekbar进度条

2023-05-30 18:09

关注

Android中怎么自定义一个垂直拖动seekbar进度条,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

package com.example.helloverticalseekbar;import android.content.Context;import android.graphics.Canvas;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.SeekBar;public class VerticalSeekBar extends SeekBar{ public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {  super(context, attrs, defStyle); } 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(-getHeight(), 0);  super.onDraw(canvas); } @Override public boolean onTouchEvent(MotionEvent event) {  if (!isEnabled())  {   return false;  }  switch (event.getAction())  {   case MotionEvent.ACTION_DOWN:   case MotionEvent.ACTION_MOVE:   case MotionEvent.ACTION_UP:    setProgress(getMax()      - (int) (getMax() * event.getY() / getHeight()));    onSizeChanged(getWidth(), getHeight(), 0, 0);    break;   case MotionEvent.ACTION_CANCEL:    break;  }  return true; }}

Demo中加上一个水平SeekBar作为对比,代码如下:

Activity:

HelloSeekBarActivity

package com.example.helloverticalseekbar;import android.os.Bundle;import android.app.Activity;import android.util.Log;import android.view.Menu;import android.widget.SeekBar;import android.widget.TextView;import android.widget.SeekBar.OnSeekBarChangeListener;public class HelloSeekBarActivity extends Activity{ private SeekBar horiSeekBar = null;  private TextView horiText = null;  private VerticalSeekBar verticalSeekBar = null; private TextView verticalText = null; @Override protected void onCreate(Bundle savedInstanceState) {  Log.d(AppConstants.LOG_TAG, "onCreate");  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_hello_seek_bar);    horiSeekBar = (SeekBar) findViewById(R.id.horiSeekBar);  horiText = (TextView)findViewById(R.id.horiText);    horiSeekBar.setOnSeekBarChangeListener(horiSeekBarListener);    verticalSeekBar = (VerticalSeekBar)findViewById(R.id.verticalSeekBar);  verticalText = (TextView)findViewById(R.id.verticalText);  verticalSeekBar.setOnSeekBarChangeListener(verticalSeekBarChangeListener);      } @Override public boolean onCreateOptionsMenu(Menu menu) {  getMenuInflater().inflate(R.menu.hello_seek_bar, menu);  return true; }   private OnSeekBarChangeListener horiSeekBarListener = new OnSeekBarChangeListener() {    @Override  public void onStopTrackingTouch(SeekBar seekBar)  {     }    @Override  public void onStartTrackingTouch(SeekBar seekBar)  {     }    @Override  public void onProgressChanged(SeekBar seekBar, int progress,    boolean fromUser)  {   Log.d(AppConstants.LOG_TAG, "Horizontal SeekBar --> onProgressChanged");   horiText.setText(Integer.toString(progress));     } };  private OnSeekBarChangeListener verticalSeekBarChangeListener = new OnSeekBarChangeListener() {    @Override  public void onStopTrackingTouch(SeekBar seekBar)  {     }    @Override  public void onStartTrackingTouch(SeekBar seekBar)  {     }    @Override  public void onProgressChanged(SeekBar seekBar, int progress,    boolean fromUser)  {   Log.d(AppConstants.LOG_TAG, "Vertical SeekBar --> onProgressChanged");   verticalText.setText(Integer.toString(progress));     } };}

布局:

activity_hello_seek_bar.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".HelloSeekBarActivity" > <TextView  android:id="@+id/myTextView"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_alignParentTop="true"  android:text="@string/hello_world" /> <SeekBar  android:id="@+id/horiSeekBar"  android:layout_width="match_parent"  android:layout_height="20dp"  android:layout_below="@id/myTextView" /> <TextView  android:id="@+id/horiText"  android:layout_width="wrap_content"  android:layout_height="20dp"  android:layout_below="@id/horiSeekBar"  android:text="horizontal" /> <com.example.helloverticalseekbar.VerticalSeekBar  android:id="@+id/verticalSeekBar"  android:layout_width="wrap_content"  android:layout_height="200dp"  android:layout_below="@id/horiText" /> <TextView  android:id="@+id/verticalText"  android:layout_width="wrap_content"  android:layout_height="20dp"  android:layout_below="@id/verticalSeekBar"  android:text="vertical" /></RelativeLayout>

运行截图:

Android中怎么自定义一个垂直拖动seekbar进度条

一个改进版的SeekBar

package com.example.helloverticalseekbarv2;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{ 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; }  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(-getHeight(), 0);  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);     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)     {      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 = 0.0f;  }  else if (y < top)  {   scale = 1.0f;  }  else  {   scale = (float) (available - y + top) / (float) available;   progress = mTouchProgressOffset;  }  final int max = getMax();  progress += scale * max;  setProgress((int) progress); }  void onStartTrackingTouch() {  mIsDragging = true; }  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); }}

关于Android中怎么自定义一个垂直拖动seekbar进度条问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯