Frage

Ich versuche, eine vertikale Suchbarin mit dem Emulator in Gang zu bringen, aber ich stecke irgendwie fest. Ich kann den Seekbar so zeigen, wie ich es möchte, und ich kann den Fortschritt machen, um das zu tun, was ich will, und ich kann den OnTouchEvent ändern, damit der Daumen vertikal anstatt horizontal gehen kann. Ich kann den Daumen nicht dazu bringen, sich außerhalb der Standard -Horizontalpixel zu bewegen, ohne setThumboffset () zu verwenden. Dies an sich ist kein Problem. Das Problem ist die Tatsache, dass ich das Thumboffset überhaupt nicht verstehe - ich denke. Ich denke, ich könnte (richtig) das Widget ändern, was ich mir ziemlich sicher bin, dass ich nicht richtig mache. Oder vielleicht könnte ich das Thumboffset nur verwenden, wenn ich es herausfinden könnte. Da ich den Fortschritt richtig berechnen kann, dachte ich, ich würde nur eine lineare Funktion des Fortschritts verwenden * (GetTOP () - getBottom ()) des Widgets, aber das scheint es nicht zu tun. Aber ich kann nicht herausfinden, worauf der Offset dreht.

Abgesehen davon bin ich mir wirklich nicht sicher, ob das, was ich in OnSizechanged () mache, gesund ist oder ob es mich später in den Arsch beißen wird.

Hier ist das 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>

Und die Klasse (ignorieren Sie den Debugging -Müll):

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

}
War es hilfreich?

Lösung

Zum API 11 and later, Kann benutzen seekbar's XML Attribute(android:rotation="270") für vertikale Wirkung.

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

Verwenden Sie für ältere API -Ebene (Ex API10): https://github.com/androselva/vertical-seekbar-android Oder sehen Sie das Beispiel hier

Sie müssen auch die Höhe und Breite aktualisieren, wie dies von Iftikhar vorgeschlagen wird

In Ordnung

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

// nicht getestet ..

wo

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

Andere Tipps

Ich habe eine Lösung erstellt, die (zumindest für mich sowieso) funktioniert und eine vertikale Suchbarin erstellt.http://hackskrieg.wordpress.com/2012/04/20/working-ververtical-seekbar-for-android/

Dieser Code wird den Daumen korrekt ausgewählt/deaktivieren, korrekt bewegen, den Hörer korrekt aktualisieren (nur wenn sich der Fortschritt ändert!), Aktualisieren/zeichnen Sie den Fortschritt richtig usw. Ich hoffe, er hilft Ihnen.

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

Ich habe diese vertikale Suchbar gerade in einen Linearlayout mit Layout_Height auf FILL_PARENT und LAYOUT_WIDTH SET auf Wrap_Content platziert.

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

Hinweis: Sie müssen einen OnseekBarchAngelistener festlegen, ansonsten erzeugt die Interaktion mit der Seekbar NullPointerexception.

Sie können bei herunterladen http://560b.sakura.ne.jp/android/verticalslidBarexample.zip, Ich hoffe, das kann Ihnen helfen

Sich ansehen Android -Quelle . Ich denke, Sie müssen mindestens TracktouchEvent ändern, und vielleicht einige andere Orte, an denen Sie auch die X-, Y -Koordinaten austauschen müssen, um Ihre Rotation der Kontrolle zu berücksichtigen.

Könnten Sie die Seekbar als horizontal lassen, sie in ein Rahmenlayout legen und dann das Layout um 90 Grad in der Java drehen? klingt machbar ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top