如何在android中的范围搜索栏中设置两个拇指之间的范围?

如何在android中的范围搜索栏中设置两个拇指之间的范围?,第1张

概述我在我的应用程序中使用范围搜索栏.它工作正常但我的要求是设置两个拇指之间的范围.默认情况下,两个拇指在我的情况下相互重叠拇指彼此不重叠. 如何在范围搜索条中设置两个拇指之间的范围? 下面是我的范围搜索栏类.在我的情况下,两个拇指之间的差异是3.如果两个拇指差异是3,拇指是不能重叠的.如何设置拇指之间的范围? 这是我用过的课程 public class RangeSeekBar<T extends 我在我的应用程序中使用范围搜索栏.它工作正常但我的要求是设置两个拇指之间的范围.默认情况下,两个拇指在我的情况下相互重叠拇指彼此不重叠.

如何在范围搜索条中设置两个拇指之间的范围?

下面是我的范围搜索栏类.在我的情况下,两个拇指之间的差异是3.如果两个拇指差异是3,拇指是不能重叠的.如何设置拇指之间的范围?

这是我用过的课程

public class RangeSeekbar<T extends Number> extends ImageVIEw {    private final Paint paint = new Paint(Paint.ANTI_AliAS_FLAG);    private final Bitmap thumbImage = BitmapFactory.decodeResource(getResources(),R.drawable.seekcircle_blue);    private final Bitmap thumbpressedImage = BitmapFactory.decodeResource(getResources(),R.drawable.seekcircle_red);    private final float thumbWIDth = thumbImage.getWIDth();    private final float thumbHalfWIDth = 0.5f * thumbWIDth;    private final float thumbHalfheight = 0.5f * thumbImage.getHeight();    private final float lineHeight = 0.8f * thumbHalfheight;    private final float padding = thumbHalfWIDth;    private final T absoluteMinValue,absoluteMaxValue;    private final NumberType numberType;    private final double absoluteMinValuePrim,absoluteMaxValuePrim;    private double normalizedMinValue = 0d;    private double normalizedMaxValue = 1d;    private Thumb pressedThumb = null;    private boolean notifyWhileDragging = false;    private OnRangeSeekbarchangelistener<T> Listener;    /**     * Default color of a {@link RangeSeekbar},#FF33B5E5. This is also kNown as "Ice Cream SanDWich" blue.     */    public static final int DEFAulT_color = color.argb(0xFF,0);    /**     * An invalID pointer ID.     */    public static final int INVALID_POINTER_ID = 255;    // Localized constants from MotionEvent for compatibility    // with API < 8 "Froyo".    public static final int ACTION_POINTER_UP = 0x6,ACTION_POINTER_INDEX_MASK = 0x0000ff00,ACTION_POINTER_INDEX_SHIFT = 8;    private float mDownMotionX;    private int mActivePointerID = INVALID_POINTER_ID;    /**     * On touch,this offset plus the scaled value from the position of the touch will form the progress value. Usually 0.     */    float mtouchProgressOffset;    private int mScaledtouchSlop;    private boolean mIsDragging;    /**     * Creates a new RangeSeekbar.     *      * @param absoluteMinValue     *            The minimum value of the selectable range.     * @param absoluteMaxValue     *            The maximum value of the selectable range.     * @param context     * @throws IllegalArgumentException     *             Will be thrown if min/max value type is not one of Long,Double,Integer,float,Short,Byte or BigDecimal.     */    public RangeSeekbar(T absoluteMinValue,T absoluteMaxValue,Context context) throws IllegalArgumentException {            super(context);            this.absoluteMinValue = absoluteMinValue;            this.absoluteMaxValue = absoluteMaxValue;            absoluteMinValuePrim = absoluteMinValue.doubleValue();            absoluteMaxValuePrim = absoluteMaxValue.doubleValue();            numberType = NumberType.fromNumber(absoluteMinValue);            // make RangeSeekbar focusable. This solves focus handling issues in case EditText Widgets are being used along with the RangeSeekbar within ScollVIEws.            setFocusable(true);            setFocusableIntouchMode(true);            init();    }    private final voID init() {            mScaledtouchSlop = VIEwConfiguration.get(getContext()).getScaledtouchSlop();    }    public boolean isnotifyWhileDragging() {            return notifyWhileDragging;    }    /**     * Should the Widget notify the Listener callback while the user is still dragging a thumb? Default is false.     *      * @param flag     */    public voID setNotifyWhileDragging(boolean flag) {            this.notifyWhileDragging = flag;    }    /**     * Returns the absolute minimum value of the range that has been set at construction time.     *      * @return The absolute minimum value of the range.     */    public T getabsoluteMinValue() {            return absoluteMinValue;    }    /**     * Returns the absolute maximum value of the range that has been set at construction time.     *      * @return The absolute maximum value of the range.     */    public T getabsoluteMaxValue() {            return absoluteMaxValue;    }    /**     * Returns the currently selected min value.     *      * @return The currently selected min value.     */    public T getSelectedMinValue() {            return normalizedTovalue(normalizedMinValue);    }    /**     * Sets the currently selected minimum value. The Widget will be invalIDated and redrawn.     *      * @param value     *            The Number value to set the minimum value to. Will be clamped to given absolute minimum/maximum range.     */    public voID setSelectedMinValue(T value) {            // in case absoluteMinValue == absoluteMaxValue,avoID division by zero when normalizing.            if (0 == (absoluteMaxValuePrim - absoluteMinValuePrim)) {                    setnormalizedMinValue(0d);            }            else {                    setnormalizedMinValue(valuetonormalized(value));            }    }    /**     * Returns the currently selected max value.     *      * @return The currently selected max value.     */    public T getSelectedMaxValue() {            return normalizedTovalue(normalizedMaxValue);    }    /**     * Sets the currently selected maximum value. The Widget will be invalIDated and redrawn.     *      * @param value     *            The Number value to set the maximum value to. Will be clamped to given absolute minimum/maximum range.     */    public voID setSelectedMaxValue(T value) {            // in case absoluteMinValue == absoluteMaxValue,avoID division by zero when normalizing.            if (0 == (absoluteMaxValuePrim - absoluteMinValuePrim)) {                    setnormalizedMaxValue(1d);            }            else {                    setnormalizedMaxValue(valuetonormalized(value));            }    }    /**     * Registers given Listener callback to notify about changed selected values.     *      * @param Listener     *            The Listener to notify about changed selected values.     */    public voID setonRangeSeekbarchangelistener(OnRangeSeekbarchangelistener<T> Listener) {            this.Listener = Listener;    }    /**     * Handles thumb selection and movement. NotifIEs Listener callback on certain events.     */    @OverrIDe    public boolean ontouchEvent(MotionEvent event) {            if (!isEnabled())                    return false;            int pointerIndex;            final int action = event.getAction();            switch (action & MotionEvent.ACTION_MASK) {            case MotionEvent.ACTION_DOWN:                    // Remember where the motion event started                    mActivePointerID = event.getPointerID(event.getPointerCount() - 1);                    pointerIndex = event.findPointerIndex(mActivePointerID);                    mDownMotionX = event.getX(pointerIndex);                    pressedThumb = evalpressedThumb(mDownMotionX);                    // Only handle thumb presses.                    if (pressedThumb == null)                            return super.ontouchEvent(event);                    setpressed(true);                    invalIDate();                    onStartTrackingtouch();                    tracktouchEvent(event);                    attemptClaimDrag();                    break;            case MotionEvent.ACTION_MOVE:                    if (pressedThumb != null) {                            if (mIsDragging) {                                    tracktouchEvent(event);                            }                            else {                                    // Scroll to follow the motion event                                    pointerIndex = event.findPointerIndex(mActivePointerID);                                    final float x = event.getX(pointerIndex);                                    if (Math.abs(x - mDownMotionX) > mScaledtouchSlop) {                                            setpressed(true);                                            invalIDate();                                            onStartTrackingtouch();                                            tracktouchEvent(event);                                            attemptClaimDrag();                                    }                            }                            if (Listener != null) {                                    Listener.onRangeSeekbarValuesChanged(this,getSelectedMinValue(),getSelectedMaxValue());                            }                    }                    break;            case MotionEvent.ACTION_UP:                    if (mIsDragging) {                            tracktouchEvent(event);                            onStopTrackingtouch();                            setpressed(false);                    }                    else {                            // touch up when we never crossed the touch slop threshold                            // should be interpreted as a tap-seek to that location.                            onStartTrackingtouch();                            tracktouchEvent(event);                            onStopTrackingtouch();                    }                    pressedThumb = null;                    invalIDate();                    if (Listener != null) {                            Listener.onRangeSeekbarValuesChanged(this,getSelectedMaxValue());                    }                    break;            case MotionEvent.ACTION_POINTER_DOWN: {                    final int index = event.getPointerCount() - 1;                    // final int index = ev.getActionIndex();                    mDownMotionX = event.getX(index);                    mActivePointerID = event.getPointerID(index);                    invalIDate();                    break;            }            case MotionEvent.ACTION_POINTER_UP:                    onSecondaryPointerUp(event);                    invalIDate();                    break;            case MotionEvent.ACTION_CANCEL:                    if (mIsDragging) {                            onStopTrackingtouch();                            setpressed(false);                    }                    invalIDate(); // see above explanation                    break;            }            return true;    }    private final voID onSecondaryPointerUp(MotionEvent ev) {            final int pointerIndex = (ev.getAction() & ACTION_POINTER_INDEX_MASK) >> ACTION_POINTER_INDEX_SHIFT;            final int pointerID = ev.getPointerID(pointerIndex);            if (pointerID == mActivePointerID) {                    // This was our active pointer going up. Choose                    // a new active pointer and adjust accordingly.                    // Todo: Make this decision more intelligent.                    final int newPointerIndex = pointerIndex == 0 ? 1 : 0;                    mDownMotionX = ev.getX(newPointerIndex);                    mActivePointerID = ev.getPointerID(newPointerIndex);            }    }    private final voID tracktouchEvent(MotionEvent event) {            final int pointerIndex = event.findPointerIndex(mActivePointerID);            final float x = event.getX(pointerIndex);            if (Thumb.MIN.equals(pressedThumb)) {                    setnormalizedMinValue(screenTonormalized(x));            }            else if (Thumb.MAX.equals(pressedThumb)) {                    setnormalizedMaxValue(screenTonormalized(x));            }    }    /**     * TrIEs to claim the user's drag motion,and requests disallowing any ancestors from stealing events in the drag.     */    private voID attemptClaimDrag() {            if (getParent() != null) {                    getParent().requestdisallowIntercepttouchEvent(true);            }    }    /**     * This is called when the user has started touching this Widget.     */    voID onStartTrackingtouch() {            mIsDragging = true;    }    /**     * This is called when the user either releases his touch or the touch is canceled.     */    voID onStopTrackingtouch() {            mIsDragging = false;    }    /**     * Ensures correct size of the Widget.     */    @OverrIDe    protected synchronized voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) {            int wIDth = 200;            if (MeasureSpec.UnspecIFIED != MeasureSpec.getMode(wIDthMeasureSpec)) {                    wIDth = MeasureSpec.getSize(wIDthMeasureSpec);            }            int height = thumbImage.getHeight();            if (MeasureSpec.UnspecIFIED != MeasureSpec.getMode(heightmeasureSpec)) {                    height = Math.min(height,MeasureSpec.getSize(heightmeasureSpec));            }            setMeasuredDimension(wIDth,height);    }    /**     * Draws the Widget on the given canvas.     */    @OverrIDe    protected synchronized voID onDraw(Canvas canvas) {            super.onDraw(canvas);            // draw seek bar background line            final RectF rect = new RectF(padding,0.5f * (getHeight() - lineHeight),getWIDth() - padding,0.5f * (getHeight() + lineHeight));            paint.setStyle(Style.FILL);            paint.setcolor(color.GRAY);            paint.setAntiAlias(true);            canvas.drawRect(rect,paint);            // draw seek bar active range line            rect.left = normalizedToScreen(normalizedMinValue);            rect.right = normalizedToScreen(normalizedMaxValue);            // orange color            paint.setcolor(DEFAulT_color);            canvas.drawRect(rect,paint);            // draw minimum thumb            drawThumb(normalizedToScreen(normalizedMinValue),Thumb.MIN.equals(pressedThumb),canvas);            // draw maximum thumb            drawThumb_max(normalizedToScreen(normalizedMaxValue),Thumb.MAX.equals(pressedThumb),canvas);    }    /**     * OverrIDden to save instance state when device orIEntation changes. This method is called automatically if you assign an ID to the RangeSeekbar Widget using the {@link #setID(int)} method. Other members of this class than the normalized min and max values don't need to be saved.     */    @OverrIDe    protected Parcelable onSaveInstanceState() {            final Bundle bundle = new Bundle();            bundle.putParcelable("SUPER",super.onSaveInstanceState());            bundle.putDouble("MIN",normalizedMinValue);            bundle.putDouble("MAX",normalizedMaxValue);            return bundle;    }    /**     * OverrIDden to restore instance state when device orIEntation changes. This method is called automatically if you assign an ID to the RangeSeekbar Widget using the {@link #setID(int)} method.     */    @OverrIDe    protected voID onRestoreInstanceState(Parcelable parcel) {            final Bundle bundle = (Bundle) parcel;            super.onRestoreInstanceState(bundle.getParcelable("SUPER"));            normalizedMinValue = bundle.getDouble("MIN");            normalizedMaxValue = bundle.getDouble("MAX");    }    /**     * Draws the "normal" resp. "pressed" thumb image on specifIEd x-coordinate.     *      * @param screenCoord     *            The x-coordinate in screen space where to draw the image.     * @param pressed     *            Is the thumb currently in "pressed" state?     * @param canvas     *            The canvas to draw upon.     */    private voID drawThumb(float screenCoord,boolean pressed,Canvas canvas) {            canvas.drawBitmap(pressed ? thumbImage : thumbImage,screenCoord - thumbHalfWIDth,(float) ((0.5f * getHeight()) - thumbHalfheight),paint);    }    private voID drawThumb_max(float screenCoord,Canvas canvas)    {            canvas.drawBitmap(pressed ? thumbpressedImage : thumbpressedImage,paint);    }    /**     * DecIDes which (if any) thumb is touched by the given x-coordinate.     *      * @param touchX     *            The x-coordinate of a touch event in screen space.     * @return The pressed thumb or null if none has been touched.     */    private Thumb evalpressedThumb(float touchX) {            Thumb result = null;            boolean minThumbpressed = isInThumbRange(touchX,normalizedMinValue);            boolean maxThumbpressed = isInThumbRange(touchX,normalizedMaxValue);            if (minThumbpressed && maxThumbpressed) {                    // if both thumbs are pressed (they lIE on top of each other),choose the one with more room to drag. this avoIDs "stalling" the thumbs in a corner,not being able to drag them apart anymore.                    result = (touchX / getWIDth() > 0.5f) ? Thumb.MIN : Thumb.MAX;            }            else if (minThumbpressed) {                    result = Thumb.MIN;            }            else if (maxThumbpressed) {                    result = Thumb.MAX;            }            return result;    }    /**     * DecIDes if given x-coordinate in screen space needs to be interpreted as "within" the normalized thumb x-coordinate.     *      * @param touchX     *            The x-coordinate in screen space to check.     * @param normalizedThumbValue     *            The normalized x-coordinate of the thumb to check.     * @return true if x-coordinate is in thumb range,false otherwise.     */    private boolean isInThumbRange(float touchX,double normalizedThumbValue) {            return Math.abs(touchX - normalizedToScreen(normalizedThumbValue)) <= thumbHalfWIDth;    }    /**     * Sets normalized min value to value so that 0 <= value <= normalized max value <= 1. The VIEw will get invalIDated when calling this method.     *      * @param value     *            The new normalized min value to set.     */    public voID setnormalizedMinValue(double value) {            normalizedMinValue = Math.max(0d,Math.min(1d,Math.min(value,normalizedMaxValue)));            invalIDate();    }    /**     * Sets normalized max value to value so that 0 <= normalized min value <= value <= 1. The VIEw will get invalIDated when calling this method.     *      * @param value     *            The new normalized max value to set.     */    public voID setnormalizedMaxValue(double value) {            normalizedMaxValue = Math.max(0d,Math.max(value,normalizedMinValue)));            invalIDate();    }    /**     * Converts a normalized value to a Number object in the value space between absolute minimum and maximum.     *      * @param normalized     * @return     */    @SuppressWarnings("unchecked")    private T normalizedTovalue(double normalized) {            return (T) numberType.toNumber(absoluteMinValuePrim + normalized * (absoluteMaxValuePrim - absoluteMinValuePrim));    }    /**     * Converts the given Number value to a normalized double.     *      * @param value     *            The Number value to normalize.     * @return The normalized double.     */    private double valuetonormalized(T value) {            if (0 == absoluteMaxValuePrim - absoluteMinValuePrim) {                    // prevent division by zero,simply return 0.                    return 0d;            }            return (value.doubleValue() - absoluteMinValuePrim) / (absoluteMaxValuePrim - absoluteMinValuePrim);    }    /**     * Converts a normalized value into screen space.     *      * @param normalizedCoord     *            The normalized value to convert.     * @return The converted value in screen space.     */    private float normalizedToScreen(double normalizedCoord) {            return (float) (padding + normalizedCoord * (getWIDth() - 2 * padding));    }    /**     * Converts screen space x-coordinates into normalized values.     *      * @param screenCoord     *            The x-coordinate in screen space to convert.     * @return The normalized value.     */    private double screenTonormalized(float screenCoord) {            int wIDth = getWIDth();            if (wIDth <= 2 * padding) {                    // prevent division by zero,simply return 0.                    return 0d;            }            else {                    double result = (screenCoord - padding) / (wIDth - 2 * padding);                    return Math.min(1d,Math.max(0d,result));            }    }    /**     * Callback Listener interface to notify about changed range values.     *      * @author Stephan Tittel ([email protected])     *      * @param <T>     *            The Number type the RangeSeekbar has been declared with.     */    public interface OnRangeSeekbarchangelistener<T> {            public voID onRangeSeekbarValuesChanged(RangeSeekbar<?> bar,T minValue,T maxValue);    }    /**     * Thumb constants (min and max).     */    private static enum Thumb {            MIN,MAX    };    /**     * Utility enumaration used to convert between Numbers and doubles.     *      * @author Stephan Tittel ([email protected])     *      */    private static enum NumberType {            LONG,DOUBLE,INTEGER,float,SHORT,BYTE,BIG_DECIMAL;            public static <E extends Number> NumberType fromNumber(E value) throws IllegalArgumentException {                    if (value instanceof Long) {                            return LONG;                    }                    if (value instanceof Double) {                            return DOUBLE;                    }                    if (value instanceof Integer) {                            return INTEGER;                    }                    if (value instanceof float) {                            return float;                    }                    if (value instanceof Short) {                            return SHORT;                    }                    if (value instanceof Byte) {                            return BYTE;                    }                    if (value instanceof BigDecimal) {                            return BIG_DECIMAL;                    }                    throw new IllegalArgumentException("Number class '" + value.getClass().getname() + "' is not supported");            }            public Number toNumber(double value) {                    switch (this) {                    case LONG:                            return new Long((long) value);                    case DOUBLE:                            return value;                    case INTEGER:                            return new Integer((int) value);                    case float:                            return new float(value);                    case SHORT:                            return new Short((short) value);                    case BYTE:                            return new Byte((byte) value);                    case BIG_DECIMAL:                            return new BigDecimal(value);                    }                    throw new InstantiationError("can't convert " + this + " to a Number object");            }    }}

编辑:java类代码

// create RangeSeekbar as Integer range between 20 and 75    final RangeSeekbar<Integer> seekbar = new RangeSeekbar<Integer>(0,35,this);    seekbar.setSelectedMinValue(5);   seekbar.setSelectedMaxValue(8);    seekbar.setonRangeSeekbarchangelistener(new RangeSeekbar.OnRangeSeekbarchangelistener<Integer>() {            @OverrIDe            public voID onRangeSeekbarValuesChanged(RangeSeekbar<?> bar,Integer minValue,Integer maxValue) {                    // handle changed range values                    Log.i(TAG,"User selected new range values: MIN=" + minValue + ",MAX=" + maxValue);                int diff=maxValue-minValue;                if(diff==4)                {                }            }    });    // add RangeSeekbar to pre-defined layout    VIEwGroup layout = (VIEwGroup) findVIEwByID(R.ID.layout);    layout.addVIEw(seekbar);
解决方法 当差异为4时,用于停止拇指的运动.您可以使用

if(diff==4) {    bar.setEnabled(false);}

为了更清楚,请转到我们的blog并查看如何在RangedSeekbar部分中拖动时禁用拇指.

总结

以上是内存溢出为你收集整理的如何在android中的范围搜索栏中设置两个拇指之间的范围?全部内容,希望文章能够帮你解决如何在android中的范围搜索栏中设置两个拇指之间的范围?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1128033.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-30
下一篇 2022-05-30

发表评论

登录后才能评论

评论列表(0条)

保存