Úpravě Android seekbar widgetu provozovat svisle

hlasů
17

Snažím se dostat vertikální seekbar děje s emulátorem, ale já jsem tak nějak zasekl. Můžu seekbar zobrazit tak, jak chci, aby to, a můžu dostat pokrok dělat to, co chci, a mohu upravit onTouchEvent dostat palec jít vertikálně namísto horizontálně. To, co nemohu udělat, je dostat palec pro pohyb mimo výchozí 29 pixelů ve vodorovném směru bez použití setThumbOffset (). To samo o sobě není problém. Problém přichází z toho, že mi nerozumí thumbOffset vůbec - myslím. Myslím, že bych mohl (správně) změnit velikost widgetu, což jsem si jistá, že nedělám dobře. Nebo možná bych mohl použít thumbOffset jestli bych mohl přijít. Vzhledem k tomu mohu správně vypočítat průběh Myslel jsem, že stačí použít lineární funkci pokroku * (getTop () - getBottom ()) widgetu, ale to nevypadá na to. Ale nemohu přijít na to, co posun je soustředěno kolem.

Jako poněkud stranou, jsem si opravdu jistý, jestli to, co dělám v onSizeChanged () je při smyslech, nebo pokud to bude mě kousnout do zadku později.

Tady je rozložení 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>

A třída (ignoruje ladění nevyžádané):

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

}
Položena 10/03/2009 v 17:54
zdroj uživatelem
V jiných jazycích...                            


5 odpovědí

hlasů
17

Vytvořil jsem řešení, které funguje (alespoň pro mě, tak jako tak) a vytváří vertikální SeekBar. http://hackskrieg.wordpress.com/2012/04/20/working-vertical-seekbar-for-android/

Tento kód bude správně vybrat / zrušte palec, pohybovat správně, aktualizujte posluchače správně (pouze v případě změny pokroku!), Aktualizace / nakreslit průběh správně, atd. Doufám, že to pomůže.

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

Jen jsem umístil svislé SeekBar uvnitř LinearLayout s layout_height nastaveným na FILL_PARENT a layout_width nastavena na 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>

Poznámka: Je nutné nastavit OnSeekBarChangeListener, jinak interakci s SeekBar bude vyrábět NullPointerException.

Odpovězeno 19/04/2012 v 11:45
zdroj uživatelem

hlasů
11

Zde si můžete stáhnout na http://560b.sakura.ne.jp/android/VerticalSlidebarExample.zip , doufám, že to může vám pomoci

Odpovězeno 28/07/2010 v 04:21
zdroj uživatelem

hlasů
9

U API 11 and later, lze použít seekbar's XMLatributy (android:rotation="270")pro vertikální účinek.

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

Pro starší úrovni API (ex API10), použijte: https://github.com/AndroSelva/Vertical-SeekBar-Android nebo zobrazit tuto ukázku zde

Máte také aktualizovat je výška a šířka, jak naznačují by Iftikhar

V pořádku

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

// nebyly testovány ..

kde

public static int convertDpToPixels(float dp, Context context){
    Resources resources = context.getResources();
    return (int) TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            dp, 
            resources.getDisplayMetrics()
    );
}
Odpovězeno 08/02/2015 v 18:24
zdroj uživatelem

hlasů
2

Podívejte se na android zdroje . Myslím, že je třeba změnit alespoň trackTouchEvent a tam možná i několik dalších míst, kde je také nutné zaměnit souřadnice X, Y, aby byly brány v úvahu otáčení ovládacího prvku.

Odpovězeno 10/03/2009 v 19:50
zdroj uživatelem

hlasů
0

Mohl byste opustit seekbar jako horizontální, dát to v rozložení jednotlivých snímků, otočte rozvržení 90 stupňů v Javě? Zní to proveditelné ...

Odpovězeno 06/11/2011 v 03:03
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more