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

2023-12-07

我在我的应用程序中使用范围搜索栏。它工作正常,但我的要求是设置两个拇指之间的范围。默认情况下,两个拇指相互重叠,在我的情况下,拇指不相互重叠。

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

下面是我的范围搜索栏类。在我的例子中,两个拇指之间的差异是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, 0, 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, getSelectedMinValue(), 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, boolean pressed, Canvas canvas)
    {
            canvas.drawBitmap(pressed ? thumbPressedImage : thumbPressedImage, screenCoord - thumbHalfWidth, (float) ((0.5f * getHeight()) - thumbHalfHeight), 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.min(1d, 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");
            }
    }}

enter image description here

编辑: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并看到如何在 RangeSeekBar 中拖动时禁用拇指部分。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • gradle更新后无法找到方法(无法编译项目)

    我尝试将项目中的 gradle 版本更新为 4 1 milestone 1 以下这些说明 https developer android com studio build gradle plugin 3 0 0 migration html
  • android edittext中的字符映射

    我想让我的编辑文本就像我写字符 g 时一样 它是相关的映射自定义字符应该写成印地语中的 我认为应该有字符映射 但没有知识任何人都可以帮助我 怎么做 其他应用程序https play google com store apps details
  • 如何获取每个StorageVolume的可用大小和总大小?

    背景 谷歌 悲伤 计划破坏存储权限 https www xda developers com android q storage access framework scoped storage 这样应用程序将无法使用标准文件 API 和文件
  • Android短音的正确播放方法?

    我正在创建一个应用程序 屏幕上将有多个图像 这些图像将是按钮 点击时会播放短促的声音 我对此进行了研究 只能找到我当前用来播放声音的方法 这似乎根本没有响应 我希望声音能够快速播放并且能够响应多次快速点击 我不确定这在 Android 中是
  • Android Studio:XML 布局中的“包装在容器中”

    编辑 XML 布局文件时 Eclipse 有一项称为 包裹在容器中 的功能 重新格式化 gt Android gt 可让您选择一个或多个视图并在其周围包裹您选择的布局 Android Studio中有类似的东西吗 目前正在实施中 问题 69
  • 按下按钮时应用不同的样式

    有没有办法在按下按钮时将样式应用于按钮 如果我有一种风格样式 xml
  • Android WebView里面的ScrollView只滚动scrollview

    在我的应用程序中 我有一个 ScrollView 其中包含一些线性视图 一些文本视图和一个 Webview 然后是其他线性布局等 问题是 WebView 不滚动 Scroll 仅侦听 ScrollView 有什么建议么
  • 自定义首选项中的android首选项水平分隔线?

    我创建了自己的自定义首选项对象来扩展首选项 我创建它们只是因为这些自定义数据类型没有首选项 一切正常 但我的自定义首选项没有相同的外观 因为它们缺少系统首选项对象具有的水平分隔线 我已经查找了创建水平分隔线的代码 但我找不到它是在哪里完成的
  • 如何更改终端的默认目录?

    我想更改 Android Studio v2 2 2 终端的默认目录 当我打开终端时 它基于项目的目录 C 项目路径 我经常需要使用adb shell 所以我必须导航到 SDK 路径 平台工具 才能使用 adb 命令 是否可以更改终端的默认
  • java.lang.IllegalStateException:应用程序 PagerAdapter 更改了适配器的内容,而没有调用 PagerAdapter#notifyDataSetChanged android

    我正在尝试使用静态类将值传递给视图 而不是使用意图 因为我必须传递大量数据 有时我会收到此错误 但无法找出主要原因是什么 Error java lang IllegalStateException The application s Pag
  • 图像作为电子邮件附件

    我想构建一个应用程序 我可以在电子邮件中附加图像 打开图像并将其设置为我的壁纸 我想让它跨平台 所以你能告诉我是否可以使用phonegap 或者我是否必须为iphone和android构建一个本机应用程序 您好 如果您只想通过电子邮件附加图
  • Android 中如何通过彩信发送图片?

    我正在开发多媒体应用程序 我正在通过相机捕获一张图像 并希望将该图像和文本发送到其他号码 但我不知道如何通过彩信发送图像 MMS 只是一个 http post 请求 您应该使用执行请求额外的网络功能 final ConnectivityMa
  • 使用 AsyncTask 传递值

    我一直在努力解决这个问题 但我已经到了不知道该怎么办的地步 我想做的是使用一个类下载文件并将其解析为字符串 然后将该字符串发送到另一个类来解析 JSON 内容 所有部件都可以单独工作 并且我已经单独测试了所有部件 我只是不知道如何将值发送到
  • Android 2.3 模拟器在更新位置时崩溃

    我正在使用 Eclipse 编写和调试 Android 应用程序 我需要做的事情之一是更新设备的位置 因此我尝试使用模拟器控制窗口中的位置控制面板 在 手动 选项卡上 我选择 十进制 输入有效的纬度和经度 然后单击 发送 不幸的是 接下来发
  • Dagger 2 没有生成我的组件类

    我正在使用 Dagger 2 创建我的依赖注入 几个小时前它还在工作 但现在不再生成组件 这是我创建组件的地方 public class App extends Application CacheComponent mCacheCompon
  • 在 Samsung Galaxy S5 Android 5.0 上使用 MediaPlayer 加载音频流需要超过 10 秒

    由于更新至 Android 5 0 MediaPlayer 在 Samsung Galaxy S5 上无法正常工作 启动音频流后加载时间超过 10 秒 示例代码 MediaPlayer mPlayer new MediaPlayer Str
  • 通过系统应用程序以编程方式静默安装 apk(无需 root)

    我有带有 android sharedUserId android uid system UID 1000 的系统级应用程序 设备未root INSTALL PACKAGES 权限包含在清单中 我可以静默安装下载的 apk 吗 我已经发现这
  • CamcorderProfile.videoCodec 返回错误值

    根据docs https developer android com reference android media CamcorderProfile html 您可以使用CamcorderProfile获取设备默认视频编解码格式 然后将其
  • 我的应用程序中的后退按钮出现问题[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我想在手机关闭时清除共享首选项值 你
  • Dagger 2 中“HasFragmentInjector”的实际用法是什么

    我之前已经实现了 dagger2 v2 2 但现在他们也添加了 dagger android 部分 所以我正在用它创建示例项目 我知道旧的方法论 Provide and Modules and 成分等注释 但从 Dagger 2 8 开始

随机推荐

  • Android 中的共享偏好设置

    我是安卓开发新手 我有一项活动 其中需要用户名和密码 我将这些值传递给一个 Web 服务 该服务返回一个密钥作为响应 我的活动中有一个切换按钮 现在 如果用户检查切换按钮 则意味着他想保持登录状态 并且当用户下次登录时应将其重定向到下一个活
  • 在 SSO 身份验证后设置 FormsAuthentication

    我的 ASP NET MVC 4 应用程序通过在 IIS 上运行的 ISAPI 筛选器受 SSO OAM 保护 当收到对我的应用程序的请求时 ISAPI 过滤器会拦截该请求并将其重定向到 SSO 用户必须登录 SSO 然后返回到我的应用程序
  • 实时视频流 iPhone

    我是 iphone 和 Objective c 的新手 我想向使用我的应用程序的用户展示一场现场比赛 假设是足球比赛 在 iPhone 应用程序中进行实时视频流需要什么 任何有关这方面的信息表示赞赏 Thanks 请大家帮忙 有人以前一定做
  • 如何在REST中实现资源的复制粘贴?

    您将如何以 RESTful 方式实现复制粘贴支持 假设我有书店资源 还有每家商店里的书 http mydomain com rest book stores 1 http mydomain com rest book stores 1 bo
  • 如何使用 Hive 使用单个 hdfs 路径创建 n 个外部表

    是否可以使用 Hive 创建 n 个指向单个 hdfs 路径的外部表 如果是的话 其优点和局限性是什么 可以在 HDFS 中的同一位置上创建许多表 同时管理和外部表 在相同数据之上创建具有完全相同架构的表根本没有用 但是您可以创建具有不同列
  • 在实体框架上使用 linq c# 进行分组

    我需要按名称分组并对名称的所有实例求和 这是我在控制器中的代码 public class FansController Controller private dbFan db new dbFan public ActionResult In
  • 为什么我们不能使用进程 ID 来代替我们绑定的端口

    为什么我们不能使用进程ID来代替我们在套接字编程中绑定的端口 在套接字编程中 我们创建套接字并获取套接字描述符 然后绑定到特定端口 对于多个连接 为什么我们不使用进程ID 因为所有连接也是返回进程ID的进程 这是一个有趣的想法 但我认为它会
  • 使用 utf8 的 MySQL 全文搜索(波斯语/阿拉伯语)

    我在 UTF8 Unicode 波斯语 阿拉伯语上进行全文搜索时遇到问题 从查询中找不到任何内容 表在编码上使用 utf8 utf8 persian ci 设置 Using mysql query SET NAMES UTF8 用于 Uni
  • Xamarin Forms 列表视图在框架中显示行项目

    您能给我推荐一些示例代码来创建如图所示的框架线吗 正如您在图像中看到的 例如对于第一行 M 应位于一个框架中 而该行中的所有其他 3 个项目应位于另一行中 下面请查看我的代码 感谢任何帮助
  • 如何隐藏平板电脑中的系统导航栏?

    在我的平板电脑上 它有以下栏来控制后退 主页等 我不知道正确的名称 状态栏 控制栏 操作栏 或其他 在程序中 它使用以下方法来实现全屏 requestWindowFeature Window FEATURE NO TITLE getWind
  • 如何将 Excel 工作表导出到新工作簿

    我有一堆包含多个工作表的 Excel 工作簿 我想循环遍历每个工作簿并将每个工作表导出到它自己的新工作簿中 我想要每个新工作簿中都有一个工作表 这是我到目前为止所得到的 Sub ExportWorksheet ByVal worksheet
  • C++ 在 Windows 中发送简单信号

    Windows 上是否有相当于kill 的函数 int kill pid t pid int sig 如果没有 是否可以根据进程的 PID 来测试进程是否正在运行 Thanks Windows 没有 Unix 意义上的信号 您可以使用Ope
  • 构建财务报表数据库

    我正在寻找构建数据库的最佳方法 我有 1000 家公司从 1997 年到 2012 年的季度财务报表 每家公司都有三份不同的报表 损益表 资产负债表和现金流量表 我希望能够对数据执行计算 例如将每个季度相加以获得每个报表上每个行项目的年度总
  • 十六进制字符串转中文字符串

    我有以下代码可以从十六进制转换为 ASCII Hexadecimal to ASCII Convertion private static string hex2ascii string hexString MessageBox Show
  • 如何将模板参数限制为指针或随机访问迭代器?

    有没有办法将模板函数的参数类型限制为仅指针或随机访问迭代器 假设我正在开发一个排序功能 该功能仅适用于可随机访问的容器 我正在寻找一种在用户传递非随机访问迭代器时抛出编译时错误的方法 include
  • 简单的 HTML DOM 空间到类中

    我正在使用简单的 HTML DOM 从网站获取元素 但是当类属性有空格时 我什么也得不到 源 HTML 来自betaexplorer com table class stats table stats main table 2 tbody
  • 如何限制 Spring MVC 控制器的 @RequestMapping 路径中​​的路由扩展?

    我有一个相当简单的任务想要完成 但似乎无法找到有关 Spring MVC 路由的信息 我有一个非常简单的控制器 它将路径路由到视图 Controller RequestMapping value help public class Help
  • SQL Server 2005 db_denydatawriter 示例查询

    我正在尝试将 mydomain myuser 添加到 db denydatawriter 角色 但我可以找到一个简单的查询示例 有人有一个简单的示例吗 如果您还没有设置登录名 用户 只需 3 个步骤 CREATE LOGIN mydomai
  • Bootstrap 元素 100% 宽度

    我想创建交替的 100 彩色块 附件中说明了 理想 情况以及当前情况 所需的设置 现在 我的第一个想法是创建一个 div 类 给它一个背景颜色 并给它 100 的宽度 block width 100 background fff 然而 你可
  • 如何在android中的范围搜索栏中设置两个拇指之间的范围?

    我在我的应用程序中使用范围搜索栏 它工作正常 但我的要求是设置两个拇指之间的范围 默认情况下 两个拇指相互重叠 在我的情况下 拇指不相互重叠 如何设置范围搜索栏中两个拇指之间的范围 下面是我的范围搜索栏类 在我的例子中 两个拇指之间的差异是