在aardio中创建动态控件,并实现网格布局实例

breezee 4月前 699

最近做了一个小工具,需要动态创建多个控件,为了方便控件展示,还需要根据窗口尺寸自动分布显示。

这里把这个过程记录下来,中间涉及到的知识点有:

  1. 动态创建控件、组件

  2. 批量访问动态控件

  3. 控件网格布局排版

  4. 控件匹配不同DPI屏幕显示

  5. 控件容器使用滚动条

动图示意如下:




import win.ui;
import fonts.fontAwesome;
/*DSG{{*/
var winform = win.form(text="动态控件网格布局";right=783;bottom=479)
winform.add(
custom={cls="custom";text="自定义控件";left=16;top=16;right=768;bottom=236;ah=1;aw=1;bgcolor=12639424;border=1;dl=1;dr=1;dt=1;z=1};
custom2={cls="custom";text="自定义控件";left=16;top=248;right=768;bottom=468;ah=1;aw=1;bgcolor=15780518;border=1;db=1;dl=1;dr=1;z=2}
)
/*}}*/

//aardio批量创建动态控件实例,网格布局实例
//https://blog.csdn.net/wuyindesign/article/details/135631340

//创建网格布局
function createGridLayout(container/*容器控件*/, itemCode/*项目代码*/, itemCount/*项目总数*/, itemWidth/*项目宽度*/, itemHeight/*项目高度*/, margin/*项目到容器的边距*/, hgap/*项目间的水平间距*/, vgap/*项目间的垂直间距*/, fillWidth/*单列横向填充*/){
	//适配DPI
	var _, _, dpiScaleX, dpiScaleY = container.getScale();
	itemWidth *= dpiScaleX;
	itemHeight *= dpiScaleY;
	margin *= dpiScaleX;
	hgap *= dpiScaleX;
	vgap *= dpiScaleX;
	
	//保存布局选项
	var layout = {};
	layout.type = "grid";
	layout.margin = margin;
	layout.hgap = hgap;
	layout.vgap = vgap;
	layout.fillWidth = fillWidth : false; //是否横向填充
	layout.itemHeight = itemHeight;
	if (!layout.fillWidth) {
		layout.itemWidth = itemWidth;
	}
	else { //横向填充模式
		layout.itemWidth = container.width - margin * 2;
	}		
	container.layout = layout;
	
	//创建滚动条
	import win.ui.scrollbar;
	container.scrollbar = win.ui.scrollbar(container, true);
	
	//动态生成控件
	for (i=1; itemCount; 1){
    	var item = container.addCtrl(
        	["item"+i] = {cls="custom";left=0;top=0;right=itemWidth;bottom=itemHeight;dl=1;dt=1;hide=1;z=1}; //默认为隐藏状态
    	);
    	container["item"+i].index = i;
    	container["item"+i].addCtrl(table.clone(itemCode)); 
   	
 		//响应事件
    	container["item"+i].onMouseClick = function(wParam,lParam){
        	winform.msgbox(container["item"+i].name.text)
    	}
	}	

	//自动布局
	setGridLayout(container);
}

//返回容器中所有的item
function getLayoutItems(container){	
	var items = {};
	for (name, ctrl in container.eachControl("custom","item")){
		items[ctrl.index] = ctrl;
	}
	return items; 
}

//设置布局
function setGridLayout(container/*容器控件*/){
	var _, _, dpiScaleX, dpiScaleY = container.getScale(); //适配DPI
	
	//读取布局选项
	var layout = container.layout;
	var margin = layout.margin * dpiScaleX;
	var hgap = layout.hgap * dpiScaleX;
	var vgap = layout.vgap * dpiScaleX;

	var itemHeight = layout.itemHeight * dpiScaleY;
	var itemWidth = layout.itemWidth * dpiScaleX;
	if (layout.fillWidth) {
		itemWidth = container.width - margin * 2;
	}
	
	//遍历容器中的item
	var items = getLayoutItems(container);
	var itemCount = #items;

	//计算一行最多显示多少个item(列数)
	var colNum = 1; //最少1列,横向填充模式也是1列
	if (!layout.fillWidth) {		
		colNum = math.floor((container.width - margin*2 + hgap)/(itemWidth + hgap)) : 1;
	}

	//判断是否显示滚动条	
	var listHeight = (itemHeight + vgap) * math.ceil(itemCount / colNum) - vgap + margin * 2; //计算item列表的总高度
	if (container.scrollbar) {
		container.scrollbar.show(listHeight > container.height);		
		//当布局类型为横向填充,且出现滚动条时,缩小item宽度,避让滚动条
		if (layout.fillWidth && listHeight > container.height) {
			itemWidth = itemWidth - User32.GetSystemMetrics(2/*_SM_CXVSCROLL*/);
		}
	}

	//第一列item的起始点
	var marginLeft = margin;
	
	//动态调整item尺寸和位置
	var itemLeft = marginLeft;
	var itemTop = margin;
	var itemRight = itemLeft + itemWidth;
	var itemBottom = itemTop + itemHeight;

	for (i=1; itemCount; 1){
		items[i].left = itemLeft;
		items[i].top = itemTop;
		items[i].right = itemRight;
		items[i].bottom = itemBottom;
    	items[i].hide = false;    	   	

    	//计算下一个item的位置
    	itemLeft = itemRight + hgap;
    	itemRight = itemLeft + itemWidth;
    	if (i % colNum == 0){
        	itemLeft = marginLeft; //超出一行最大显示个数,left回到起始点
        	itemRight = itemLeft + itemWidth;
        	itemTop = itemBottom + vgap;        	
        	itemBottom = itemTop + itemHeight;
    	}   	
	}
}

//动态控件的模板
var itemTemplate = {
    icon = {cls="plus";left=0;top=0;right=120;bottom=48;align="left";color=3947580;dl=1;dt=1;iconColor=16711680;iconStyle={font=LOGFONT(h=-48;name='FontAwesome')};iconText='\uF007';paddingBottom=5;paddingLeft=3;paddingRight=3;paddingTop=5;z=2};
    name = {cls="static";left=120;top=0;right=360;bottom=28;dl=1;dt=1;font=LOGFONT(h=-16);transparent=1;z=3};
    status = {cls="static";left=120;top=28;right=360;bottom=48;color=8421504;font=LOGFONT(h=-11);dl=1;dt=1;transparent=1;z=4};
}

//创建第一个表格布局
var itemCount = 5; //item总数
var itemWidth, itemHeight = 360, 48; //item宽度/高度
var margin = 8; //item到容器间的距离
var hgap, vgap = 15, 10; //item之间的横间距/竖间距
createGridLayout(winform.custom, itemTemplate, itemCount, itemWidth, itemHeight, margin, hgap, vgap);

//修改每个item的内容
var layoutItems = getLayoutItems(winform.custom);
for(i=1; #layoutItems; 1){
	layoutItems[i].name.text = "客户名称"+i;   
	layoutItems[i].status.text = ">> 这里是简介信息"+i;
}

//创建第二个表格布局,横向填充模式
//修改控件模板
var itemTemplate2 = table.clone(itemTemplate);
itemTemplate2["listview"] = {cls="listview";border=1;left=0;top=48;right=800;bottom=120;aw=1;dl=1;dt=1;fullRow=1;transparent=1;z=5};
createGridLayout(winform.custom2, itemTemplate2, 2, 800, 120, margin, hgap, vgap, true);

//修改每个item的内容
var layoutItems2 = getLayoutItems(winform.custom2);
for(i=1; #layoutItems2; 1){
	layoutItems2[i].name.text = "客户名称"+i; 
	layoutItems2[i].status.text = ">> 这里是简介信息";
	layoutItems2[i].listview.setColumns({"姓名";"性别";"年龄"})
	layoutItems2[i].listview.items = {{"111";"222";"333"};{"111";"222";"333"}};
}

//窗体缩放的时,自动重新布局
winform.adjust = function( cx,cy,wParam ) {	 
	for(name,ctrl in winform.eachControl("custom") ){
		if (ctrl.layout){
			setGridLayout(ctrl);
		}
	}
}; 

winform.show();
win.loopMessage();



最新回复 (5)
  • 光庆 4月前
    0 2

  • breezee 4月前
    0 3
    光庆
    在光庆大佬面前班门弄斧了,你的pluslist库功能更完善,我这只是自己瞎琢磨
  • Viewer8122 4月前
    0 4
    谢谢分享~!
  • lcj21 4月前
    0 5
    不错,学习了。
  • niheibie 3月前
    0 6
    66666666
返回