10

TextViewを使用してサブクラスをローテーションしようとしていcanvas.rotate()ます:

canvas.save();

final int w = getWidth();
final int h = getHeight();

float px = w/2f;
float py = h/2f;
canvas.rotate(mAngle, px, py);

super.draw(canvas);

canvas.restore();

TextView は回転していますが、ビューの境界が切り取られています:

図

これは私のビューのサイズが原因であることを理解しています-回転中に変更されるべきですが、変更されません。しかし、幅\高さを変更してもonMeasure問題は残ります-私はを使用してLayoutParams.WRAP_CONTENTいるので、TextViewで提供される値に従ってサイズを変更するだけsetMeasuredDimensionsです

どうすればこの問題を解決できますか?

4

4 に答える 4

4

ここでの全体的な問題は、WRAP_CONTENT を使用していることだと思います。ビューのクリップ四角形は、それを行うと、テキスト コンテンツのサイズになります。この問題を解決する最も簡単な方法は、パディングを使用することです。このようなものは、私にとってはうまくいきます:

<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" />

もちろん、このようにすると、コンテンツごとに少し異なるパディングを選択する必要があります。それができない場合は、onMeasure をオーバーライドして、TextView の onMeasure とまったく同じように処理し、必要に応じて回転に対応するパディングを追加します。

後で追加: 実際、これを理解するのはちょっと楽しかったです。私は次の onMeasure を持っています。これはかなりうまく機能します。

@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);
}

残っている唯一の問題は、回転前の寸法に従ってテキストが折り返されることです。それも直さねば…。

mAngle が設定されると、sinA と cosA が計算されます。

于 2013-01-20T16:46:39.690 に答える
2

現在のビュー階層で textView を回転できない場合は、別のビュー階層でアニメーション化する必要があります。

textView のビットマップ表現を作成します。ImageView のようなこのビットマップのホルダーを使用します。imageView を、上部にある別のレイアウトに接続し、トリミングされない場所に接続します。textView を非表示にします。ImageView でアニメーションを実行します。アニメーションが終了したら、textView 表現を更新し、textView を表示して、ImageView を削除します。

あなたが望むものの正確なコード例を見つけることはできませんが、これを見てください。交差する場所は次のとおりです。

mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
mWindowManager.addView(YOUR_VIEW_WITH_ANIMATION, mWindowParams);
于 2013-01-20T15:03:14.283 に答える
2

G. Blake Meike によって提供された最初の解決策は、開始するのに適した方法ですが、多くの問題が発生します。

問題を克服するには別の方法があります。これは非常に単純ですが、通常は使用しないでください (元の Android ソースから不要なものを削除したため)。コンクリートの描画を制御するには、その親のメソッドをViewオーバーライドできます(はい、の独自のサブクラスまたは のようなより具体的なものが必要です)。これが私の解決策の例です:drawChildViewGroupFrameLayout

@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;
}

主なアイデアは、クリップされていないキャンバスを子に付与することです。

于 2013-01-21T13:31:07.573 に答える
1

https://github.com/grantland/android-autofittextview 特にその refitText() メソッドを確認できます。

Textview を回転すると、すべての魔法が始まる onMeasure() メソッドが呼び出されます。

于 2013-01-20T15:25:01.693 に答える