【问题标题】:How do a create a landscape version of my view without actually being in landscape mode?如何在不实际处于横向模式的情况下创建我的视图的横向版本?
【发布时间】:2011-05-04 09:34:39
【问题描述】:

我正在尝试制作一个固定为纵向模式的视图控制器,但它有一个可以“淡入”顶部的横向版本。这意味着我需要能够拥有一个适合横向尺寸的屏幕版本,并且可以旋转 90 度(或 270 度,视情况而定)。在 iPhone 上这很容易,但我在 Android 上苦苦挣扎。我有一个自定义视图,其中包含我想要旋转的视图,但我似乎无法正确调整子视图的大小,或者让旋转正确排列。有没有更简单的方法?或者,我在这里做错了什么?

@Override
protected void onDraw(Canvas canvas) {
    if (getChildCount() == 1) {
        canvas.save();
        canvas.rotate(90, canvas.getWidth() / 2, canvas.getHeight() / 2); 
        // I have no idea what my pivot point should be

        View child  = getChildAt(0);

        Bitmap bitmap = // bitmap of child
        Paint paint = new Paint();
        canvas.drawBitmap(bitmap, 0, 0, paint);

        canvas.restore();
    }
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    if (getChildCount() == 1) {
        View child  = getChildAt(0);
        child.layout(top, left, bottom, right);
    }
}

建议实际更改视图控制器的方向是没有帮助的。我需要它保持纵向模式,以便以部分 Alpha 透明度同时显示纵向版本。

明确地说,我需要能够与旋转坐标中的视图交互,所以我需要能够按下按钮、使用滚动视图等。

【问题讨论】:

  • 您能否添加一个 iphone 屏幕截图,显示您尝试复制的行为?
  • 我必须给你一个文字截图。 :) 考虑以纵向模式显示的一页文本。现在考虑横向模式下的一页文本。现在将它们放在一起,您可以看到横向模式文本隐约覆盖在纵向模式文本的顶部。这就是我所追求的,而且是有原因的,它只是不涉及问题本身。 :)

标签: android rotation


【解决方案1】:

API 级别 11 为 Views 引入了 setRotationX/Y,这似乎正是您想要的。

假设 Honeycomb 不是您的目标 API 版本,这是我在玩了几个小时后发现的(肯定比我当前的项目更具挑战性!):

  1. 渲染当然是可行的(而且相对容易)
  2. 这是一次大规模的黑客攻击,您一开始就不应该这样做

基本上,主要问题不是渲染而是处理事件。由于 Android 不知道视图是横向的(您只是以这种方式渲染它),因此视图将响应由原始预旋转坐标界定的区域。因此,没有点击(好吧,除非你有一个方形按钮,只有侧面的文字!)。

真的,您可能应该考虑向后移植 Honeycomb 更改。

话虽如此,并有一个很大的免责声明,即在许多情况下这可能不起作用,这里有一个示例应用:

package com.side; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.os.Bundle; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.RelativeLayout; import android.widget.RelativeLayout.LayoutParams; import android.widget.TextView; public class TestActivity extends Activity { private class SidewaysGroup extends ViewGroup{ public SidewaysGroup(Context context) { super(context); } @Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { Log.i("Sideways", "Parent size: " + getWidth() + "x" + getHeight() + ", child size: " + child.getWidth() + "x" + child.getHeight()); // Create a new canvas for the child (there's probably a way to use the original canvas but I couldn't figure out the transformations) Canvas childCanvas = new Canvas(); Bitmap childBitmap = Bitmap.createBitmap(child.getWidth(), child.getHeight(), Bitmap.Config.ARGB_8888); childCanvas.setBitmap(childBitmap); boolean ret = super.drawChild(childCanvas, child, drawingTime); Matrix matrix = new Matrix(); // rotate at the bottom left corner matrix.postRotate(90f, 0, childBitmap.getHeight()); // after the rotation we are one `height` further down than we should be matrix.postTranslate(0, -childBitmap.getHeight()); canvas.drawBitmap(childBitmap, matrix, new Paint()); return ret; } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { if(changed && getChildCount()==1) { final View child = getChildAt(0); // This is breaking the flow (measuring would be done twice) - should be moved to onMeasure or measure() itself // notice that it inverts the dimensions child.measure(MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec( getMeasuredWidth(), MeasureSpec.AT_MOST)); child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight()); } } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView verticalView = new TextView(this); verticalView.setText("This is the vertical text"); verticalView.setGravity(Gravity.CENTER); verticalView.setTextSize(50f); verticalView.setTextColor(Color.parseColor("#88ffffff")); // add a bit of transparency to the text SidewaysGroup group = new SidewaysGroup(this); Button horizontalButton= new Button(this); horizontalButton.setText("This is the horizontal button"); horizontalButton.setGravity(Gravity.CENTER); horizontalButton.setTextSize(50f); horizontalButton.setBackgroundDrawable(null); horizontalButton.setTextColor(Color.WHITE); horizontalButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { Log.i("Sideways", "Button click"); } }); group.addView(horizontalButton); RelativeLayout mainLayout = new RelativeLayout(this); RelativeLayout.LayoutParams relparams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); relparams.addRule(RelativeLayout.CENTER_IN_PARENT); mainLayout.addView(verticalView, relparams); mainLayout.addView(group, relparams); setContentView(mainLayout); mainLayout.requestLayout(); } }

聚焦和翻译事件留给读者作为练习:)

【讨论】:

  • 这是非常好的东西,而且比我迄今为止所能得到的还要远。我发现了一些对映射事件很有用的旋转代码 (groups.google.com/group/android-developers/msg/4c0388feef7bd3d2),但是有太多东西不能正常工作,例如 EditText 视图和按钮上的高亮显示。
  • 感谢您的帮助。它没有解决我的问题,但值得赏金。
【解决方案2】:

您想在两个视图(垂直和水平)中滚动吗? 如果没有,也许您可​​以截取垂直文本的屏幕截图(请参阅 here )然后对布局进行实际旋转(我知道您不希望这样做,但我不明白为什么,如果垂直视图只是需要作为叠加)然后用竖屏的截图作为简单的透明位图叠加...

【讨论】:

  • 横向视图位于滚动视图中,因此不能只是屏幕截图。
【解决方案3】:

从你的 cmets 看来你想要这个:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
   <LinearLayout
        android:id="@+id/linearlayout1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal"
        >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/linearlayout2"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" />
    </LinearLayout>
</FrameLayout>

但我看不出你会如何或为什么想要这个

【讨论】:

  • 我绝对不想这样。我想要一个旋转的实际视图,而不是垂直布局。
  • 0oo 所以你的意思是阅读你需要移动你的头的文本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-29
相关资源
最近更新 更多