安卓屏幕方向:仅锁定部分布局

7
我正在开发一款利用相机预览的相机应用程序。为了使用全屏进行预览,我锁定了该活动,使用了以下代码:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

现在我有以下问题:每当我渲染一个表单或者弹出对话框时,它总是以横向模式显示,即使用户使用他/她的设备处于竖屏模式。我尝试使用变换动画旋转编辑文本视图,虽然它们正确地旋转了,但我不能再聚焦它们,键盘总是以横向模式显示:(您知道如何找到解决方法吗?
重要提示:检测方向不是这里的问题。问题是:如何旋转表单/视图/视图组和键盘,使其仍可用。
我知道这必须有可能:三星的相机应用程序(随 Galaxy S3 一起提供)能够旋转视图而不旋转预览,所以肯定有解决办法!请参见:

http://www.letsgomobile.org/images/reviews/0186/galaxy-s3-camera.jpg

http://cdn2.mos.techradar.futurecdn.net//art/mobile_phones/Samsung/GalaxyS3/Galaxy%20Fire/Samsung_Galaxy_S3_25-580-100.JPG


你有尝试使用android:theme="@android:style/Theme.Dialog"将新的Activity启动为对话框而不是实际对话框吗?我怀疑这个假对话框应该会像你仅将相机活动锁定在横向方向一样对方向变化做出反应。不幸的是,我目前无法尝试它自己。 - Audrius
还没有尝试过。如果能发挥作用就太好了... - stoefln
刚试了一下,不起作用:无论我如何旋转设备,对话框活动都显示为横向。 - stoefln
你如何显示相机的预览?也许你不应该锁定方向,而是找到一种方法,在预览时始终使用全屏,而应用程序的其余部分可以移动...? - Matthieu
我也思考过这个问题。我正在使用 SurfaceHolder 来附加预览: mSurfaceView = new SurfaceView(context); addView(mSurfaceView); mSurfaceView.getHolder().addCallback(this); 然后,在 surfaceCreated() 回调中: camera.setPreviewDisplay(holder); - stoefln
6个回答

2
通过设置该属性
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

你正在将屏幕锁定为横屏模式,即使用户使用纵向持有设备,也不会切换到纵向模式。根据我对你问题的理解,你可以采取一种方法。
android:configChanges="orientation"

在清单文件中添加以下属性到您的Activity中。在Activity类中覆盖onConfigurationChange方法,您可以根据需要处理方向变化,而不是将Activity锁定为横向。
如果我正确理解了您的问题,则这可能会对您有所帮助。

我知道我可以做到。但是,正如我已经写过的那样,我没有成功地呈现一个旋转的编辑文本框(或按钮),它仍然可以工作,并且键盘总是以横向模式显示。 - stoefln

2
三星相机应用程序正在使用方向传感器的方向更改监听器。如果用户从设置中阻止设备旋转,则仍会发生旋转。
您需要创建完整的自定义小部件,因此无法使用内置对话框,您必须显示CustomDialog ....
基本思路是使用OrientationEventListener和SensorManager。在设备旋转时,您必须更新UI并根据新方向旋转视图。这里有一个关于使用OrientationEventListener的教程 如何使用OrientationEventListener 在大多数相机应用程序中,活动仍然被锁定在LANDSCAPE上。 所有相机应用程序都会使用此技巧来简化处理SurfaceView大小随旋转而变化的操作。

我已经实现了OrientationEventListener-这不是问题所在...然而,你的意思是说我不能使用标准的ScrollView、Edittext和其他控件吗?我真的必须自己编写吗?三星的小部件(至少滚动视图)看起来像标准的Android视图。你认为有没有可能旋转键盘? - stoefln
你需要实现两种方向(layout_portrait和layout_land)。当方向变为0时,你需要设置为竖屏;当旋转变为(270+-20)时,你需要移除视图并填充横屏视图,并将其附加。 - Anis BEN NSIR
键盘仍将保持在原地,否则您必须使用Activity onChange处理方向并注册为传感器。 - Anis BEN NSIR

0
在您的清单文件中,为相机预览活动提供以下属性:android:configChanges="keyboardHidden|orientation"。欲了解更多信息,请参阅this
<activity
        android:name=".Your_Activity_Name"
        android:configChanges="keyboardHidden|orientation"
        android:label="@string/app_name" >
        <intent-filter>
            <!-- Your filter attributes if any. -->
        </intent-filter>
    </activity>

在您的活动类中,重写onConfigurationChanged方法,并根据需要处理相关屏幕方向模式(例如横向或纵向)。
@Override
 public void onConfigurationChanged(Configuration newConfig) {
     super.onConfigurationChanged(newConfig);

     // Checks the orientation of the screen
     if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
         Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        //Your code to do the other things in landscape mode...

     } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
         Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
       //Your code to do the other things in portrait mode...

     }
 }

希望这能帮到你解决问题。


酷 - 不知道可以旋转 Toast 消息。然而,我仍然不知道如何旋转表单元素。 - stoefln
当屏幕方向改变时,Android会自动处理这个问题。每次屏幕方向改变时,它都会调用onConfigurationChanged方法。 - Rupesh Yadav
不会自动旋转,因为我调用了setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)来锁定相机预览为横屏,这将锁定整个活动。 - stoefln
是的,你是正确的,它不会被调用,因为你已经请求了方向。这个链接可能对你有帮助。 - Rupesh Yadav
那应该如何帮助我?您能详细说明一下吗?正如先前所说:我知道如何捕捉方向,但我不知道如何旋转视图/表单和键盘。 - stoefln

0

你最好尝试使用另一个活动作为对话框,并在清单中设置其属性(方向和主题)并使用它。


不起作用- 刚刚尝试过:无论我如何旋转设备,对话框活动都显示为横向。 - stoefln

0

据我所知:旋转是通过捕获方向事件并根据该方向充气屏幕以实现的。

  1. 在横屏中充气
  2. 发生旋转
  3. 充气屏幕上要更改的部分,例如我们为按钮的持有者视图充气新的纵向布局,而不是横向布局。

您必须将布局划分为部分,并在运行时将它们添加在一起。

另一种实现方法是使用表面视图进行相机预览,然后使用另一个布局来容纳表面并在其上方添加 framelayout


我不希望应用程序重新充气。只需考虑以45°模式拍摄的图像-您肯定不希望每次用户在横向和纵向之间旋转手机时都重建整个界面。 - stoefln

0

你需要通过旋转设备来覆盖活动的行为,你需要在你的清单文件中添加orientationChange,然后为此事件添加监听器并手动旋转你的视图。

如果你使用这种方法,所有对话框等(系统视图)都会以正确的方式显示。

请查看: http://developer.android.com/reference/android/app/Activity.html#ConfigurationChanges

还有这个: 如何处理屏幕方向更改时进度对话框和后台线程处于活动状态? (我想是第二个答案)


不理解。你说的“必须通过旋转设备来覆盖活动的行为”是什么意思? - stoefln
如果您在清单文件中声明您将处理configChanges:orientation - 您将能够覆盖onConfigurationChanged(Configuration)或类似的方法,并且在此方法中,您可以手动旋转仅必要的视图。 - dilix
是的,但正如我之前所写的那样,通过编程方式旋转EditText或键盘并不起作用。你知道怎么做吗? - stoefln

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接