写点什么

APICloud AVM 框架列表组件 list-view 的使用、flex 布局教程

作者:APICloud
  • 2022 年 2 月 09 日
  • 本文字数:4554 字

    阅读完需:约 15 分钟

avm.js 是 APICloud 推出的多端开发框架。使用 avm.js 一个技术栈可同时开发 Android & iOS 原生 App、小程序和 iOS 轻 App,且多端渲染效果统一;全新的 App 引擎 3.0 不依赖 webView,提供百分百的原生渲染,保障 App 性能和体验与原生 App 一致。


list-view 定义可复用内容的竖向滚动视图,可以优化内存占用和渲染性能,支持下拉刷新和上拉加载。可使用 scroll-view 的基本属性


list-view 里面可放置 cell、list-header、list-footer、refresh 等组件,使用 cell 组件作为每项显示内容。


下面看一个 list-view 的示例:


<template>  <list-view id="listView" class="main" enable-back-to-top onscrolltolower={this.onscrolltolower}>    <cell class="cell c-lc-rl_ac c-sy-border_bottom c-lc-ptb" onclick={this.itemClick}>      <img class="img" src={item.url} alt="">      <text class="title c-filling-w c-pl">{item.title}</text>    </cell>    <list-footer class="footer">      <text>加载中...</text>    </list-footer>  </list-view></template><style src='../../css/c-layout-mini.css' scoped></style><style>.main {  width: 100%;  height: 100%;} .cell {  width: 100%;  height: 70px;} .img {  height: 50px;  width: 50px;  margin-left: 10px;}.title {  height: 50px;  font-size: 20px;  line-height: 50px;} .footer {  justify-content: center;  align-items: center;}</style> <script>export default {  name: 'test',  methods: {    apiready() {      this.initData(false);    },    initData(loadMore) {      var that = this;      var skip = that.dataList ? that.dataList.length : 0;      var dataList = [];      for (var i = 0; i < 20; i++) {        dataList[i] = {          title: '项目' + (i + skip),          url: '../../image/nav_tab_2.png'        }      }      var listView = document.getElementById('listView');      if (loadMore) {        that.dataList = that.dataList.concat(dataList);        listView.insert({          data: dataList        });      } else {        that.dataList = dataList;        listView.load({          data: dataList        });      }    },    onscrolltolower() {      this.initData(true);    },    itemClick(e) {      api.alert({        msg: '当前项索引:' + e.currentTarget.index      });    }  }}</script>
复制代码


效果如下图:



list-view 只支持 APP,需要用自定义 loader 或 APPloader 调试。调试教程可查看文档APICloud Studio3 WiFi真机同步和WiFi真机预览使用说明


list-view 自带内存回收功能,可以滚动加载更多。


给 list -view 添加下拉刷新组件refresh


根据 refresh 组件文档,把 refresh 标签添加到 list-view 标签中,如下:


<template>    <list-view id="listView" class="main" enable-back-to-top onscrolltolower={this.onscrolltolower}>        <refresh class="refresh" state={refreshState} onstatechange={this.onstatechange}>            <image class={refreshIconClass} src="../../image/refresh.png"></image>            <image class={refreshLoadingClass} src="../../image/loading_more.gif"></image>            <text class="refreshStateDesc">{refreshStateDesc}</text>        </refresh>        <cell class="cell c-lc-rl_ac c-sy-border_bottom c-lc-ptb" onclick={this.itemClick}>            <img class="img" src={item.url} alt="">            <text class="title c-filling-w c-pl">{item.title}</text>        </cell>        <list-footer class="footer">            <text>加载中...</text>        </list-footer>    </list-view></template>
复制代码


把 refresh 组件的 css ,js 代码也复制到相应的 style 和 script 标签中,并在项目目录 image 标签下添加用到的两张下拉刷新图片。完整代码如下:


<template>    <list-view id="listView" class="main" enable-back-to-top onscrolltolower={this.onscrolltolower}>        <refresh class="refresh" state={refreshState} onstatechange={this.onstatechange}>            <image class={refreshIconClass} src="../../image/refresh.png"></image>            <image class={refreshLoadingClass} src="../../image/loading_more.gif"></image>            <text class="refreshStateDesc">{refreshStateDesc}</text>        </refresh>        <cell class="cell c-lc-rl_ac c-sy-border_bottom c-lc-ptb" onclick={this.itemClick}>            <img class="img" src={item.url} alt="">            <text class="title c-filling-w c-pl">{item.title}</text>        </cell>        <list-footer class="footer">            <text>加载中...</text>        </list-footer>    </list-view></template><style  src='../../css/c-layout-mini.css' scoped></style><style>.main {  width: 100%;  height: 100%;}
.cell{ width: 100%; height: 70px;}
.img{ height: 50px; width: 50px; margin-left: 10px; }.title { height: 50px; font-size: 20px; line-height: 50px;}
.footer { justify-content: center; align-items: center; }
.refresh { align-items: center; justify-content: center; background-color: #eee; } .refreshStateDesc { color: #e3007f; font-size: 13px; } .refreshIcon { position: absolute; width: 25px; height: 22px; bottom: 21px; left: 70px; transition-property: transform; transition-duration: 100ms; } .refreshIcon-normal { transform: rotate(0); visibility: visible; } .refreshIcon-dragging { transform: rotate(180deg); visibility: visible; } .refreshIcon-refreshing { visibility: hidden; } .refreshLoading { position: absolute; width: 22px; height: 22px; bottom: 21px; left: 70px; visibility: hidden; } .refreshLoading-refreshing { visibility: visible; }
</style>
<script> export default { name: 'test', data(){ return { refreshState: 'normal' } }, computed: { refreshIconClass(){ if (this.data.refreshState == 'normal') { return 'refreshIcon refreshIcon-normal'; } else if (this.data.refreshState == 'dragging') { return 'refreshIcon refreshIcon-dragging'; } else if (this.data.refreshState == 'refreshing') { return 'refreshIcon refreshIcon-refreshing'; } }, refreshLoadingClass() { if (this.data.refreshState == 'refreshing') { return 'refreshLoading refreshLoading-refreshing'; } else { return 'refreshLoading'; } }, refreshStateDesc() { if (this.data.refreshState == 'normal') { return '下拉可以刷新'; } else if (this.data.refreshState == 'dragging') { return '松开可以刷新'; } else if (this.data.refreshState == 'refreshing') { return '刷新中...'; } } }, methods:{ apiready() { this.initData(false); }, initData(loadMore) { var that = this; var skip = that.dataList?that.dataList.length:0; var dataList = []; for (var i=0;i<20;i++) { dataList[i] = { title: '项目' + (i + skip), url: '../../image/nav_tab_2.png' } } var listView = document.getElementById('listView'); if (loadMore) { that.dataList = that.dataList.concat(dataList); listView.insert({ data: dataList }); } else { that.dataList = dataList; listView.load({ data: dataList }); } }, onscrolltolower() { this.initData(true); }, itemClick(e) { api.alert({ msg: '当前项索引:' + e.currentTarget.index }); }, onstatechange(e) { var state = e.detail.state; if (state == 'normal') { this.data.refreshState = 'normal'; } else if (state == 'dragging') { this.data.refreshState = 'dragging'; } else if (state == 'refreshing') { this.data.refreshState = 'refreshing'; var that = this; setTimeout(function(){ that.data.refreshState = 'normal'; }, 2000); } } } }</script>
复制代码


wi-fi 同步到手机 loader,下拉页面,运行效果如下:



Flex 布局介绍:Flex 布局意思是弹性盒子布局,比较适合移动端场景,适配不同屏幕大小。


<div>   <div>item</div>   <div>item</div>   <div>item</div></div>
复制代码


通常可以把父元素定义为弹性盒子或称为容器,其子元素为弹性盒子的项目。flex 布局的主要功能是在主轴或交叉轴按预期排列分布项目,定义每个项目占用空间比例,并可跟随容器大小伸缩。



上图引自下面这篇博客,推荐阅读:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html


推荐一个 flex git:https://gitee.com/jiang_xincheng/c-layout

用户头像

APICloud

关注

一次编码多端运行,移动应用低代码开发平台 2020.12.22 加入

APICloud多端技术遵循标准 Web Components组件化思想,兼容Vue 、React语法特性,一次编码同时发布为Android 、iOS 、小程序、Html5(SPA)多端应用。

评论

发布
暂无评论
APICloud AVM框架列表组件list-view的使用、flex布局教程