vertical seekbar draw progress on thumb - android

I made vertical seekbar. Now I want to display progress on seekbar thumb. I successfully implemented this but now my text is showing below seekbar thumb. I want to draw text on top of seekbar thumb How can I achieve this? I also add my code
public class TextThumbSeekBar extends SeekBar {
public TextThumbSeekBar(Context context) {
super(context);
}
private int mThumbSize;
private TextPaint mTextPaint;
public TextThumbSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mThumbSize = 50;
mTextPaint = new TextPaint();
mTextPaint.setColor(Color.BLACK);
mTextPaint.setTextSize(50);
mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
mTextPaint.setTextAlign(Paint.Align.CENTER);
}
public TextThumbSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
mThumbSize = 50;
mTextPaint = new TextPaint();
mTextPaint.setColor(Color.BLACK);
mTextPaint.setTextSize(50);
mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
mTextPaint.setTextAlign(Paint.Align.CENTER);
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(h, w, oldh, oldw);
}
#Override
public synchronized void setProgress(int progress) // it is necessary for calling setProgress on click of a button
{
super.setProgress(progress);
onSizeChanged(getWidth(), getHeight(), 0, 0);
}
#Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
protected void onDraw(Canvas c) {
String progressText = String.valueOf(getProgress());
c.drawText(progressText, getThumb().getBounds().centerY(), getHeight() - getThumb().getBounds().centerX(), mTextPaint);
c.rotate(-90);
c.translate(-getHeight(), 0);
super.onDraw(c);
}
#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:
super.onTouchEvent(event);
setProgress(getMax() - (int) (getMax() * event.getY() / getHeight()));
onSizeChanged(getWidth(), getHeight(), 0, 0);
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
}
Here how I used this class in my xml
<demo.smart.com.smartchargeboxdemoapp.TextThumbSeekBar
android:max="100"
android:thumb="#drawable/shape_seek_bar_text_thumb"
android:layout_gravity="center"
android:id="#+id/seekbar"
android:layout_width="30dp"
android:layout_height="match_parent" />
And here's the result that I get

Although the question is old, I did in this case the thumbTint transparent and before the drawText I did 'drawRect' to draw my thumb that won't be rotated.
Hope I helped.

Related

seekbar thumb going off from seekbar, seekbar thumb misplacement

pic of wrong seekbar I am using custom vertical seekbar in a fragment, it was working fine before but suddenly it started showing wrongly. The seekbar thumb is being misplaced in some devices, in my case I am using an HTC desire which is running on API 21.
I am posting my seekbar code snippets here.
This is the xml version of the vertical seekbar
<com.sampleApp.progressbars.VerticalProgressBar
android:id="#+id/exposureSlider"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_above="#id/icBrightnessDim"
android:layout_below="#id/icBrightnessBright"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:maxWidth="50dp"
android:minHeight="50dp"
android:minWidth="50dp"
android:progressDrawable="#drawable/custom_seekbar_progress"
android:thumb="#drawable/seek_bar_thumb"
app:ssbPopupBackgroundColor="#color/grey"
app:ssbPopupEnabled="true"
app:ssbPopupHeight="80dp"
app:ssbPopupThumbColor="#color/grey"
app:ssbPopupWidth="20dp"
app:ssbThrottleEnabled="false"
app:ssbTouchAreaOffset="16dp"
/>
This is Vertical seekbar code
public class VerticalProgressBar extends android.support.v7.widget.AppCompatSeekBar {
public VerticalProgressBar(Context context) {
super(context);
}
public VerticalProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
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());
}
protected void onDraw(Canvas c) {
c.rotate(-90);
c.translate(-getHeight(), 0);
super.onDraw(c);
}
private OnSeekBarChangeListener onChangeListener;
#Override
public void setOnSeekBarChangeListener(OnSeekBarChangeListener onChangeListener){
this.onChangeListener = onChangeListener;
}
private int lastProgress = 0;
#Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
onChangeListener.onStartTrackingTouch(this);
setPressed(true);
setSelected(true);
break;
case MotionEvent.ACTION_MOVE:
super.onTouchEvent(event);
int progress = getMax() - (int) (getMax() * event.getY() / getHeight());
// Ensure progress stays within boundaries
if(progress < 0) {progress = 0;}
if(progress > getMax()) {progress = getMax();}
setProgress(progress); // Draw progress
if(progress != lastProgress) {
// Only enact listener if the progress has actually changed
lastProgress = progress;
onChangeListener.onProgressChanged(this, progress, true);
}
onSizeChanged(getWidth(), getHeight() , 0, 0);
setPressed(true);
setSelected(true);
break;
case MotionEvent.ACTION_UP:
onChangeListener.onStopTrackingTouch(this);
setPressed(false);
setSelected(false);
break;
case MotionEvent.ACTION_CANCEL:
super.onTouchEvent(event);
setPressed(false);
setSelected(false);
break;
}
return true;
}

Using a custom Vertical SeekBar, thumb highlight does not rotate with the bar

I am using a custom Vertical Seekbar and everything works great, except for the Thumb highlight.
As I scroll the left seekbar up and down, the thumb highlight continues to scroll left to right at the top of the screen as if the seekbar is still horizontal. My custom vertical seekbar is as follows:
public class VerticalSeekBar extends SeekBar {
protected OnSeekBarChangeListener changeListener;
public VerticalSeekBar(Context context) {
super(context);
}
public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
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
public synchronized void setProgress(int progress) {
super.setProgress(progress);
onSizeChanged(getWidth(), getHeight(), 0, 0);
}
#Override public void setOnSeekBarChangeListener(OnSeekBarChangeListener mListener)
{
this.changeListener = mListener;
}
protected void onDraw(Canvas c) {
c.rotate(-90);
c.translate(-getHeight(),0);
super.onDraw(c);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
setProgress(getMax() - (int) (getMax() * event.getY() / getHeight()));
if (changeListener != null)
changeListener.onStartTrackingTouch(this);
setSelected(true);
setPressed(true);
break;
case MotionEvent.ACTION_UP:
if (changeListener != null)
changeListener.onStopTrackingTouch(this);
setSelected(false);
setPressed(false);
break;
case MotionEvent.ACTION_MOVE:
int i=getMax() - (int) (getMax() * event.getY() / getHeight());
setProgress(i);
onSizeChanged(getWidth(), getHeight(), 0, 0);
if (changeListener != null)
changeListener.onProgressChanged(this, i, true);
setPressed(true);
setSelected(true);
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
}
I can eliminate the highlight entirely by removing
setSelected(true);
setPressed(true);
But ideally I want to keep the standard design pattern and have the highlight follow where the thumb is. Is there anyway to access the location and position of the highlight so I can rotate that as well?
I had the same question and came across this similar post for an answer:
Android SeekBar custom rectangle thumb visual bug
Set the Background to null. I added "setBackground(null);" to the constructor of my extended SeekBar class, but the suggested solution does this in the activity.xml file under the "SeekBar" section.

Can't update vertical seekbar programmatically (Without touching it)

I have been stuck on this problem since a long time. I left it then came back to it but so far I haven't found a working solution. Problem is simple, I have a vertical seekbar and I want to update it programmatically without touching it, but it doesn't happen. This is my vertical seekbar code
public class VerticalSeekBar extends SeekBar {
public VerticalSeekBar(Context context) {
super(context);
}
public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
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());
}
protected void onDraw(Canvas c) {
c.rotate(-90);
c.translate(-getHeight(), 0);
super.onDraw(c);
}
#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;
}
}
This is how the seekbar is declared in the xml
<com.gnr.kumar.varun.songapp.views.VerticalSeekBar
android:id="#+id/slider_1"
android:layout_width="wrap_content"
android:layout_height="200dp"
android:max="100"
android:padding="10dp"
android:progress="50"
android:progressBackgroundTint="#9cf2ec"
android:progressTint="#9cf2ec"
android:thumb="#drawable/thumb" />
I try to do things like
SeekBar sliders[] = new SeekBar[NUM_OF_SLIDERS];
sliders[0] = (SeekBar) findViewById(R.id.slider_1);
sliders[0].setProgress(100);
But it just changes the seekbar position to slightly more than 0 when in fact it should be at its maxima. No matter how big number I use instead of 100, it is the same. Can someone please help !! Thanks in advance !!!
I was finally able to solve my problem after a long time. All I had to do was to override this in Vertical Seekbar class. A comment on the accepted answer to this question helped me.
#Override public synchronized void setProgress(int progress){
super.setProgress(progress);
onSizeChanged(getWidth(), getHeight(), 0, 0);
}

Android: Draw seekbar progress from center

Hey guys I am currently working on my own Android SeekBar and I want to make the progress color to be drawn from the center of the bar to the thumb. Currently, my SeekBar class looks like this:
public class VerticalSeekBar extends SeekBar {
public VerticalSeekBar(Context context) {
super(context);
}
public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
setThumb(getResources().getDrawable(R.drawable.slidera));
setProgressDrawable(getResources().getDrawable(R.drawable.sl_bg));
}
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());
}
protected void onDraw(Canvas c) {
c.rotate(-90);
c.translate(-getHeight(), 0);
super.onDraw(c);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
[...]
My Problem now is that I don't know what method I need to override in order to change the behaviour of the drawing of the ProgressDrawable, I am sure there must be some way.
Thanks in advance
So this is now the whole class. The getRekt methods get the size of the SeekBar and the other stuff you see in the onDraw method is pretty much self-explaining. The background drawable is a drawable consisting of the color value 0x00000000 so it doesn't cover the "new" progress background.
public class VerticalSeekBar extends SeekBar {
public VerticalSeekBar(Context context) {
super(context);
}
public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
setThumb(getResources().getDrawable(R.drawable.slidera));
setThumbOffset(0);
setProgressDrawable(getResources().getDrawable(R.drawable.sl_bg));
setPadding(0,0,0,0);
}
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());
}
protected void onDraw(Canvas c) {
c.rotate(-90);
c.translate(-getHeight(), 0);
Paint paint = new Paint();
paint.setColor(0xffff7700);
paint.setStrokeWidth(11);
BlurMaskFilter blurMaskFilter=new BlurMaskFilter(15.0f,BlurMaskFilter.Blur.OUTER);
c.drawLine(
getRectX()+(getProgress()-50)*getRHeight()/100, getRectY(),getRectX(), getRectY(), paint);
paint.setMaskFilter(blurMaskFilter);
c.drawLine(
getRectX()+(getProgress()-50)*getRHeight()/100, getRectY(),getRectX(), getRectY(), paint);
drawMeter(c);
super.onDraw(c);
}
public int getRectX(){
Rect MLG= getProgressDrawable().getBounds();
return MLG.centerX();
}
public int getRectY(){
Rect MLG= getProgressDrawable().getBounds();
return MLG.centerY();
}
public int getRHeight(){
Rect MLG= getProgressDrawable().getBounds();
return MLG.width();
}
public void drawMeter(Canvas c){
Paint paint = new Paint();
paint.setColor(0xffff7700);
paint.setStrokeWidth(2);
c.drawLine(
0,100,0, 0, paint);
c.drawLine(
getRHeight()/2,100,getRHeight()/2, 0, paint);
c.drawLine(
getRHeight(),100,getRHeight(), 0, paint);
}
#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;
}
}
This should then look like this:

Android: vertical RatingBar?

How can I rotate the RatingBar?
Is there an example for a vertical custom RatingBar?
This is sample code for vertical rating bar...
public class VerticalRatingBar extends RatingBar {
private int x, y, z, w;
#Override
protected void drawableStateChanged() {
// TODO Auto-generated method stub
super.drawableStateChanged();
}
public VerticalRatingBar(Context context) {
super(context);
}
public VerticalRatingBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalRatingBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(h, w, oldh, oldw);
this.x = w;
this.y = h;
this.z = oldw;
this.w = oldh;
}
#Override
protected synchronized void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
protected void onDraw(Canvas c) {
c.rotate(-90);
c.translate(-getHeight(), 0);
super.onDraw(c);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
setSelected(true);
setPressed(true);
break;
case MotionEvent.ACTION_MOVE:
setProgress(getMax()
- (int) (getMax() * event.getY() / getHeight()));
onSizeChanged(getWidth(), getHeight(), 0, 0);
break;
case MotionEvent.ACTION_UP:
setSelected(false);
setPressed(false);
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
#Override
public synchronized void setProgress(int progress) {
if (progress >= 0)
super.setProgress(progress);
else
super.setProgress(0);
onSizeChanged(x, y, z, w);
}
}
There's a setRotation method on the view which will hopefully achieve what you're after.

Categories

Resources