Modify Android Crawler Widget to work vertically

I'm trying to get a vertical arrow coming with an emulator, but I'm kind of stuck. I can make the search bar display how I want it, and I can make progress to do what I want, and I can change onTouchEvent to make the thumb move vertically, not horizontally. What I cannot do is make my thumb move beyond the default 29 horizontal pixels without using setThumbOffset (). This in itself is not a problem. The problem comes from the fact that I donโ€™t understand thumbOffset at all - I think. I think I can (correctly) resize the widget, which I'm sure I'm wrong. Or maybe I could just use thumbOffset if I could figure it out. Since I can correctly calculate the move, I thought I was just using the linear progress function * (getTop () - getBottom ()) of the widget, but it doesn't seem to. But I canโ€™t understand what an offset is with the center around.

As a little aside, I'm really not sure what what I'm doing in onSizeChanged () is normal or if it is going to bite me in the ass later on.

Here's the main.xml layout:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.mobilsemantic.mobipoll.SlideBar android:id="@+id/slide" android:layout_width="wrap_content" android:layout_height="fill_parent" android:max="100" android:progress="0" android:secondaryProgress="25" /> <Button android:id="@+id/button" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="Hello, I am a Button" /> <TextView android:id="@+id/tracking" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> 

And the class (ignores the debugging error):

 import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.SeekBar; public class SlideBar extends SeekBar { private int oHeight = 320, oWidth = 29; private int oProgress = -1, oOffset = -1;; private float xPos = -1, yPos = -1; private int top = -1, bottom = -1, left = -1, right = -1; public SlideBar(Context context) { super(context); } public SlideBar(Context context, AttributeSet attrs) { super(context, attrs); oOffset = this.getThumbOffset(); oProgress = this.getProgress(); } public SlideBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } protected synchronized void onMeasure(int widthMeasureSpec, intheightMeasureSpec) { int height = View.MeasureSpec.getSize(heightMeasureSpec); oHeight = height; this.setMeasuredDimension(oWidth, oHeight); } protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(h, w, oldw, oldh); } protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); left = l; right = r; top = t; bottom = b; } protected void onDraw(Canvas c) { c.rotate(90); c.translate(0,-29); super.onDraw(c); } public boolean onTouchEvent(MotionEvent event) { xPos = event.getX(); yPos = event.getY(); float progress = (yPos-this.getTop())/(this.getBottom()-this.getTop()); oOffset = this.getThumbOffset(); oProgress = this.getProgress(); Log.d("offset" + System.nanoTime(), new Integer(oOffset).toString()); Log.d("progress" + System.nanoTime(), new Integer(oProgress).toString()); float offset; offset = progress * (this.getBottom()-this.getTop()); this.setThumbOffset((int)offset); Log.d("offset_postsetprogress" + System.nanoTime(), new Integer(oOffset).toString()); Log.d("progress_postsetprogress" + System.nanoTime(), new Integer(oProgress).toString()); this.setProgress((int)(100*event.getY()/this.getBottom())); return true; } } 
+17
android layout seekbar widget
Mar 10 '09 at 16:54
source share
5 answers

For API 11 and later you can use the seekbar XML attributes (android:rotation="270") for a vertical effect.

 <SeekBar android:id="@+id/seekBar1" android:layout_width="match_parent" android:layout_height="wrap_content" android:rotation="270"/> 

For an older API level (ex API10) use: https://github.com/AndroSelva/Vertical-SeekBar-Android or see a sample here

You also need to update its height and width, as Iftikhar suggests.

In order

 seekBar.setLayoutParams( new ViewGroup.LayoutParams(convertDpToPixels(1.0f,mContext), ViewGroup.LayoutParams.WRAP_CONTENT)); 

// not tested.

Where

 public static int convertDpToPixels(float dp, Context context){ Resources resources = context.getResources(); return (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, dp, resources.getDisplayMetrics() ); } 
+9
Feb 08 '15 at 18:24
source share

I created a solution that works (at least for me, anyway) and creates a vertical SeekBar. http://hackskrieg.wordpress.com/2012/04/20/working-vertical-seekbar-for-android/

This code will correctly select / deselect the thumb, move correctly, correctly update the listener (only when changing progress!), Update / correctly execute the move, etc. Hope this helps you.

 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); } 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: // Calling the super seems to help fix drawing problems super.onTouchEvent(event); int progress = getMax() - (int) (getMax() * event.getY() / getHeight()); // Ensure progress stays within boundaries of the seekbar if(progress < 0) {progress = 0;} if(progress > getMax()) {progress = getMax();} // Draw progress setProgress(progress); // Only enact listener if the progress has actually changed // Otherwise the listener gets called ~5 times per change if(progress != lastProgress) { lastProgress = progress; onChangeListener.onProgressChanged(this, progress, true); } onSizeChanged(getWidth(), getHeight() , 0, 0); onChangeListener.onProgressChanged(this, getMax() - (int) (getMax() * event.getY() / getHeight()), true); 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; } public synchronized void setProgressAndThumb(int progress) { setProgress(getMax() - (getMax()- progress)); onSizeChanged(getWidth(), getHeight() , 0, 0); } public synchronized void setMaximum(int maximum) { setMax(maximum); } public synchronized int getMaximum() { return getMax(); } } 

I simply placed this vertical SeekBar inside LinearLayout with the layout_height parameter set to FILL_PARENT and layout_width set to WRAP_CONTENT.

 <LinearLayout android:layout_width="wrap_content" android:layout_height="fill_parent" android:orientation="vertical" > <com.safetyculture.jsadroidtablet.VerticalSeekBar android:id="@+id/calculatorVerticalSeekBar" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_gravity="bottom" android:max="4" android:progress="2" /> </LinearLayout> 

NOTE. You must set OnSeekBarChangeListener, otherwise interaction with SeekBar will throw a NullPointerException.

+17
Apr 19 '12 at 10:45
source share

you can download http://560b.sakura.ne.jp/android/VerticalSlidebarExample.zip , I hope this can help you

+11
Jul 28 '10 at 3:21
source share

Check out the android source . I think you need to change at least trackTouchEvent and possibly a few other places where you also need to change the x, y coordinates to take into account your control rotation.

+2
Mar 10 '09 at 18:50
source share

Could you leave the arrow horizontal, put it in the layout of the frame, and then rotate the layout 90 degrees in java? sounds doable ...

0
Nov 06 2018-11-11T00:
source share



All Articles