Pregunta

Estoy tratando de obtener una barra de búsqueda vertical con el emulador, pero estoy algo atascado. Puedo hacer que la barra de búsqueda se muestre como yo quiero, y puedo obtener el progreso para hacer lo que quiero, y puedo modificar el onTouchEvent para que el pulgar vaya verticalmente en lugar de horizontalmente. Lo que no puedo hacer es mover el pulgar fuera del predeterminado 29 píxeles horizontales sin usar setThumbOffset (). Esta en en sí mismo no es un problema. El problema viene del hecho de que yo no entiendo el thumbOffset en absoluto, supongo. Creo que podría (correctamente) cambiar el tamaño del widget, que estoy bastante seguro de que no estoy haciendo lo correcto. O tal vez podría solo use el thumbOffset si pudiera resolverlo. Ya que puedo calcular el progreso correctamente pensé que solo usaría un lineal función de progreso * (getTop () - getBottom ()) del widget pero eso no parece hacerlo Pero no puedo entender cuál es el desplazamiento centrado alrededor.

Como algo aparte, no estoy muy seguro de lo que estoy haciendo en onSizeChanged () está cuerdo o si me va a morder el culo más tarde en.

Aquí está el diseño main.xml:

<?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>

Y la clase (ignore la basura de depuración):

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;
        }

}
¿Fue útil?

Solución

Para API 11 y posterior , puede usar los atributos XML de barra de búsqueda (android: rotación = " 270 ") para efectos verticales.

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

Para el nivel de API anterior (ex API10), use: https://github.com/ AndroSelva / Vertical-SeekBar-Android o vea esta muestra aquí

  

También debe actualizar su altura & amp; ancho sugerido por Iftikhar

En orden

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

// no he probado ..

donde

public static int convertDpToPixels(float dp, Context context){
    Resources resources = context.getResources();
    return (int) TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            dp, 
            resources.getDisplayMetrics()
    );
}

Otros consejos

He creado una solución que funciona (al menos para mí, de todos modos) y crea un SeekBar vertical. http://hackskrieg.wordpress.com/2012/04/20/working -vertical-seekbar-for-android /

Este código seleccionará / deseleccionará correctamente el pulgar, se moverá correctamente, actualizará el oyente correctamente (¡solo cuando el progreso cambie!), actualizará / dibujará el progreso correctamente, etc. Espero que lo ayude.

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();
}
}

Acabo de colocar este SeekBar vertical dentro de un LinearLayout con layout_height establecido en FILL_PARENT y layout_width establecido en 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>

NOTA: debe establecer un OnSeekBarChangeListener, de lo contrario, interactuar con SeekBar producirá NullPointerException.

puede descargar en http://560b.sakura.ne.jp/android /VerticalSlidebarExample.zip , espero que esto pueda ayudarte

Eche un vistazo a fuente de Android . Creo que debe cambiar al menos trackTouchEvent y tal vez haya algunos otros lugares donde también deba intercambiar las coordenadas x, y para tener en cuenta su rotación del control.

¿Podría dejar la barra de búsqueda como horizontal, colocarla en un diseño de marco y luego rotar el diseño 90 grados en Java? suena factible ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top