Domanda

Sto cercando di ottenere una barra di ricerca verticale con l'emulatore, ma lo sono una specie di bloccato. Posso ottenere la barra di ricerca per visualizzare il modo in cui lo voglio, e posso ottenere i progressi per fare quello che voglio e posso modificare il onTouchEvent per spostare il pollice in verticale anziché orizzontalmente. Quello che non posso fare è spostare il pollice fuori dal 29 pixel orizzontali predefiniti senza usare setThumbOffset (). Questo dentro di per sé non è un problema. Il problema deriva dal fatto che io non capisco affatto il thumbOffset - immagino. Penso che potrei (correttamente) ridimensionare il file widget, che sono abbastanza sicuro di non fare bene. O forse potrei basta usare il thumbOffset se riuscissi a capirlo. Da quando posso calcolare i progressi in modo corretto Ho pensato che avrei usato solo un lineare funzione di avanzamento * (getTop () - getBottom ()) del widget ma quello non sembra farlo. Ma non riesco a capire quale sia l'offset centrato intorno.

A parte questo, non sono davvero sicuro di cosa sto facendo onSizeChanged () è sano o se mi morderà nel culo più tardi on.

Ecco il layout 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>

E la classe (ignora la spazzatura di debug):

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

}
È stato utile?

Soluzione

Per API 11 e successive , puoi usare gli attributi XML di seekbar (android: rotazione = " 270 ") per effetto verticale.

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

Per il livello API precedente (ex API10), utilizzare: https://github.com/ AndroSelva / Vertical-SeekBar-Android o guarda questo esempio qui

  

Devi anche aggiornare la sua altezza e amp; larghezza come suggerito da Iftikhar

In ordine

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

// non hanno testato ..

dove

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

Altri suggerimenti

Ho creato una soluzione che funziona (almeno per me, comunque) e crea un SeekBar verticale. http://hackskrieg.wordpress.com/2012/04/20/working -Verticale-SeekBar-for-android /

Questo codice seleziona / deseleziona correttamente il pollice, si sposta correttamente, aggiorna l'ascoltatore correttamente (solo quando i progressi cambiano!), aggiorna / disegna i progressi correttamente, ecc. Spero che ti aiuti.

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

Ho appena inserito questo SeekBar verticale all'interno di un LinearLayout con layout_height impostato su FILL_PARENT e layout_width impostato su 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: è necessario impostare un OnSeekBarChangeListener, altrimenti l'interazione con SeekBar produrrà NullPointerException.

puoi scaricare da http://560b.sakura.ne.jp/android /VerticalSlidebarExample.zip , spero che ciò possa aiutarti

Dai un'occhiata a sorgente android . Penso che devi cambiare almeno trackTouchEvent e forse ci sono alcuni altri posti in cui devi anche scambiare le coordinate x, y per tenere conto della rotazione del controllo.

Potresti lasciare la barra di ricerca in orizzontale, metterla in un layout a cornice, quindi ruotare il layout di 90 gradi in Java? sembra fattibile ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top