HTML + JavaScript 学习Metro程序 (3) - ListView + AppBar

本文介绍如何处理ListView在AppBar显示时被遮挡的问题。通过响应AppBar的beforeshow和beforehide事件,动态调整ListView的高度,确保内容可见。通过示例代码展示了解决方案,并解释了其工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AppBar大量的Metro应用里面使用,那么这里有一个很基本的问题:AppBar需要在屏幕中占用一定的空间。那么会不会当AppBar显示的时候,某些东西被AppBar盖住了呢?

比如,应用里面有个listview,这个listview的底部接近屏幕的底部,那么当AppBar显示的时候,listview底部的一部分会被AppBar盖住,从而使得用户无法看到那部分东西,这显然是一个很不好的现象。MSDN上专门有一个页面来描述这个问题,http://msdn.microsoft.com/zh-cn/library/windows/apps/jj649138.aspx。这也说明这是个普遍问题。

 

其实解决这个问题的关键在于AppBar的2个消息:beforeshow和beforehide。

在AppBar显示前,把ListView的高度缩小一点,在AppBar隐藏前,将ListView的高度恢复到原始高度。

 

先来看看HTML代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>pagecontrol</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
    <script src="//Microsoft.WinJS.1.0/js/ui.js"></script>

    <link href="/css/pagecontrol.css" rel="stylesheet" />
    <script src="/js/pagecontrol.js"></script>
    <script src="/js/appbar.js"></script>

</head>
<body>
    <!-- Full screen container for ListView -->
    <div id="scenarioFullscreen">
        <header style="text-align:center;margin-top:80px">Test listview + appbar</header>
        <section style="height:720px;margin-top:40px">
            <div id="scenarioListView" style="height:100%"
                data-win-control="WinJS.UI.ListView"
                data-win-options="{ itemTemplate: smallListIconTextTemplate, selectionMode: 'multi', tapBehavior: 'toggleSelect', swipeBehavior: 'select', layout: { type: WinJS.UI.ListLayout, maxRows: 100 },itemDataSource : DataExample.itemList.dataSource }" >
            </div>
        </section>
    </div>    
    <!-- AppBar with contextual commands for a ListView -->
    <!-- BEGINTEMPLATE: Template code for AppBar -->
    <div id="scenarioAppBar" data-win-control="WinJS.UI.AppBar">
        <button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'cmdAdd',label:'Add',icon:'add',section:'global',extraClass:'singleSelect',tooltip:'Add item'}"></button>
        <button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'cmdSelectAll',label:'Select All',icon:'selectall',section:'selection',extraClass:'ContextRelated',tooltip:'Select All'}"></button>
        <button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'cmdClearSelection',label:'Clear Selection',icon:'clearselection',section:'selection',extraClass:'ContextRelated',tooltip:'Clear Selection'}"></button>
        <hr     data-win-control="WinJS.UI.AppBarCommand" data-win-options="{type:'separator',section:'selection',extraClass:'ContextRelated'}" />
        <button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'cmdDelete',label:'Delete',icon:'delete',section:'selection',extraClass:'ContextRelated',tooltip:'Delete item'}"></button>
    </div>
    <!-- ENDTEMPLATE --> 
    
</body>
</html>

简单的加了一个ListView和一个AppBar。ListView是一个非常有用,也非常灵活的控件,具体可以参考:http://msdn.microsoft.com/zh-cn/library/windows/apps/hh465465.aspx

这里就是一个简单应用。

给这个listview加一些测试数据,看js代码:

(function () {
    "use strict";

    var dataArray = [
    { title: "Basic banana", text: "Low-fat frozen yogurt", picture: "images/60banana.png" },
    { title: "Banana blast", text: "Ice cream", picture: "images/60banana.png" },
    { title: "Brilliant banana", text: "Frozen custard", picture: "images/60banana.png" },
    { title: "Orange surprise", text: "Sherbet", picture: "images/60orange.png" },
    { title: "Original orange", text: "Sherbet", picture: "images/60orange.png" },
    { title: "Vanilla", text: "Ice cream", picture: "images/60vanilla.png" },
    { title: "Very vanilla", text: "Frozen custard", picture: "images/60vanilla.png" },
    { title: "Marvelous mint", text: "Gelato", picture: "images/60mint.png" },
    { title: "Succulent strawberry", text: "Sorbet", picture: "images/60strawberry.png" },
    { title: "Basic banana", text: "Low-fat frozen yogurt", picture: "images/60banana.png" },
    { title: "Banana blast", text: "Ice cream", picture: "images/60banana.png" },
    { title: "Brilliant banana", text: "Frozen custard", picture: "images/60banana.png" },
    { title: "Orange surprise", text: "Sherbet", picture: "images/60orange.png" },
    { title: "Original orange", text: "Sherbet", picture: "images/60orange.png" },
    { title: "Vanilla", text: "Ice cream", picture: "images/60vanilla.png" },
    { title: "Very vanilla", text: "Frozen custard", picture: "images/60vanilla.png" },
    { title: "Marvelous mint", text: "Gelato", picture: "images/60mint.png" },
    { title: "Succulent strawberry", text: "Sorbet", picture: "images/60strawberry.png" },
    { title: "Basic banana", text: "Low-fat frozen yogurt", picture: "images/60banana.png" },
    { title: "Banana blast", text: "Ice cream", picture: "images/60banana.png" },
    { title: "Brilliant banana", text: "Frozen custard", picture: "images/60banana.png" },
    { title: "Orange surprise", text: "Sherbet", picture: "images/60orange.png" },
    { title: "Original orange", text: "Sherbet", picture: "images/60orange.png" },
    { title: "Vanilla", text: "Ice cream", picture: "images/60vanilla.png" },
    { title: "Very vanilla", text: "Frozen custard", picture: "images/60vanilla.png" },
    { title: "Marvelous mint", text: "Gelato", picture: "images/60mint.png" },
    { title: "Succulent strawberry", text: "Sorbet", picture: "images/60strawberry.png" },
    { title: "lastitem", text: "test", picture: "images/60strawberry.png" }
    ];

    var dataList = new WinJS.Binding.List(dataArray);

    // Create a namespace to make the data publicly
    // accessible. 
    var publicMembers =
        {
            itemList: dataList
        };
    WinJS.Namespace.define("DataExample", publicMembers);

})();

搞了一些测试代码,然后创建一个成员dataList,并且通过WinJS.Namespace暴露出来。这样在HTML里面就可以把ListView和这些数据绑定起来,就是设置一个属性:

itemDataSource : DataExample.itemList.dataSource

这样,我们就可以显示这么个界面:



这个list的底部已经接近屏幕的底部了,如果不做特殊处理,那么当AppBar显示的时候,list底部一部分就被盖住了。

先看一下beforeshow的响应函数:

function doAppBarShow() {
        var listView = document.getElementById("scenarioListView");
        var appBar = document.getElementById("scenarioAppBar");
        var appBarHeight = appBar.offsetHeight;
        // Move the scrollbar into view if appbar is sticky
        if (appBar.winControl.sticky) {
            var listViewTargetHeight = "calc(100% - " + appBarHeight + "px)";
           
            var transition = {
                property: 'height',
                duration: 367,
                timing: "cubic-bezier(0.1, 0.9, 0.2, 0.1)",
                to: listViewTargetHeight
            };
            WinJS.UI.executeTransition(listView, transition);
        }
    }

这个函数就做了一件事情,当AppBar是sticky(就是一直显示着)的时候将ListView高度缩小一点(缩小部分比AppBar的高度稍微大一点)。

beforehide对应的函数:

function doAppBarHide() {
        var listView = document.getElementById("scenarioListView");
        var appBar = document.getElementById("scenarioAppBar");
        var appBarHeight = appBar.offsetHeight;
        // Move the scrollbar into view if appbar is sticky
        if (appBar.winControl.sticky) {
            var listViewTargetHeight = "100%";
            var transition = {
                property: 'height',
                duration: 367,
                timing: "cubic-bezier(0.1, 0.9, 0.2, 0.1)",
                to: listViewTargetHeight
            };
            WinJS.UI.executeTransition(listView, transition);
        }
    }

当AppBar不是Sticky的时候,将ListView恢复到原来的高度。

当用户点击ListView里面的某一项时候,会触发iteminvoked的消息,给它绑定一个函数:

function doSelectItem() {
        var appBarDiv = document.getElementById("scenarioAppBar");
        var appBar = document.getElementById('scenarioAppBar').winControl;
        var listView = document.getElementById("scenarioListView").winControl;
        var count = listView.selection.count();
        if (count > 0) {
            // Show selection commands in AppBar
            appBar.showCommands(appBarDiv.querySelectorAll('.ContextRelated'));
            appBar.sticky = true;
            appBar.show();
        } else {
            // Hide selection commands in AppBar
            appBar.hide();
            appBar.hideCommands(appBarDiv.querySelectorAll('.ContextRelated'));
            appBar.sticky = false;
        }
    }

也就是说当用户选择了一项或者多项的时候,显示class是ContextRelated的按钮,并且将AppBar设置成Sticky模式,然后显示AppBar。反之,如果用户没有选中任何项,则改成非Sticky的,隐藏ContextRelated的按钮并且隐藏AppBar。

比如:用户点击了ListView里面的某一项,那么就会显示AppBar,然后再点一次,这个时候就没有任何选中项了,就会隐藏AppBar。


initAppBar用来处理按钮的响应函数:

function initAppBar() {
        var appBarDiv = document.getElementById("scenarioAppBar");
        var appBar = document.getElementById("scenarioAppBar").winControl;
        // Add event listeners
        document.getElementById("cmdAdd").addEventListener("click", doClickAdd, false);
        document.getElementById("cmdDelete").addEventListener("click", doClickDelete, false);
        document.getElementById("cmdSelectAll").addEventListener("click", doClickSelectAll, false);
        document.getElementById("cmdClearSelection").addEventListener("click", doClickClearSelection, false);
        appBar.addEventListener("beforeshow", doAppBarShow, false);
        appBar.addEventListener("beforehide", doAppBarHide, false);
        
        // Hide selection group of commands
        appBar.hideCommands(appBarDiv.querySelectorAll('.ContextRelated'));
        // Disable AppBar until in full screen mode

        var listView = document.getElementById("scenarioListView").winControl;
        listView.addEventListener("iteminvoked", doSelectItem);

    }

这个函数里面绑定了应用栏按钮的响应函数,还有beforeshow和beforehide两个事件的响应函数和ListView的iteminvoked事件。

在ready函数里面调用一下这个函数:

var page = WinJS.UI.Pages.define("pagecontrol.html", {
        ready: function (element, options) {
            initAppBar();
            
        },
    });


这样,当用户选择ListView里面的某一项的时候:

1. doSelectItem会被调用,doSelectItem会根据是否有选中项来显示/隐藏AppBar;

2. AppBar显示前会调用doAppBarShow,doAppBarShow会将ListView的高度缩小一点;

3. AppBar隐藏前会调用doAppBarHide,doAppBarHide会将ListView高度复原。

这样就解决了ListView底部被AppBar覆盖的问题,其实ListView只是一种例子,其他的控件也会有被覆盖的问题,解决的办法是类似的(当然有时被覆盖一下也不要紧)。

效果:

可以看到ListView的底部显示在AppBar的上面了,这样就不会被盖住了。

完整js代码:

(function () {
    "use strict";
    var page = WinJS.UI.Pages.define("pagecontrol.html", {
        ready: function (element, options) {
            initAppBar();
            
        },
    });

    function initAppBar() {
        var appBarDiv = document.getElementById("scenarioAppBar");
        var appBar = document.getElementById("scenarioAppBar").winControl;
        // Add event listeners
        document.getElementById("cmdAdd").addEventListener("click", doClickAdd, false);
        document.getElementById("cmdDelete").addEventListener("click", doClickDelete, false);
        document.getElementById("cmdSelectAll").addEventListener("click", doClickSelectAll, false);
        document.getElementById("cmdClearSelection").addEventListener("click", doClickClearSelection, false);
        appBar.addEventListener("beforeshow", doAppBarShow, false);
        appBar.addEventListener("beforehide", doAppBarHide, false);
        
        // Hide selection group of commands
        appBar.hideCommands(appBarDiv.querySelectorAll('.ContextRelated'));
        // Disable AppBar until in full screen mode

        var listView = document.getElementById("scenarioListView").winControl;
        listView.addEventListener("iteminvoked", doSelectItem);

    }

    function doClickAdd()
    { }
    function doClickDelete()
    { }
    function doClickSelectAll()
    { }
    function doClickClearSelection()
    { }

    function doSelectItem() {
        var appBarDiv = document.getElementById("scenarioAppBar");
        var appBar = document.getElementById('scenarioAppBar').winControl;
        var listView = document.getElementById("scenarioListView").winControl;
        var count = listView.selection.count();
        if (count > 0) {
            // Show selection commands in AppBar
            appBar.showCommands(appBarDiv.querySelectorAll('.ContextRelated'));
            appBar.sticky = true;
            appBar.show();
        } else {
            // Hide selection commands in AppBar
            appBar.hide();
            appBar.hideCommands(appBarDiv.querySelectorAll('.ContextRelated'));
            appBar.sticky = false;
        }
    }

    /* This function slides the ListView scrollbar into view if occluded by the AppBar (in sticky mode) */
    function doAppBarShow() {
        var listView = document.getElementById("scenarioListView");
        var appBar = document.getElementById("scenarioAppBar");
        var appBarHeight = appBar.offsetHeight;
        // Move the scrollbar into view if appbar is sticky
        if (appBar.winControl.sticky) {
            var listViewTargetHeight = "calc(100% - " + appBarHeight + "px)";
           
            var transition = {
                property: 'height',
                duration: 367,
                timing: "cubic-bezier(0.1, 0.9, 0.2, 0.1)",
                to: listViewTargetHeight
            };
            WinJS.UI.executeTransition(listView, transition);
        }
    }

    /* This function slides the ListView scrollbar back to its original position */
    function doAppBarHide() {
        var listView = document.getElementById("scenarioListView");
        var appBar = document.getElementById("scenarioAppBar");
        var appBarHeight = appBar.offsetHeight;
        // Move the scrollbar into view if appbar is sticky
        if (appBar.winControl.sticky) {
            var listViewTargetHeight = "100%";
            var transition = {
                property: 'height',
                duration: 367,
                timing: "cubic-bezier(0.1, 0.9, 0.2, 0.1)",
                to: listViewTargetHeight
            };
            WinJS.UI.executeTransition(listView, transition);
        }
    }


})();

(function () {
    "use strict";

    var dataArray = [
    { title: "Basic banana", text: "Low-fat frozen yogurt", picture: "images/60banana.png" },
    { title: "Banana blast", text: "Ice cream", picture: "images/60banana.png" },
    { title: "Brilliant banana", text: "Frozen custard", picture: "images/60banana.png" },
    { title: "Orange surprise", text: "Sherbet", picture: "images/60orange.png" },
    { title: "Original orange", text: "Sherbet", picture: "images/60orange.png" },
    { title: "Vanilla", text: "Ice cream", picture: "images/60vanilla.png" },
    { title: "Very vanilla", text: "Frozen custard", picture: "images/60vanilla.png" },
    { title: "Marvelous mint", text: "Gelato", picture: "images/60mint.png" },
    { title: "Succulent strawberry", text: "Sorbet", picture: "images/60strawberry.png" },
    { title: "Basic banana", text: "Low-fat frozen yogurt", picture: "images/60banana.png" },
    { title: "Banana blast", text: "Ice cream", picture: "images/60banana.png" },
    { title: "Brilliant banana", text: "Frozen custard", picture: "images/60banana.png" },
    { title: "Orange surprise", text: "Sherbet", picture: "images/60orange.png" },
    { title: "Original orange", text: "Sherbet", picture: "images/60orange.png" },
    { title: "Vanilla", text: "Ice cream", picture: "images/60vanilla.png" },
    { title: "Very vanilla", text: "Frozen custard", picture: "images/60vanilla.png" },
    { title: "Marvelous mint", text: "Gelato", picture: "images/60mint.png" },
    { title: "Succulent strawberry", text: "Sorbet", picture: "images/60strawberry.png" },
    { title: "Basic banana", text: "Low-fat frozen yogurt", picture: "images/60banana.png" },
    { title: "Banana blast", text: "Ice cream", picture: "images/60banana.png" },
    { title: "Brilliant banana", text: "Frozen custard", picture: "images/60banana.png" },
    { title: "Orange surprise", text: "Sherbet", picture: "images/60orange.png" },
    { title: "Original orange", text: "Sherbet", picture: "images/60orange.png" },
    { title: "Vanilla", text: "Ice cream", picture: "images/60vanilla.png" },
    { title: "Very vanilla", text: "Frozen custard", picture: "images/60vanilla.png" },
    { title: "Marvelous mint", text: "Gelato", picture: "images/60mint.png" },
    { title: "Succulent strawberry", text: "Sorbet", picture: "images/60strawberry.png" },
    { title: "lastitem", text: "test", picture: "images/60strawberry.png" }
    ];

    var dataList = new WinJS.Binding.List(dataArray);

    // Create a namespace to make the data publicly
    // accessible. 
    var publicMembers =
        {
            itemList: dataList
        };
    WinJS.Namespace.define("DataExample", publicMembers);

})();



 

内容概要:本文详细介绍了扫描单分子定位显微镜(scanSMLM)技术及其在三维超分辨体积成像中的应用。scanSMLM通过电调透镜(ETL)实现快速轴向扫描,结合4f检测系统将不同焦平面的荧光信号聚焦到固定成像面,从而实现快速、大视场的三维超分辨成像。文章不仅涵盖了系统硬件的设计与实现,还提供了详细的软件代码实现,包括ETL控制、3D样本模拟、体积扫描、单分子定位、3D重建和分子聚类分析等功能。此外,文章还比较了循环扫描与常规扫描模式,展示了前者在光漂白效应上的优势,并通过荧光珠校准、肌动蛋白丝、线粒体网络和流感A病毒血凝素(HA)蛋白聚类的三维成像实验,验证了系统的性能和应用潜力。最后,文章深入探讨了HA蛋白聚类与病毒感染的关系,模拟了24小时内HA聚类的动态变化,提供了从分子到细胞尺度的多尺度分析能力。 适合人群:具备生物学、物理学或工程学背景,对超分辨显微成像技术感兴趣的科研人员,尤其是从事细胞生物学、病毒学或光学成像研究的科学家和技术人员。 使用场景及目标:①理解和掌握scanSMLM技术的工作原理及其在三维超分辨成像中的应用;②学习如何通过Python代码实现完整的scanSMLM系统,包括硬件控制、图像采集、3D重建和数据分析;③应用于单分子水平研究细胞内结构和动态过程,如病毒入侵机制、蛋白质聚类等。 其他说明:本文提供的代码不仅实现了scanSMLM系统的完整工作流程,还涵盖了多种超分辨成像技术的模拟和比较,如STED、GSDIM等。此外,文章还强调了系统在硬件改动小、成像速度快等方面的优势,为研究人员提供了从理论到实践的全面指导。
内容概要:本文详细介绍了基于Seggiani提出的渣层计算模型,针对Prenflo气流床气化炉中炉渣的积累和流动进行了模拟。模型不仅集成了三维代码以提供气化炉内部的温度和浓度分布,还探讨了操作条件变化对炉渣行为的影响。文章通过Python代码实现了模型的核心功能,包括炉渣粘度模型、流动速率计算、厚度更新、与三维模型的集成以及可视化展示。此外,还扩展了模型以考虑炉渣组成对特性的影响,并引入了Bingham流体模型,更精确地描述了含未溶解颗粒的熔渣流动。最后,通过实例展示了氧气-蒸汽流量增加2%时的动态响应,分析了温度、流动特性和渣层分布的变化。 适合人群:从事煤气化技术研究的专业人士、化工过程模拟工程师、以及对工业气化炉操作优化感兴趣的科研人员。 使用场景及目标:①评估不同操作条件下气化炉内炉渣的行为变化;②预测并优化气化炉的操作参数(如温度、氧煤比等),以防止炉渣堵塞;③为工业气化炉的设计和操作提供理论支持和技术指导。 其他说明:该模型的实现基于理论公式和经验数据,为确保模型准确性,实际应用中需要根据具体气化炉的数据进行参数校准。模型还考虑了多个物理场的耦合,包括质量、动量和能量守恒方程,能够模拟不同操作条件下的渣层演变。此外,提供了稳态求解器和动态模拟工具,可用于扰动测试和工业应用案例分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值