当前位置: 移动技术网 > 移动技术>移动开发>Android > Android自定义垂直拖动seekbar进度条

Android自定义垂直拖动seekbar进度条

2019年07月24日  | 移动技术网移动技术  | 我要评论

android自带的seekbar是水平的,要垂直的,必须自己写一个类,继承seekbar。

一个简单的垂直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>

运行截图:

一个改进版的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;
 }

 /**
  * 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(-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);

 }

 /**
  * 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);

 }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网