Fusion App2.0已经在内测了,笔者有幸参与,发现新版有许多亮点,比如:UI更美观了、源码管理更有序了、编辑器更好用了、新增代码回溯功能等。下面记录一下旧版本工程迁移到新工程的一些笔记。

旧版本工程:fas文件

新版本工程:fap文件

 

弃用 替代 需导入包
CardView MaterialCardView import “com.google.android.material.card.MaterialCardView”
PageView ViewPager import “androidx.viewpager.widget.ViewPager”
CircleImageView ShapeableImageView import “com.google.android.material.imageview.ShapeableImageView”

准确得说CardView未被弃用,只要你导入包import “androidx.cardview.widget.CardView”

一、FusionApp基本

1、UI事件

顶栏搜索功能回调事件
onSearchEvent(keyword)

侧滑栏列表点击事件
onDrawerListItenClick(data,recyclerview,listIndex,itemIndex)

顶栏菜单项目点击事件
onMenuItemClick(title)

悬浮按钮点击事件
onFloatingActionButtonClick(v)

2、设置点击事件

为了更好的运行效率和代码复用,FusionApp已将UI事件注册在main.lua中,您需要简单学习本文,以了解如何为您添加的项目设置点击事件

设置顶栏/菜单栏按钮点击事件

假设您在应用栏>菜单项中添加了三个菜单标题分别为:橘子、苹果、菠萝的菜单项,那么您可以这样写它的点击事件

--初始化一张点击事件表
functions={}

functions["橘子"]=function()
 print("剥了橘子")
end

functions["苹果"]=function()
 print("削了苹果")
end

functions["菠萝"]=function()
 print("吃了菠萝")
end

--[=[同理,需要写哪个项目的点击事件就添加
functions["你的项目标题"]=function()
end
以上代码块到文件中]=]

--注册点击事件,如无其它需求,不用扩展写
function onMenuItemClick(title)
  local event=functions[title]
  if(event~=nil)then
    event()
  end
end

设置侧滑栏列表点击事件

假设您在侧滑栏>侧滑栏列表中添加了三个标题分别为:菠萝派、香芋派、红豆派的菜单项,那么您该这样写它的点击事件

--初始化一张点击事件表
functions={}

functions["香芋派"]=function()
 print("4月10日吃了麦当劳的香芋派")
end

functions["菠萝派"]=function()
 print("4月13日吃了麦当劳的菠萝派")
end

functions["红豆派"]=function()
 print("肯德基送了一张红豆派买一送一券")
end

--[=[仍然同理,需要写哪个项目的点击事件就添加

functions["你的项目标题"]=function()
end

以上代码块到文件中]=]

--注册点击事件,如无其它需求,不用扩展写
function onDrawerListItemClick(data, recyclerView, listIndex, itemIndex)
    --侧滑栏列表的数据是二维结构,所以需要先获取到点击项目所在列表的数据
    local listData = data.get(listIndex);
    --获取到所在列表的数据后获取点击项目的数据
    local itemData = listData.get(itemIndex);
    --最后获取到点击的项目的标题
    local title = itemData.getTitle();
    local event=functions[title]
    if(event~=nil)then
      event()
    end
end

3、加载图片

引入图片

如需加载本地图片,请将工程需要用到的所有本地图片放置在工程目录/images文件夹中,填写相对路径后,FusionApp会自动使用Glide框架为您加载

兼容方式:也可直接放置在所加载页面同目录下,但为了更好的复用和更清晰的项目结构,您应当以上条为标准放置您的图片资源

加载图片

假设/images目录中放置了一张名为a.png的文件。

在布局文件中填写图片相对路径,即可引入。

{
  ImageView
  layout_width="wrap",
  layout_height="wrap",
  src="/a.png",
}

获取图片路径和手动加载图片

使用Glide时不支持填写图片相对路径,如需手动获取图片绝对路径以利用Glide为您的项目载入图片资源,请使用activity中的Loader类

--填写图片名称,获取到图片的绝对路径
local path=activity.loader.getImagesDir("图片名称")
--使用glide加载
Glide.with(activity).load(path).into(imageView)

或者直接使用Loader类来加载

this.loader.loadImage(imageView,"图片名称")

4、部分常用API参考

activity.startFusionActivity(pageName,[bundle]) 跳转到其它页面

activity.getLoader().getFusionDir() 获取当前运行目录

activity.getViewConfig() 获取应用配置

getLoader().updatePageConfig() 更新应用配置

activity.setSharedData(“key”,”value”) 设置应用共享数据

activity.getSharedData(“key”) 获取应用共享数据

5、接口的使用

以下代码块展示了如何创建接口以及如何为组件注册接口

require "import"
import "com.google.android.material.button.MaterialButton"
import "android.view.View"
local button=MaterialButton(activity)
--创建接口
local listener=View.OnClickListener{onClick = function(v)
end}
--把接口注册到组件
button.setOnClickListener(listener)
--也可以使用匿名函数注册
button.setOnClickListener{onClick = function(s)
        print("点击")
        end
    }
--onxxx事件可以简写
button.onClick=function(v)
    print(v)
end

6、 Webview相关API

本示例仅演示基础使用,WebView是Android端强大的浏览器控件,更多的特性需要您善用Google及相关Android文档查询。

获取WebView

local uiManager=activity.getUiManager()

--获取当前页面的WebView
local webView=uiManager.getCurrentFragment().getWebView()

--获取其它页面的WebView
uiManager.getFragment(number).getWebView()

基本API

--获取当前页面的URL
local url=webView.getUrl()

--获取当前页面的原始URL(重定向后可能当前url不同)
--就是http headers的Referer参数,loadUrl时为null
local originalUrl=webView.getOriginalUrl()

--获取当前页面的标题
local title=webView.getTitle()

--获取当前页面网站的favicon
local iconBitmap=webView.getFavicon()

--获取当前页面的加载进度
local progress=webView.getProgress()

--通知WebView内核网络状态
--用于设置JS属性`window.navigator.isOnline`和产生HTML5事件`online/offline`
webView.setNetworkAvailable(true/false)

加载网页相关API

--加载URL指定的网页
loadUrl("网页链接")

--携带http headers加载URL指定的网页
loadUrl("网页链接", Map<String, String> additionalHttpHeaders)

--使用POST请求加载指定的网页
postUrl(String url, byte[] postData)

--重新加载当前网页
reload()

--加载内容
loadData("数据", mimeType, encoding);

--使用baseUrl加载内容
loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl)

导航相关API

--复制一份BackForwardList
copyBackForwardList()

--浏览器是否可后退
canGoBack()

--浏览器是否可前进
canGoForward()

--是否可前进/后退steps页,大于0表示前进小于0表示后退
canGoBackOrForward(steps)

--后退一页
goBack()

--前进一页
goForward()

--前进/后退steps页,大于0表示前进小于0表示后退
goBackOrForward(steps)

--清除当前webview访问的历史记录
clearHistory()

网页查找相关API

--设置网页查找结果回调
setFindListener(FindListener listener)

--异步执行查找网页内包含的字符串并设置高亮,查找结果会回调.
findAllAsync("需查找的关键词")

--查找下一个匹配的字符串
findNext(forward)

--清除网页查找的高亮匹配字符串
clearMatches()

保存网页/翻页与缩放

--保存网页(.html)到指定文件
saveWebArchive("文件路径")

--保存网页(.html)到文件
saveWebArchive(basename, autoname,callback);

--上翻一页,即向上滚动WebView高度的一半
pageUp(true/false)

--下翻一页,即向下滚动WebView高度的一半
pageDown(boolean bottom)

--缩放
zoomBy(0.5)

--放大
zoomIn()

--缩放
zoomOut()

7、创建布局

请您阅读本文,使用.aly布局表为您的应用创建更精美的布局,布局表支持安卓控件的大部分属性

与原生安卓XML布局文件的不同点

  1. id表示在Lua中变量的名称,而不是安卓的可以findViewById的常量id。
  2. ImageView的src属性是当前目录图片名称或绝对文件路径图片或网络上的图片。
  3. layout_width与layout_height的值支持fill与wrap简写。
  4. onClick值为lua函数或java onClick接口或他们的全局变量名称。
  5. 背景background支持背景图片,背景色与LuaDrawable自绘制背景,背景图片参数为是当前目录图片名称或绝对文件路径图片或网络上的图片,颜色同backgroundColor,自绘制背景参数为绘制函数或绘制函数的全局变量名称。
  6. 控件背景色使用backgroundColor设置,值为”十六进制颜色值”。
  7. 尺寸单位支持 px,dp,sp,in,mm,%w,%h。

使用布局表前请先使用”import”导入需使用的控件的Java类。

require "import"
import "android.widget.*"
import "com.google.android.material.card.MaterialCardView"

--布局表格式
--[[layout={
    控件类名称,
    id=控件名称,
    属性=值,
    {
        子控件类名称,
        id=控件名称,
        属性=值,
        }
    }
]]

--例如:
layout={
  LinearLayout,--视图类名称
  id="linear",--视图ID,可以在loadlayout后直接使用
  orientation="vertical",--属性与值
  {
    MaterialCardView,--子视图类名称
    cardElevation="4dp",--属性与值
    layout_width="fill",--布局属性
    layout_height="wrap",
    layout_margin="20dp",
  },
}
--使用loadlayout函数解析布局表生成布局。
activity.setContentView(loadlayout(layout))
--也可以简化为:
activity.setContentView(layout)
--如果使用单独文件布局(比如有个layout.aly布局文件)也可以简写为:
activity.setContentView("layout")
--此时不用导入布局文件。

8、监听浏览器事件

获取到当前页面的Fragment并为其中的浏览器设置事件监听,如果想为指定页的浏览器设置监听事件,请使用this.uiManager.getFragment(index)方法获取碎片并设置。

require"import"
import "net.fusionapp.core.ui.fragment.WebInterface"
local uimanager=activity.uiManager
local fragment=uimanager.currentFragment
fragment.setWebInterface(WebInterface{
  onPageFinished=function(view,url)
    --页面加载结束事件
  end,
  onPageStarted=function(view,url,favicon)
    --页面开始加载事件
  end,
  onReceivedTitle=function(view,title)
    --获取到网页标题时加载的事件
  end,
  onLoadResource=function(view,url)
    --页面资源加载监听
    --可通过该方法获取网页上的资源
  end,
  onUrlLoad=function(view,url)
    --即将开始加载事件,url参数是即将加载的url
    --该函数返回一个布尔值
    --返回true则拦截本次加载  
    return false
  end
})

9、界面之间的交互

您可以在工程编辑器中点击右上角,新建页面,页面名称只能输入英文名

跳转到其它界面并传递参数

--创建一个bundle,用于传递参数
--如果没有参数,则不要传递bundle
local bundle=Bundle()
bundle.putString("key","value")
--bundle.putInt("key",0)
activity.startFusionActivity("页面名称",bundle)

获取其它界面传递过来的参数

local intent=activity.getIntent()
print(intent.getStringExtra("key"))

跳转界面:简易方式

跳转界面

local value="需要传递的值"
activity.newActivity("页面名称",{value})

接收参数

local value=...
print(...)

10、UiManager API参考

UiManager是FusionApp里您的应用视图控件的管理者,请参考本文,已明确如何使用UiManager在代码里控制您的应用Ui。

获取UiManager

--获取到uiManager
local uiManager=this.uiManager

获取界面中的控件

local viewPager=uiManager.viewPager
--获取页视图

local edittext=uiManager.searchEditText
--获取顶栏搜索输入框控件

local recyclerView=uiManager.recyclerView
--获取抽屉栏的列表视图,可用于自定义抽屉栏的列表

local textview=uiManager.drawerHeaderSecondaryTextView
--获取抽屉栏页眉副文本TextView

local textview=uiManager.drawerHeaderMainTextView
--获取抽屉栏页眉主文本TextView

local wallpaper=uiManager.drawerWallpaper
--获取抽屉栏壁纸ImageView

local avatarImageView=uiManager.drawerHeaderAvatarImageView
--获取抽屉栏头像ImageView

local coordinator=uiManager.coordinatorLayout
--获取协调者布局,创建snackbar时需要使用此视图作为第一个参数

local fragment=uiManager.getFragment(index)
--获取当前的浏览页

local currentPage=uiManager.currentFragment
--获取当前浏览页碎片视图

local drawerly=uiManager.drawerLayout
--获取DrawerLayout

local appBar=uiManager.appBarLayout
--获取AppBar

local indicatorView=uiManager.indicatorView
--获取指示器视图

local pagerAdapter=uiManager.pagerAdapter
--获取ViewPager的适配器

关于应用栏

--获取toolbar
local toolbar=uiManager.toolbar
--设置toolbar标题
toolbar.titleText="标题"
--设置toolbar子标题
toolbar.subTitleText="子标题"

页面状态

isUnfoldSearchBar()
--搜索栏是否展开

toggleDrawer()
--开/关 抽屉栏

closeDrawer()
--关闭抽屉栏

获取页面配置数据

local themeConfig=uiManager.themeConfig
--获取主题配置

local viewConfig=getViewConfig()
--获取当前视图配置模型数据类,可查看view.json的结构以清楚它的属性

local colors=getColors()
--获取当前视图主题配色数据类

--colors.colorPrimary
--获取主题的主色,返回一个十六进制字符串。

--colors.colorAccent
--获取主题的强调色

--colors.textColorPrimary
--获取主题的主文本色

--colors.textColorSecondary
--获取主题的副文本色

--更多属性请自行查看主题文件。

二、部分框架使用

1、Glide图片加载框架

在图片加载上,十分的不建议您继续使用loadbitmap方法。

新版支持了Google推荐的Glide图片加载框架,请您使用该框架,为您的项目更高效轻快的加载图片,只需一句代码,全程掌控图片对象的生命周期,您无需担心任何内存泄漏与加载速度的问题。

如何最简单的使用?

import "com.bumptech.glide.Glide"
local url="图片路径"
Glide.with(activity).load(url).into(imageView)

2、ShareCompat分享

分享媒体资源或文本信息给手机上的其它应用是我们的App常用需求之一。 想要更兼容、更便捷的分享内容到其它应用,请您参考本示例,使用AndroidX框架中的ShareCompat分享框架,为您的App实现分享功能

ShareCompat 分享文本

import "androidx.core.app.ShareCompat"
ShareCompat.IntentBuilder
 .from(activity)
 .setText("文本内容")
 .setType("text/plain")
 .startChooser();

ShareCompat 分享文件或图片

import "net.fusionapp.core.MyFileProvider"
import "java.io.File"
import "androidx.core.app.ShareCompat"
local file=File("文件路径")
local uri = MyFileProvider.getUriForFile(activity, MyFileProvider.getAuthor(activity), file)
--文件的mime类型
local mimetype = "image/png"
ShareCompat.IntentBuilder
 .from(activity)
 .setStream(uri)
 .setType(mimetype)
 .startChooser() 

3、Material输入框组件

Material输入框组件: TextInputEditText

require "import"
import "android.widget.*"
import "com.google.android.material.textfield.*"
import "androidx.appcompat.widget.Toolbar"
import "com.google.android.material.button.MaterialButton"
import "com.google.android.material.appbar.AppBarLayout"
import "android.graphics.Color"
import "com.google.android.material.card.MaterialCardView"

local view_table=
{LinearLayout,
  layout_width="match",
  layout_height="match",
  orientation=1,
  {
    AppBarLayout,
    layout_width="match",
    layout_height="wrap",
    {
      Toolbar,
      layout_width="match",
      layout_height="wrap",
      --subTitle="",
      title="MaterialCardView",
    },
  },
  {MaterialCardView,
    id="cardview",--设置ID
    layout_height="wrap",
    layout_width="fill",
    layout_margin="24dp",
    --strokeWidth="2dp", --边框宽度
    --strokeColor="#03DAC5", --边框颜色
    cardBackgroundColor="#ffffff",--卡片背景色
    cardElevation="2dp",--卡片阴影强度
    radius="4dp",--卡片圆角幅度    
    {LinearLayout,
      layout_height="wrap",
      layout_width="match",
      orientation=1,
      padding="24dp",
      {TextView,
        id="title",
        textSize="18sp",
        text="什么是MaterialCardView?",
        textColor="#000000",
        textStyle="bold"
      },
      {TextView,
        id="message",
        textSize="16sp",
        text="MaterialCardView 是 CardView 的拓展,它继承与 CardView,所以 CardView 具备的它都具备,除此之外,它还在 CardView 的基础上增加了可以绘制边框这一特性,分别为 strokeColor 和 strokeWidth 这两个属性",
        layout_marginTop="8dp",
        textColor="#444444",
      },
    },
  },
  {
    MaterialButton,
    id="button",
    text="设置边框",
    layout_gravity="right",
    layout_marginRight="24dp"
  },
}

activity.setContentView(loadlayout(view_table))
activity.window.statusBarColor=Color.parseColor("#03DAC5")

button.onClick=function()
  cardview.strokeWidth=4
  cardview.strokeColor=Color.parseColor("#03DAC5")
end

4、Material卡片组件

Material卡片组件: MaterialCardview
require "import"
import "android.widget.*"
import "com.google.android.material.textfield.*"
import "androidx.appcompat.widget.Toolbar"
import "com.google.android.material.button.MaterialButton"
import "com.google.android.material.appbar.AppBarLayout"
import "android.graphics.Color"
import "com.google.android.material.card.MaterialCardView"

local view_table=
{LinearLayout,
  layout_width="match",
  layout_height="match",
  orientation=1,
  {
    AppBarLayout,
    layout_width="match",
    layout_height="wrap",
    {
      Toolbar,
      layout_width="match",
      layout_height="wrap",
      --subTitle="",
      title="MaterialCardView",
    },
  },
  {MaterialCardView,
    id="cardview",--设置ID
    layout_height="wrap",
    layout_width="fill",
    layout_margin="24dp",
    --strokeWidth="2dp", --边框宽度
    --strokeColor="#03DAC5", --边框颜色
    cardBackgroundColor="#ffffff",--卡片背景色
    cardElevation="2dp",--卡片阴影强度
    radius="4dp",--卡片圆角幅度    
    {LinearLayout,
      layout_height="wrap",
      layout_width="match",
      orientation=1,
      padding="24dp",
      {TextView,
        id="title",
        textSize="18sp",
        text="什么是MaterialCardView?",
        textColor="#000000",
        textStyle="bold"
      },
      {TextView,
        id="message",
        textSize="16sp",
        text="MaterialCardView 是 CardView 的拓展,它继承与 CardView,所以 CardView 具备的它都具备,除此之外,它还在 CardView 的基础上增加了可以绘制边框这一特性,分别为 strokeColor 和 strokeWidth 这两个属性",
        layout_marginTop="8dp",
        textColor="#444444",
      },
    },
  },
  {
    MaterialButton,
    id="button",
    text="设置边框",
    layout_gravity="right",
    layout_marginRight="24dp"
  },
}

activity.setContentView(loadlayout(view_table))
activity.window.statusBarColor=Color.parseColor("#03DAC5")

button.onClick=function()
  cardview.strokeWidth=4
  cardview.strokeColor=Color.parseColor("#03DAC5")
end

5、悬浮按钮组件

悬浮按钮组件: FloatingActionButton
require "import"
import "com.google.android.material.floatingactionbutton.FloatingActionButton"
import "android.widget.*"

local layout={FrameLayout,
  layout_height="fill",
  layout_width="fill",
  {FloatingActionButton,
    id="fab",
    layout_height="wrap",
    layout_width="fill",
    layout_gravity="bottom|right",
    layout_margin="24dp",
  },
}

activity.setContentView(loadlayout(layout))

import "com.bumptech.glide.Glide"
--imgres可以是本地图片地址,或者网络链接,图片文件bytes 等等
local imgres=activity.getExternalFilesDir(null).absolutePath.."/material-icons/content/add"
Glide.with(activity).load(imgres).into(fab);

--设置点击事件###
fab.onClick=function()
  print("点击了FAB")
end

6、对话框组件

MaterialAlertDialogBuilder对话框组件

旧版本的”泡沫对话框”现在已弃用,请您根据以下示例使用更标准的Material对话框组件

require("import")
import"com.google.android.material.dialog.MaterialAlertDialogBuilder"

dialog=MaterialAlertDialogBuilder(activity)
dialog.setTitle("标题")
dialog.setMessage("这是对话框消息")
dialog.setNeutralButton("中立",nil)
dialog.setPositiveButton("积极",{
  onClick=function()
   print("点击了积极按钮")
  end
})
dialog.setNegativeButton("消极",{
  onClick=function()
   print("点击了消极按钮")
  end
})
dialog.show()

设置列表

local items={"列表项目1","列表项目2","列表项目3"}
dialog.setItems(items,{
  onClick=function(dialog,i)
    print("点击了"..items[i+1])
  end
})

设置单选列表

local items={"单选列表项目1","单选列表项目2","单选列表项目3"}
local selectIndex=1 --选中项索引
dialog.setSingleChoiceItems(items,selectIndex,{
  onClick=function(dialog,i)
    print("选择了"..items[i+1])
  end
})

设置多选列表

local items={"列表项目1","列表项目2","列表项目3","列表项目4"}
local checkedItems={true,false,true,false}
dialog.setMultiChoiceItems(items,checkedItems,{
  onClick=function(dialog,i,isChecked)
    checkedItems[i+1]=isChecked
  end
})
dialog.setPositiveButton("确定",{
  onClick=function()
    local s="选中了"
    for i,v in ipairs(items) do
      if(checkedItems[i])then
        s=s..v
      end
    end
  print(s)
  end
})

7、Materia消息栏组件

Materia消息栏组件: Snackbar

require "import"
import "android.view.View"
import "com.google.android.material.snackbar.Snackbar"

local anchor=activity.findViewById(android.R.id.content)

Snackbar.make(anchor, "Snackbar提示消息", Snackbar.LENGTH_LONG).setAction("按钮", View.OnClickListener{
  onClick=function(v)
    print("点击了按钮")
  end
}).show();






文件名称:FusionApp2.0
适用版本:Android / HarmonyOS
更新日期:2021-05-09
文件大小:60.7M


Invitation
QQ Group
1095632335

created:04/01/2020

Welcome to the Group

Use this card to join us and participate in a pleasant discussion together .

Welcome to JISHUSONGSHU Group,wish you a nice day .