Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android和SeekBar-Prevent';拇指';从触摸SeekBar时移动到拖动/滚动屏幕_Android_Seekbar - Fatal编程技术网

Android和SeekBar-Prevent';拇指';从触摸SeekBar时移动到拖动/滚动屏幕

Android和SeekBar-Prevent';拇指';从触摸SeekBar时移动到拖动/滚动屏幕,android,seekbar,Android,Seekbar,我有一个android应用程序,它有一个表格布局,每一行都有一个SeekBar和一个ToggleButton。这些行超出了屏幕的可见范围,因此可以滚动。当我触摸并拖动页面向上滚动,并在此过程中触摸SeekBar时,它会立即改变“拇指”的位置,而不是滚动页面。但是,ToggleButton的行为不是这样的;相反,我可以开始拖动按钮并滚动,然后释放,而无需切换按钮更改状态 <declare-styleable name="SeekBarEx"> <attr name="min"

我有一个android应用程序,它有一个表格布局,每一行都有一个SeekBar和一个ToggleButton。这些行超出了屏幕的可见范围,因此可以滚动。当我触摸并拖动页面向上滚动,并在此过程中触摸SeekBar时,它会立即改变“拇指”的位置,而不是滚动页面。但是,ToggleButton的行为不是这样的;相反,我可以开始拖动按钮并滚动,然后释放,而无需切换按钮更改状态

<declare-styleable name="SeekBarEx">

<attr name="min" format="float"/>
<attr name="max" format="float"/>
<attr name="value" format="float"/>
</declare-styleable>

</resources>

有没有办法让SeekBar以这种方式运行,这样触摸它开始拖动不会导致工具栏改变位置,而是滚动页面?

我通过对SeekBar进行子类化并检查运动角度是否大于45度来实现它。在这种情况下,忽略触摸并返回false,这样滚动视图就可以完成它的工作

<declare-styleable name="SeekBarEx">

<attr name="min" format="float"/>
<attr name="max" format="float"/>
<attr name="value" format="float"/>
</declare-styleable>

</resources>
编辑:

<declare-styleable name="SeekBarEx">

<attr name="min" format="float"/>
<attr name="max" format="float"/>
<attr name="value" format="float"/>
</declare-styleable>

</resources>
这是一个扩展的SeekBar,允许您在浮点而不是整数中设置最小/最大值

public class SeekBarEx extends SeekBar implements
        SeekBar.OnSeekBarChangeListener {
    final int SEEK_POINTS = 0x10000;
    final String TAG = "SeekBarEx";
    public float mMax;
    public float mMin;
    public OnSeekBarExChangeListener delegate = null;

    public interface OnSeekBarExChangeListener {
        public void onSeekChanged(SeekBarEx seekBarEx, float value,
                boolean fromUser);

        public void onStartTrackingTouch(SeekBarEx seekBar);

        public void onStopTrackingTouch(SeekBarEx seekBar);
    }

    public SeekBarEx(Context ctx, AttributeSet attr) {
        super(ctx, attr);

        super.setMax(SEEK_POINTS);

        mMin = 0f;
        mMax = 1.0f;
        initAttributes(attr);
        this.setOnSeekBarChangeListener(this);
    }

    public void setDelegate(OnSeekBarExChangeListener d) {
        delegate = d;
    }


    public void initAttributes(AttributeSet attrSet) {
        TypedArray a;
        a = getContext().obtainStyledAttributes(attrSet, R.styleable.SeekBarEx);

        final int N = a.getIndexCount();

        int i;
        for (i = 0; i < N; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
            case R.styleable.SeekBarEx_max:
                mMax = a.getFloat(i, 1.0f);
                Log.d(TAG, "maxSet " + mMax);
                break;
            case R.styleable.SeekBarEx_min:
                mMin = a.getFloat(i, 0f);
                Log.d(TAG, "minSet" + mMin);
                break;
            case R.styleable.SeekBarEx_value:
                this.setValue(a.getFloat(i, 0));
                break;
            }
        }

        a.recycle();

    }

    @Override
    public int getProgress() {
        return super.getProgress();
    }

    public float getValue() {
        float r;
        float run;
        r = (float) super.getProgress();
        r = r / (float) SEEK_POINTS;
        run = mMax - mMin;
        r = r * run + mMin;
        return r;
    }

    public void setValue(float v) {
        if (Float.isNaN(v) || Float.isInfinite(v))
            return;
        if (v > mMax)
            v = mMax;
        if (v < mMin)
            v = mMin;
        float run;
        int setv;
        run = mMax - mMin;
        v -= mMin;
        setv = Math.round(v * (float) SEEK_POINTS / run);
        super.setProgress(setv);
    }

    public boolean valueChanged = false;

    public void cancelTracking() {
        if (oldValue != Float.NaN) {
            this.setValue(oldValue);
            oldValue = Float.NaN;
            valueChanged = false;
            acceptTouches = false;
            acceptChange = false;
        }
    }

    // we override these methods so that when we forcully cancel
    // on ontouches moved. We can revert back to the old value
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress,
            boolean fromUser) {
        Log.d(TAG, "SeekBar changed to " + progress);
        if (delegate != null && acceptTouches) {
            valueChanged = true;
            delegate.onSeekChanged(this, this.getValue(), fromUser);
        } else
            cancelTracking();
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        if (delegate != null)
            delegate.onStartTrackingTouch(this);
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        if (delegate != null && valueChanged)
            delegate.onStopTrackingTouch(this);
        else
            cancelTracking();
        acceptChange = false;
        valueChanged = false;
    }

    public float mY, mX;
    public boolean acceptTouches = true;
    // acceptChange never read todo: delete
    public boolean acceptChange = false;
    public float oldValue = Float.NaN;

    public ScrollView getScrollView() {
        View view;
        view = this;
        int maxUp;
        maxUp = 5;
        while (view != null && maxUp > 0) {
            view = (View) view.getParent();
            ScrollView scroller;
            if (view instanceof ScrollView) {
                scroller = (ScrollView) view;
                return scroller;
            }
            maxUp--;
        }
        return null;
    }
    // **************************************
    // This is the important part in achieving the effect in scroll
    // view to be nice
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action;
        action = event.getAction() & MotionEvent.ACTION_MASK;
        ScrollView scroller = this.getScrollView();
        boolean mayScroll;

        mayScroll = true;
        if (scroller == null)
            mayScroll = false;
        else {
            int scrollAmount = scroller.getMaxScrollAmount();
            if (scrollAmount == 0)
                mayScroll = false;
        }
        switch (action) {
        case MotionEvent.ACTION_CANCEL:
            Log.d(TAG, "got cancel touches");
            cancelTracking();
            super.onTouchEvent(event);
            return true;
        case MotionEvent.ACTION_DOWN:
            mX = event.getX();
            mY = event.getY();
            acceptTouches = true;
            acceptChange = false;
            oldValue = this.getValue();
            valueChanged = false;
            break;
        case MotionEvent.ACTION_MOVE:
            float x;
            float y;
            x = event.getX();
            y = event.getY();
            float dx;
            float dy;
            dx = x - mX;
            dy = y - mY;
            if (dx < 0)
                dx = -dx;
            if (dy < 0)
                dy = -dy;

            y = this.getHeight() / 2 - y;
            float angle;
            float distance;
            distance = dx * dx + dy * dy;
            // I just realized this is wrong it should be
            // angle = (float)Math.acos(Math.abs(dx)/Math.sqrt(distance))
            // I'm leaving it until tested or someone can confirm
            angle = (float) Math.atan(dy / dx);
            int distanceLimit;
            distanceLimit = this.getHeight() / 3;
            distanceLimit *= distanceLimit;
            // if we move at an angle of atleast 45degrees
            // cancel
            if (mayScroll && angle > Math.PI / 4.0) {
                cancelTracking();
            }

            mX += 100000;
            if (y < 0)
                y = -y;
            // if we moved finger too far just cancel
            // cause the person may have wanted to scroll but
            // failed so we revert back to the old value
            if (y > this.getHeight() * 2) {
                cancelTracking();
            } else if (acceptTouches)
                acceptChange = true;
            break;
        default:
            break;
        }
        // if we accept touches do the usual otherwise
        // return false so scrollView can do it's thing
        if (acceptTouches)
            return super.onTouchEvent(event);
        return false;
    }

}
<declare-styleable name="SeekBarEx">

<attr name="min" format="float"/>
<attr name="max" format="float"/>
<attr name="value" format="float"/>
</declare-styleable>

</resources>
public类SeekBarEx扩展SeekBar实现
SeekBar.onseekbarchaneglistener{
最终整数搜索点=0x10000;
最后一个字符串标记=“SeekBarEx”;
公共浮动mMax;
公众浮点数;
public OnSeekBarExChangeListener委托=null;
SeekbareXchangeListener上的公共接口{
SeekChanged上的公共无效(SeekBarEx SeekBarEx,浮动值,
布尔值(用户);
开始跟踪触摸时的公共无效(SeekBarEx seekBar);
TopTrackingTouch(SeekBarEx seekBar)上的公共无效;
}
公共SeekBarEx(上下文ctx,属性集attr){
超级(ctx、attr);
super.setMax(搜索点);
mMin=0f;
mMax=1.0f;
初始属性(attr);
this.setonseekbarchaneglistener(this);
}
public void setDelegate(onseekbarexchanged侦听器){
代表=d;
}
public void initAttributes(AttributeSet attreset){
Darray a型;
a=getContext().ActainStyledAttributes(attrSet,R.styleable.SeekBarEx);
final int N=a.getIndexCount();
int i;
对于(i=0;imMax)
v=mMax;
if(v0){
view=(view)view.getParent();
滚动视图滚动条;
如果(滚动视图的视图实例){
滚动器=(滚动视图)视图;
返回滚动条;
}
马克斯普--;
}
返回null;
}
// **************************************
//这是实现滚动效果的重要部分
//景色宜人
@凌驾
公共布尔onTouchEvent(运动事件){
内联作用;
action=event.getAction()&MotionEvent.action\u掩码;
ScrollView scroller=this.getScrollView();
布尔卷轴;
maycoll=true;
如果(滚动条==null)
maycoll=false;
否则{
int scrollmount=scroller.getMaxScrollmount();
如果(滚动量==0)
maycoll=false;
}
开关(动作){
case MotionEvent.ACTION\u取消:
Log.d(标记“got cancel t