如何在Android

时间:2018-03-29 16:41:49

标签: android touch

场合
我给自己写了一个自定义视图。它基本上是一个进度条,可以一次显示2个进度(例如视频的缓冲时间和播放时间)。我还希望用户与它进行交互(例如设置视频的时间)。但在这里我遇到了一个问题

问题
这种互动已经实施,理论上也很好。但在实际部分中,android对用户触摸和滑动的位置不够准确,无法正常工作。

红点表示我的手指在哪里。酒吧应该跟随手指的移动。但是你可以看到它并没有安静地到达现场。

enter image description here
enter image description here

问题
有没有办法在组件上接收用户手指的准确位置?

我的组件
有趣的东西发生在方法initListener()

public final class ProgressBarView extends View {

  /* Values */
  private double progressBackground = 0;
  private double progressForeground = 0;
  private boolean inputEnabled = true;
  private boolean paused;
  private final List<ProgressChangeListener> listenerPool = new ArrayList<>();

  /* UI */
  private final Paint colorOutlineBar = new Paint();
  private final Paint colorBackgroundBar = new Paint();
  private final Paint colorBackgroundProgress = new Paint();
  private final Paint colorForegroundProgress = new Paint();

  private final Paint colorOutlineIndicator = new Paint();
  private final Paint colorBackgroundIndicator = new Paint();

  private final int barRounding;
  private final int barOutlineThickness;
  private final int indicatorRadius;
  private final int indicatorOutlineThickness;

  public ProgressBarView(Context pContext, AttributeSet pAttributes) {
    super(pContext, pAttributes);
    colorOutlineBar.setColor(getColor(pAttributes, R.styleable.ProgressBarView_colorOutlineBar, R.color.black));
    colorBackgroundBar.setColor(getColor(pAttributes, R.styleable.ProgressBarView_colorBackgroundBar, R.color.dark_grey));
    colorBackgroundProgress.setColor(getColor(pAttributes, R.styleable.ProgressBarView_colorBackgroundProgress, R.color.light_gray));
    colorForegroundProgress.setColor(getColor(pAttributes, R.styleable.ProgressBarView_colorForegroundProgress, R.color.white));
    colorOutlineIndicator.setColor(getColor(pAttributes, R.styleable.ProgressBarView_colorOutlineIndicator, R.color.black));
    colorBackgroundIndicator.setColor(getColor(pAttributes, R.styleable.ProgressBarView_colorBackgroundIndicator, R.color.white));

    barRounding = getIntegerValue(pAttributes, R.styleable.ProgressBarView_barRounding, 10);
    barOutlineThickness = getIntegerValue(pAttributes, R.styleable.ProgressBarView_barOutlineThickness, 4);
    indicatorRadius = getIntegerValue(pAttributes, R.styleable.ProgressBarView_indicatorRadius, 10);
    indicatorOutlineThickness = getIntegerValue(pAttributes, R.styleable.ProgressBarView_indicatorOutlineThickness, 4);

    initListener();
  }

  public interface ProgressChangeListener {

    public void onPause(ProgressBarView pView);

    public void onResume(ProgressBarView pView);

  }

  public final List<ProgressChangeListener> getListenerPool() {
    return listenerPool;
  }

 /* *JUST A BUNCH OF GETTERS AND SETTERS FOR THE FIELDS ABOVE* */

@Override
  protected final void onDraw(final Canvas pCanvas) {
    final RectF barOutline = new RectF(indicatorRadius, 0, getWidth() - indicatorRadius, getHeight());
    final RectF barBackground = new RectF(indicatorRadius + barOutlineThickness, barOutlineThickness, getWidth() - indicatorRadius - barOutlineThickness, getHeight() - barOutlineThickness);
    final RectF barProgressBackground = new RectF(indicatorRadius + barOutlineThickness, barOutlineThickness, getPositionForProgress(progressBackground), getHeight() - barOutlineThickness);
    final RectF barProgressForeground = new RectF(indicatorRadius + barOutlineThickness, barOutlineThickness, getPositionForProgress(progressForeground), getHeight() - barOutlineThickness);

    pCanvas.drawRoundRect(barOutline, barRounding, barRounding, colorOutlineBar);
    pCanvas.drawRoundRect(barBackground, barRounding, barRounding, colorBackgroundBar);
    pCanvas.drawRoundRect(barProgressBackground, barRounding, barRounding, colorBackgroundProgress);
    pCanvas.drawRoundRect(barProgressForeground, barRounding, barRounding, colorForegroundProgress);

    final int x = getPositionForProgress(progressForeground);
    final int y = getHeight() / 2;
    pCanvas.drawCircle(x, y, indicatorRadius, colorOutlineIndicator);
    pCanvas.drawCircle(x, y, indicatorRadius - indicatorOutlineThickness, colorBackgroundIndicator);


    invalidate();
  }

  private void initListener() {
    setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if (inputEnabled) {
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        postAsyncPause();
                        return true;
                    case MotionEvent.ACTION_UP: {
                        float x = motionEvent.getX() * motionEvent.getXPrecision();
                        progressForeground = x / (getWidth() - indicatorRadius * 2) * 100;
                        postAsyncResume();
                        return true;
                    }
                    case MotionEvent.ACTION_MOVE: {
                        float x = motionEvent.getX() * motionEvent.getXPrecision();
                        progressForeground = x / (getWidth() - indicatorRadius * 2) * 100;
                        return true;
                    }
                    default:
                        break;
                }
            }
            return false;
        }
    });
  }

  private final void postAsyncPause() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            for (ProgressChangeListener listener : listenerPool) {
                listener.onPause(ProgressBarView.this);
            }
        }
    }).start();
  }

  private final void postAsyncResume() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            for (ProgressChangeListener listener : listenerPool) {
                listener.onResume(ProgressBarView.this);
            }
        }
    }).start();
  }

  private final int getColor(final AttributeSet pAttributes, final int pAttributeId, final int pColorId) {
    final TypedArray a = getContext().obtainStyledAttributes(pAttributes, R.styleable.ProgressBarView);
    int color = a.getColor(pAttributeId, -1);
    a.recycle();
    if (color == -1) {
        color = getResources().getColor(pColorId);
    }
    return color;
  }

  private final int getIntegerValue(AttributeSet pAttributes, int pAttributeId, int pDefaultValue) {
    final TypedArray a = getContext().obtainStyledAttributes(pAttributes, R.styleable.ProgressBarView);
    int color = a.getInteger(pAttributeId, -1);
    a.recycle();
    if (color == -1) {
        return pDefaultValue;
    }
    return color;
    }


  private final int getPositionForProgress(double pPercentage) {
    int barWidth = getWidth() - barOutlineThickness - 2 * indicatorRadius;
    if (pPercentage >= 100) {
        return barWidth;
    } else if (pPercentage <= 0) {
        return indicatorRadius;
    }
    return (int) (barWidth / 100 * pPercentage);
  }

}

0 个答案:

没有答案