سؤال

أنا أحاول الحصول على عمودي seekbar الذهاب مع المحاكي, ولكن أنا نوع من عالقة.يمكنني الحصول على seekbar إلى عرض الطريق الذي أريده ، وأنا أستطيع أن تقدم على فعل ما أريد تعديل onTouchEvent للحصول على الإبهام الذهاب عموديا بدلا من أفقيا.ما لا أستطيع القيام به هو الحصول على الإبهام إلى التحرك خارج الافتراضي 29 بكسل أفقي دون استخدام setThumbOffset().هذا في في حد ذاته ليس مشكلة.المشكلة تأتي من حقيقة أن أنا لا أفهم thumbOffset في جميع أظن.أعتقد أن (صحيح) حجم القطعة التي أنا متأكد من أنني لم أفعل الصواب.أو ربما مجرد استخدام thumbOffset إذا أنا يمكن أن الرقم بها.منذ أستطيع أن حساب التقدم بشكل صحيح اعتقدت أن مجرد استخدام الخطية وظيفة تقدم * (getTop() - getBottom()) من القطعة ولكن هذا لا يبدو أن تفعل ذلك.ولكن أنا لا يمكن معرفة ما يقابلها هو تتمحور حول.

بوصفها جانبا إلى حد ما, أنا حقا غير متأكد ما إذا كان ما أفعله في onSizeChanged() هو عاقل أو إذا كان الذهاب إلى لدغة لي في الحمار في وقت لاحق على.

هنا 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>

وفئة (تجاهل التصحيح غير المرغوب فيه):

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

}
هل كانت مفيدة؟

المحلول

بالنسبة API 11 and later, يمكن استخدام seekbar's XML سمات(android:rotation="270") الرأسي تأثير.

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

لكبار السن من مستوى API (السابق API10),استخدام: https://github.com/AndroSelva/Vertical-SeekBar-Android أو ترى هذا عينة هنا

عليك أيضا أن التحديث هو الطول و العرض كما اقترح من قبل افتخار

في

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

//لم يختبر..

حيث

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

نصائح أخرى

ولقد خلق الحل الذي يعمل (على الأقل بالنسبة لي، على أي حال) ويخلق SeekBar عمودي. http://hackskrieg.wordpress.com/2012/04/20/working -vertical-seekbar مقابل الروبوت /

وهذا الرمز سوف تختار بشكل صحيح / إلغاء الإبهام، التحرك بشكل صحيح، قم بتحديث المستمع بشكل صحيح (فقط عندما يتغير التقدم!)، وتحديث / رسم التقدم بشكل صحيح، وما إلى ذلك وآمل أن يساعدك.

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

وأنا فقط وضعت هذا SeekBar عمودي داخل LinearLayout مع layout_height المقرر أن FILL_PARENT وlayout_width المقرر أن 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>

ملحوظة: يجب تعيين لOnSeekBarChangeListener، والتفاعل خلاف مع SeekBar سوف تنتج NullPointerException

ويمكنك تحميل على http://560b.sakura.ne.jp/android /VerticalSlidebarExample.zip ، و آمل أن يكون هذا قد يمكن أن تساعدك

ونلقي نظرة على الموقع المصدر الروبوت . أعتقد أنك بحاجة إلى تغيير ما لا يقل عن trackTouchEvent وربما هناك بعض الأماكن الأخرى حيث كنت في حاجة أيضا لمبادلة س، ص ينسق أن تأخذ في الاعتبار دوران الخاص بك من السيطرة عليها.

هل يمكن أن تترك seekbar كما الأفقي، ووضعها في تخطيط الإطار، ثم تناوب على تخطيط 90 درجة في جافا؟ يبدو قابلة للتنفيذ ...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top