尽量不要使用以下事件:松开右键、双击左键。原因是移动平台不支持或不推荐这些操作。
原则上不再支持使用水平滚动条,为此尽量不让出现水平滚动。实在避免不了,1)只让小幅滚动,2)界面让有较好提示,举个例子,要在一行显示10个按钮,而每屏最多只能显示两个,那在每个按钮左上角放上(1/10)字样,让用户很快知道前、后还有多少内容。
一、布局
1.1 栈层(stack)
单选(radio)模式,用在场景时,需打勾“最大页的标称尺寸作为该控件的标称尺寸”
对单选模式,如果不打勾该选项,控件的标称尺寸等于当前正显示layer的标称尺寸。为什么不像画中画一样取所有layer中最大的标称尺寸。
- 按布局规则,INVISIBLE状态的控件不应该计算标称尺寸,layer也是控件,一旦不符合就会造成错误。举个例子,要用layout_init置text_maximum_width_为0,而tgrid::layout_init只清visible!=twidget::INVISIBLE的栅格,此时若计算visible==twidget::INVISIBLE栅格标称尺寸,会使得当中存在多行文本控件时,用不是0的text_maximum_width_去计算,导致算出过大标称尺寸。
- app可能在每个layer放上复杂布局,每次计算标称尺寸时都要算所有layer会影响效率。举个例子,该窗口从上到下以着header、body、navigation布局,body顶层就是个stack,然后通过navigation切换到相应layer。
回到问题,为什么场景下得打勾控件的标称尺寸取最大页的,让看一个示例。
一stack有两个layer:tb_normal_layer(标称高度50)和tb_share_layer(标称高度45)。现在要从tb_share_layer切换到tb_normal_layer。因为当前正显示的layer是tb_share_layer,计算渲染尺寸是根据它来的,值是(1080, 45)。要切到换tb_normal_layer,这时要计算标称尺寸,这个是按切换到的tb_normal_layer来的,算出的是(450, 50)。由于标称高度50大于渲染高度45,set_radio_layer(layer)中的tgrid::place认为放不下,抛出异常。此时tgrid::place中的grid是tb_normal_layer,是那个要被显示的grid。
<librose>/gui/widgets/stack.cpp
------
void tstack::set_radio_layer(int layer)
{
...
if (desire_visible_grid != nullptr) {
if (window->layouted()) {
// below logic likes invalidate_layout
desire_visible_grid->clear_text_maximum_width();
// 此时已在显示tb_normal_layer, 如果不打勾选项,算出的是此layer的标称高度50
tpoint size = get_best_size();
// size是现在正在用的渲染尺寸。如果不打勾选项,基于的标称尺寸是根据tb_share_layer算出的,高度是45
bool require_layout = size.x > w_ || size.y > h_;
if (!require_layout) {
size = calculate_best_size_bh(w_);
require_layout = size.x > w_ || size.y > h_;
}
if (!require_layout || window->is_scene()) {
// 场景时,不管将有的标称高度有没有大于现在的渲染高度,都会进入这里
desire_visible_grid->place(get_origin(), get_size());
} else {
// 场景时,trigger_invalidate_layout(window)是个空操作,因而不会进入这里
// if this best_size > last render_size, -->layout
lock.reset();
trigger_invalidate_layout(window);
}
}
...
}
}解决办法。
- stack计算渲染尺寸时,使用tb_normal_layer的。——此时显示上已切换到tb_normal_layer,但只能计算标称尺寸。渲染尺寸只能使用之前,而之前的i渲染尺寸是根据之前正显示的layer计算的,即tb_share_layer。
- 不调用tgrid::place,而是告知重布局整个窗口。——场景时,trigger_invalidate_layout(window)是个空操作,没有重布局窗口功能。
- 把此个stack配置成“最大页的标称尺寸作为该控件的标称尺寸”。
采用第三种方案。这也要求,在场景中,使用的stack控件必须打勾“最大页的标称尺寸作为该控件的标称尺寸”。
1.2 报表(report)
对多行报表,如果各个单元控件含有长、短不一文字,建议给宽度的标称尺寸设个固定值。原因是多行时,一旦宽度没有设固定值,报表单元标称尺寸取的是第一个显示单元的标称尺寸。设固定值能避免报表布局受第一个单元是啥文字的影响。
举个例子,有一个单元类型是vertical_node风格按钮的多行报表。在t1时刻,第一个单元底下文字是“聊天”,算出的标称尺寸是(96, 116),此时报表会按96这个宽度去布局每个单元(多行报表时,每单元尺寸必相等)。在t2时刻,第一个单元文字是“去位置”,算出标称尺寸是(108, 116),此时报表会变成按108这个宽度去布局每个单元。