【问题标题】:How can I change among multiple layouts based on an orientation change in Android?如何根据 Android 中的方向更改在多个布局之间进行更改?
【发布时间】:2014-02-10 21:20:02
【问题描述】:

这个问题我已经有一段时间了,我正在寻求帮助。我是初学者,所以如果我的术语不正确,我深表歉意。我会尽量回复。

我正在开发一个 Android 应用程序,该应用程序链接到一个朋友的网站,他在该网站上播放各种视频。我的应用程序非常基本,因为我希望它以一种布局打开,当您单击按钮打开其中一个流时,它会以不同的布局打开。我还希望布局根据屏幕的方向而改变。我已经在应用程序的布局文件夹中创建了 4 个不同的 XML 文件。我有主屏竖屏布局文件,主屏横屏布局文件,流屏竖屏文件,流屏布局文件。

我的问题是我不确定如何在 4 个不同的布局文件之间切换。以下代码是我觉得应该如何切换到不同视图的函数:

public void screenOrientation()
{
    int rotation = ((WindowManager)getApplicationContext().getSystemService(WINDOW_SERVICE)).getDefaultDisplay().getRotation();

    LinearLayout mainPortrait = (LinearLayout) view.findViewById(R.layout.main);
    LinearLayout mainLandscape = (LinearLayout) view.findViewById(R.layout.mainlandscape);
    LinearLayout streamPortrait = (LinearLayout) view.findViewById(R.layout.streaminappportrait);
    LinearLayout streamLandscape = (LinearLayout) view.findViewById(R.layout.streaminapplandscape);

    if (Global.appShowingMain == true && Global.appShowingStream == false)
    {
        switch (rotation)
        {
            case 0:
                mainPortrait.setVisibility(View.VISIBLE);
                break;
            case 90:
                mainLandscape.setVisibility(View.VISIBLE);
                break;
            case 180:
                mainPortrait.setVisibility(View.VISIBLE);
                break;
            case 270:
                mainLandscape.setVisibility(View.VISIBLE);
                break;
            default:
                mainPortrait.setVisibility(View.VISIBLE);
                break;
        }
    }
    else if (Global.appShowingStream == true && Global.appShowingMain == false)
    {
        switch (rotation)
        {
            case 0:
                streamPortrait.setVisibility(View.VISIBLE);
                break;
            case 90:
                streamLandscape.setVisibility(View.VISIBLE);
                break;
            case 180:
                streamPortrait.setVisibility(View.VISIBLE);
                break;
            case 270:
                streamLandscape.setVisibility(View.VISIBLE);
                break;
            default:
                streamPortrait.setVisibility(View.VISIBLE);
                break;
        }
    }
}

对于如何根据屏幕的方向在这些不同的布局之间进行切换,我真的很困惑。有人可以帮忙吗?

编辑:根据我在下面进行的对话,我已将相关代码更改为以下内容:

public void screenOrientation() { int rotation = ((WindowManager)getApplicationContext().getSystemService(WINDOW_SERVICE)).getDefaultDisplay().getRotation();

    if (Global.appShowingMain == true && Global.appShowingStream == false)
    {
        switch (rotation)
        {
            case 0:
                setContentView(R.layout.main);
                break;
            case 90:
                setContentView(R.layout.mainlandscape);
                break;
            case 180:
                setContentView(R.layout.main);
                break;
            case 270:
                setContentView(R.layout.mainlandscape);
                break;
            default:
                setContentView(R.layout.main);
                break;
        }
    }
    else if (Global.appShowingStream == true && Global.appShowingMain == false)
    {
        switch (rotation)
        {
            case 0:
                setContentView(R.layout.streaminappportrait);
                break;
            case 90:
                setContentView(R.layout.streaminapplandscape);
                break;
            case 180:
                setContentView(R.layout.streaminappportrait);
                break;
            case 270:
                setContentView(R.layout.streaminapplandscape);
                break;
            default:
                setContentView(R.layout.streaminappportrait);
                break;
        }
    }
}

发生的情况是,无论您以横向还是纵向模式打开应用程序,主纵向布局都只显示。当您更改方向时,该纵向布局是唯一可见的。当您尝试转到流时,无论您是横向还是纵向,都会打开流布局的纵向版本。当您打开该流布局并且屏幕方向发生变化时,它会将您带回主菜单纵向。

【问题讨论】:

  • 你试过做 setContentView(R.layout.desired_resource); ?
  • 在某一时刻,所有这些 setVisibility 代码行都是对应于它们的相应布局文件的 setContentView 行,但是当我拥有所有这些代码时应用程序崩溃了。
  • 假设我们按照您的方式保留它,所有这些视图是否都在同一个层次结构中?它们包含在哪里?我只看到你显示视图,而不是隐藏它们。是否有可能最顶层的视图始终可见,从而掩盖了底层视图?
  • 另外——这个实现的实际问题是什么?崩溃?记录垃圾邮件?没有显示视图?
  • 我不知道我必须隐藏视图。我假设使视图自动可见会使所有其他视图不可见。编辑:我会把代码改回我之前的 setContentView 情况,我会告诉你的。

标签: android layout views orientation


【解决方案1】:

您需要做的就是放置两种布局,一种用于纵向,一种用于横向。 layout 文件夹中的纵向和 layout-land 文件夹中的横向。

【讨论】:

  • 我试过了,但这似乎只适用于一组屏幕。我有两组屏幕需要在它们之间切换。
【解决方案2】:

您可以通过这种方式以编程方式执行此操作:

if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
  // Do the changes within the portrait orientation
  ...
}
else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
  // Do the changes within the landscape orientation
  ...
}

这假设您在 Activity 或派生类中执行此操作。如果没有,您必须为 getResources() 方法提供一个 Context 实例:

mycontext.getResources()...

---- 编辑----

  • getResources():这是Context 类中的一个方法。这意味着,如果您在扩展了Context 定义的另一个类(例如Activity)的类中运行此方法,则无需提供任何其他内容。您可以在Contexts here 上阅读更多信息。你会知道如果你正在扩展 Activity 并查看你的类定义,它应该是这样的:

    public class MyActivity extends Activity { ... }
    

所以基本上,这个方法会返回一个包含所有资源的Resources 对象。您可以在here 阅读更多内容。但是你不需要所有的资源,所以让我们再做一步。

  • getConfiguration()getResources() 方法返回一个 Resources 实例。这个类提供了一个getConfiguration() 方法,它返回一个Configuration 实例(更多关于这个here),它包含许多你可以使用的配置参数。其中之一是方向,因此您有两个常量,ORIENTATION_PORTRAITORIENTATION_LANDSCAPE。有关此here 的更多信息。

但是,如果您在一个静态类中,即没有Context,则您必须在先前保存的Context 实例上显式调用getResources()。例如,在onCreate() 方法中将其保存为mycontext = this;。不过,这可能会导致内存泄漏,因此在example 中解释了处理此问题的最佳方法( 如果需要)。

【讨论】:

  • 对不起,我对 Android 编程比较陌生。有什么方法可以简化你的答案吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多