【问题标题】:How to drag a rotated DragShadow?如何拖动旋转的 DragShadow?
【发布时间】:2013-06-11 17:13:00
【问题描述】:

我用 ObjectAnimator 旋转了一个 TextView,如下所示:

ObjectAnimator rotate = ObjectAnimator.ofFloat(aRotatedTextView, "rotation", 0f, someAngle);

现在,我尝试像这样在长按时拖放旋转的(!)TextView:

public boolean onLongClick(View view) {
    ClipData data = ClipData.newPlainText("DragData", (String) view.getTag());
    DragShadowBuilder dragShadowBuilder = new View.DragShadowBuilder(view);
    mDragInProgress = view.startDrag(data, dragShadowBuilder, view, 0);
    view.setVisibility(View.INVISIBLE);
    return true;
}

会发生什么是 DragShadow 是在没有旋转的情况下创建的(角度==0)。我已经看到很多我无法使用的位图示例(但不是旋转)。 有没有办法创建一个旋转的 DragShadow?

【问题讨论】:

    标签: android drag-and-drop rotation


    【解决方案1】:

    需要同样的东西。像这样实现它(也包括缩放)

    new OnTouchListener() {
        @Override
        public boolean onTouch(final View view, MotionEvent event) {
    
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
        double rotationRad = Math.toRadians(view.getRotation());
        final int w = (int) (view.getWidth() * view.getScaleX());
        final int h = (int) (view.getHeight() * view.getScaleY());
        double s = Math.abs(Math.sin(rotationRad));
        double c = Math.abs(Math.cos(rotationRad));
        final int width = (int) (w * c + h * s);
        final int height = (int) (w * s + h * c);
        DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view) {
            @Override
            public void onDrawShadow(Canvas canvas) {
                canvas.scale(view.getScaleX(), view.getScaleY(), width / 2,
                        height / 2);
                canvas.rotate(view.getRotation(), width / 2, height / 2);
                canvas.translate((width - view.getWidth()) / 2,
                        (height - view.getHeight()) / 2);
                super.onDrawShadow(canvas);
            }
    
            @Override
            public void onProvideShadowMetrics(Point shadowSize,
                    Point shadowTouchPoint) {
                shadowSize.set(width, height);
                shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
            }
        };
    
        view.startDrag(null, shadowBuilder, view, 0);
        ...
    }
    

    【讨论】:

    • +1 感谢 Virus 为我节省了宝贵的时间。出色的工作人!
    【解决方案2】:

    我自己一直在兜圈子,并没有在各种论坛上找到太多帮助。

    我的观察是,即使视图旋转,提供给阴影生成器的画布仍处于原始未旋转状态。

    我最接近正确旋转的拖动阴影是通过实现自定义阴影构建器并将被拖动视图的当前旋转传递给它。

    在 onProvideShadowMetrics(Point size, Point touch) 中,我根据当前的旋转设置了阴影尺寸,这样对于旋转的视图,就有足够的高度来绘制阴影

    在 onDrawShadow(Canvas canvas) 中,我再次考虑旋转并将画布旋转与视图相同的量。然后我让基类通过调用 super.onDrawShadow(canvas) 创建实际的阴影。旋转点与旋转实际视图时使用的点相同。

    最终结果是我有一个旋转的拖动阴影,它被部分剪裁了。看起来即使在基类中使用了画布旋转,绘图点也非常靠近画布的边缘,以至于部分阴影被剪掉了。我无法弄清楚如何调整画布,以便基类中的绘图以正确的偏移量完成以防止剪切。

    看来我最终可能会在不依赖基类的情况下自己完成所有阴影绘制。

    祝你好运。

    m.a

    更新:

    谢谢病毒。我终于重新审视了我的应用程序的这一部分,并尝试了你建议的方法,效果很好。我不能投票,因为我没有足够的积分等。

    【讨论】:

      猜你喜欢
      • 2018-02-05
      • 1970-01-01
      • 2010-12-18
      • 1970-01-01
      • 2017-09-15
      • 2015-02-04
      • 2012-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多