如何在方向更改时重新加载具有不同XML模板的页面?

时间:2016-04-14 13:02:32

标签: android nativescript

当设备的方向发生变化时,如何重新加载页面(使用新模板)? 我想在横向模式下使用不同的布局。这是NativeScript,而不是Java。

如果我以横向方式到达页面,则会选择正确的xml文件,但如果我更改方向,则不会重新加载任何内容。

请注意,这不是刷新CSS的问题,而是需要不同的XML文件。

3 个答案:

答案 0 :(得分:2)

NativeScript解决方案:

首先,你需要与方向事件联系起来。您可以通过几种方式参与该活动。

第一个也是最简单的方法是安装nativescript-orientation插件,它将全局绑定到事件中,然后每次定向更改时,它将自动在每个当前页面上调用orientation的导出函数。 /> 安装:

tns plugin install nativescript-orientation

打开app.js文件并添加到文件顶部;

require('nativescript-orientation');

然后通过创建:

exports.orientation = function(args) {
  if (args.landscaped) { /* do landscape stuff */ }
  else { /* do port */
};

在您希望收到更改方向通知的任何页面上,将在具有该功能的页面上调用它,您可以根据需要处理该事件。

但是,如果您不想使用插件,可以通过以下方式直接绑定到方向事件:

var application = require('application');
exports.onNavigateTo = function() {
  application.on(application.orientationChangedEvent,myOrientationFunction);
}

exports.onNavigateFrom = function() {
  application.off(application.orientationChangedEvent, myOrientationFunction);

function myOrientationFunction(args) {
  // We have an orientation event
}

但是,当您的页面首次打开时,您必须要求收到有关该事件的通知,并且您必须在页面关闭时将自己从通知中删除。这是上面的插件为您处理的每页额外的大量代码。请注意,当您自己执行此操作时,还需要将NavigateTo / NavigatedFrom添加到< Page>在Declarative UI XML文件中标记,否则不会调用这些函数。

好的,既然你有自己喜欢的事件;让我们来看看我们如何让你的想法发挥作用。

现在,您要求每次页面更改时切换布局;这通常是最糟糕的事情;但我会先回答它,然后再给你一个替代方法,用来做很复杂的布局,可以在肖像和横向模式下自动完成。

<强>我的编目-Landscape.xml

<Page><StackLayout><Label text="Landscape"/></StackLayout></Page>

<强>我的编目-Portrait.xml

<Page><StackLayout><Label text="Portrait"/></StackLayout></Page>

<强>我的编目-Landscape.js

var commonPage = require("./MyPage.js");
var frame = require('ui/frame');
exports.orientation = function(args) {
  if (args.landscape === false) {
     frame.topmost().navigate('MyPage-Portrait');
  }
};

// Tie all the common page code into this pages exports
for (var key in commonPage) {
   if (commonPage.hasOwnProperty(key)) {
      exports[key] = commonPage[key];
   }
}

<强>我的编目-Portrait.js

var commonPage = require("./MyPage.js");
var frame = require('ui/frame');
exports.orientation = function(args) {
  if (args.landscape === true) {
     frame.topmost().navigate('MyPage-Landscape');
  }
};

// Tie all the common page code into this pages exports
for (var key in commonPage) {
   if (commonPage.hasOwnProperty(key)) {
      exports[key] = commonPage[key];
   }
}

<强> MyPage.js

exports.TapHandler = function() { /* Someone Tapped */ }
exports.someOtherLogic = function() { /* More logic */ }
exports.etc = function() { /* etc */ }

您将所有常用页面逻辑放在MyPage文件中;但你专门导航到特定的风景或肖像页面;如果页面方向发生变化,他们每个人都有责任导航到另一个版本。

关于上述解决方案的说明:

  1. 您需要从任何其他页面导航到正确版本的页面;即。如果你处于风景模式;当你导航到另一个页面;您需要确保导航到页面的景观版本。
  2. NS-Orientation插件确实为您提供了一个句柄辅助功能,可以找出当前的方向,以便更轻松。
  3. 记得让MyPage.js拥有所有常用代码;您想尝试消除特定页面版本上的任何自定义代码。
  4. 他们是你可以使用的帧重载命令;然而它完全清除了历史;意思是你无法向后导航。即Page1 - &gt; Page2,frame.reloadPage()表示后退按钮不会返回到Page1。如果这是可以接受的;你可以使上述系统更简单;而不是创建单独的xml&amp; js文件你只需要一个myPage.landscape.xml和myPage.portrait.xml,你需要在每个方向更改时调用frame.reloadPage();
  5. 现在对我而言,对于你可能需要在页面之间进行的简单更改,这可能是一种严重的过度杀伤。所以我将在我的应用程序中描述我是如何做到的;它有一些相当复杂的屏幕,但它们看起来非常漂亮,完全改变了方向变化的功能。

    这是编写NativeScript-orientation插件的部分原因。在页面方向更改时,将自动向XML中的<Page>元素添加/删除“格局”类名。这允许你在CSS中做的是:

    .myLabel {
      font-size: 12;
      background-color: blue;
      height: 20;
    }
    
    .landscape .myLabel {
      font-size: 16;
      background-color: green;
      height: 40;
    }
    

    如果你还没弄明白我要去哪儿;这使您可以在横向模式下为页面设置自定义CSS,而在纵向模式下则可以。此外,当您使用 exports.orientation 功能时,您也可以根据方向运行自定义代码。

    所以在我的情况下;在手机上,我的滚动列表是向上滚动的单个滚动列表,其大小与屏幕完全相同,看起来非常清晰。切换到横向模式时;它隐藏了操作栏,添加了一个fab按钮,调整整个网格项的大小以适应相同的比例,并将滚动模式切换到左右。整个外观变化的大部分是在纯css中完成的;其余的是在exports.orientation函数中完成的,它处理切换滚动方向等事情。

    免责声明:我是NativeScript-orientation插件的作者

答案 1 :(得分:0)

在您的活动中:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setContentView(R.layout.my_layout);
}

确保两个方向都具有相同名称的布局XML

res/layout/my_layout.xml
res/layout-land/my_layout.xml

答案 2 :(得分:0)

使用正确的资源文件名,Android系统会自动使用适当的资源重新加载您的活动/片段。 您可以通过设置android:configChanges手动捕获和处理事件(但这是一种罕见的情况)。

查看一些文档: