Android 如何旋转TextView而不剪裁其边界?

Android 如何旋转TextView而不剪裁其边界?,android,android-canvas,Android,Android Canvas,我正在尝试使用canvas.rotate()旋转我的TextView子类: TextView是旋转的,但是我的视图的边界被剪裁: 我知道这是因为我的视图的大小——它在旋转过程中不会改变,而应该改变。但是,如果我在测量时更改中的宽度/高度问题仍然存在-我正在使用布局参数。包装内容,因此文本视图只需根据设置的测量尺寸中提供的值更改其大小即可 如何解决此问题?好的,如果无法在当前视图层次结构中旋转textView,则应在另一个层次结构中为其设置动画 创建文本视图的位图表示。使用类似于ImageVie

我正在尝试使用
canvas.rotate()
旋转我的
TextView
子类:

TextView是旋转的,但是我的视图的边界被剪裁:

我知道这是因为我的视图的大小——它在旋转过程中不会改变,而应该改变。但是,如果我在测量时更改
中的宽度/高度
问题仍然存在-我正在使用
布局参数。包装内容
,因此
文本视图
只需根据
设置的测量尺寸
中提供的值更改其大小即可


如何解决此问题?

好的,如果无法在当前视图层次结构中旋转textView,则应在另一个层次结构中为其设置动画

创建文本视图的位图表示。使用类似于ImageView的位图的支架。将imageView连接到另一个位于顶部且不会被裁剪的布局。隐藏你的文本视图。在ImageView上运行动画。动画完成后,更新textView表示,显示textView并删除ImageView

我找不到您想要的确切代码示例,但请看一看。插话地点是:

mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
mWindowManager.addView(YOUR_VIEW_WITH_ANIMATION, mWindowParams);
你可以退房 特别是它的text()方法


旋转Textview毕竟会导致调用onMeasure()方法,这是所有魔术的开始。

我认为这里的整个问题是,您使用的是WRAP\u内容。执行此操作时,视图的clip rect是文本内容的大小。解决此问题的最简单方法是使用填充。像这样的东西对我来说很好:

<com.example.twistedtext.TwistedTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="30dp"
    android:gravity="center"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    twistedtext:rotation="30.0f"
    android:text="@string/hello_world" />
剩下的唯一问题是,文本将根据旋转前的尺寸进行包装。你也得把它修好


新浪和cosA是在设置mAngle时计算的。

第一眼看到G.Blake Meike提供的解决方案是一个很好的开始,但是会出现很多问题

克服问题还有另一种方法。它非常简单,但通常不应该使用(因为我刚刚从原始android源代码中删除了一些不必要的东西)。要控制混凝土
视图的绘制
可以覆盖其父对象的
drawChild
方法(是的,您需要自己的
视图组的子类
或类似于
框架布局
的更具体的子类)。以下是我的解决方案的一个示例:

@Override
protected boolean drawChild(Canvas canvas, View child, long time) {
    //TextBaloon - is view that I'm trying to rotate
    if(!(child instanceof TextBaloon)) {
        return super.drawChild(canvas, child, time);
    }

    final int width = child.getWidth();
    final int height = child.getHeight();

    final int left = child.getLeft();
    final int top = child.getTop();
    final int right = left + width;
    final int bottom = top + height;

    int restoreTo = canvas.save();

    canvas.translate(left, top);

    invalidate(left - width, top - height, right + width, bottom + height);
    child.draw(canvas);

    canvas.restoreToCount(restoreTo);

    return true;
}

我的主要想法是将非剪裁画布授予孩子。

尝试将安卓设置为:clipChildren=false;android:clipToPadding=false;到TextView的父对象。@Leonidos旋转时会产生奇怪的瑕疵。另外,我必须剪辑一些视图,所以我不能只设置
clipChildren=false
。啊!我被抢了!那不是解决办法,那是黑客!哦,好吧,解决它很有趣。@G.BlakeMeike不完全是黑客:)这是
drawChild
method的一个要点-控制绘图。然而,你的回答最终会导致更“正确”的解决方案,所以我会给你一个赏金)非常感谢德米特里。事实证明,为了修复文本布局,您需要覆盖的方法TextView.makeNewLayout受保护,但@hide。基于新的边界,很难防止文本被重新包装。糟糕,等等,我想我刚才吐在嘴里了。因此,除非围绕中心点旋转,否则无法在不剪切图像视图的情况下旋转图像视图。一定有很好的理由,但这似乎很愚蠢。我不想覆盖onDraw、添加填充或任何其他此类愚蠢行为。来吧,Android只需旋转位图并根据需要在父视图上移动/调整大小!我想在不剪切的情况下旋转ImageView,这是唯一适合我的解决方案。太不可思议了。安卓应该更容易。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int w = getMeasuredWidth();
    int h = getMeasuredHeight();
    w = (int) Math.round(w * cosA + h * sinA);
    h = (int) Math.round(h * cosA + w * sinA);
    setMeasuredDimension(w, h);
}
@Override
protected boolean drawChild(Canvas canvas, View child, long time) {
    //TextBaloon - is view that I'm trying to rotate
    if(!(child instanceof TextBaloon)) {
        return super.drawChild(canvas, child, time);
    }

    final int width = child.getWidth();
    final int height = child.getHeight();

    final int left = child.getLeft();
    final int top = child.getTop();
    final int right = left + width;
    final int bottom = top + height;

    int restoreTo = canvas.save();

    canvas.translate(left, top);

    invalidate(left - width, top - height, right + width, bottom + height);
    child.draw(canvas);

    canvas.restoreToCount(restoreTo);

    return true;
}