HarmonyOS三方件開發(fā)指南(18)-Flexbox流式布局組件
引言
上一篇給大家介紹底部導航欄的組件使用及開發(fā)指南,本篇將給大家?guī)砹硪粋€鴻蒙三方件的是實現(xiàn):Flexbox,何為Flexbox,如果對Java的Swing比較熟悉的話一定不會陌生,就是控件根據(jù)ViewGroup的寬,自動的往右添加,如果當前行剩余空間不足,則自動添加到下一行。有點所有的控件都往左飄的感覺,第一行滿了,往第二行飄~所以也叫流式布局。鴻蒙并沒有提供流式布局,但是某些場合中,流式布局還是非常適合使用的,比如關鍵字標簽,搜索熱詞列表等,比如下圖:
這些都特別適合使用Flexbox,本篇會帶領大家自己實現(xiàn)Flexbox,然后使用我們自己定義的Flexbox實現(xiàn)上面的標簽效果。學會使用一個控件和學會寫一個控件,我相信大家都明白,授人以魚不如授人以漁。
接下來看下鴻蒙模擬器的實現(xiàn)效果,效果圖如下:
圖(1)默認標簽狀態(tài)
圖(2)標簽選中狀態(tài)
VideoCache使用指南
Ø 新建工程, 添加組件Har包依賴
在應用模塊中添加HAR,只需要將flexboxlibrary-debug.har復制到entry\libs目錄下即可
Ø 修改配置文件
1. 在布局中添加如下代碼:
- <com.istone.flexboxlibrary.HWFlowViewGroup
- ohos:id="$+id:viewgroup"
- ohos:height="match_content"
- ohos:width="match_parent"
- ohos:background_element="gray"
- ohos:orientation="vertical"
- />
2.在代碼中通過以下方式使用:
- //mNames 是item的數(shù)據(jù)源,可以是任意需要顯示的數(shù)據(jù)類型,根據(jù)實際情況去定義
- parentLayout = (HWFlowViewGroup) findComponentById(ResourceTable.Id_viewgroup);
- parentLayout.HWFlowViewGroup(getContext(), mNames, parentLayout);
- parentLayout.setOnItemClickListener((Component view) -> {
- //item點擊之后的回調(diào)
- Text text = (Text)view;
- if(text.isSelected()){
- text.setTextColor(Color.BLACK);
- }else{
- text.setTextColor(Color.WHITE);
- }
- });
- 1.
VideoCache開發(fā)指南
在上述中,已經(jīng)說明Flexbox 如何在開發(fā)過程中使用,接下來簡單的分析下Flexbox 實現(xiàn)思路
1、對于Flexbox ,需要指定的LayoutConfig,我們目前只需要能夠識別margin、padding即可
2、measureChild中計算所有childView的寬度,然后根據(jù)childView的寬度,計算當前每一行的寬度
3、最后根據(jù)計算之后的寬度,對中所有的childView進行布局。
以text為例,計算每個childView 的代碼如下:
- private float measureChild(Text text) {
- Paint paint = new Paint();
- paint.setTextSize(text.getTextSize());
- float childWidth = paint.measureText(text.getText());
- childWidth = childWidth + text.getPaddingLeft() + text.getPaddingRight() + text.getMarginLeft() + text.getMarginRight();
- return childWidth;
- }
- 1.
初始化每行的布局,代碼如下:
- private DirectionalLayout initDirtLayout() {
- DirectionalLayout childLayout = new DirectionalLayout(mContext);
- childLayout.setOrientation(Component.HORIZONTAL);
- DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_CONTENT);
- layoutConfig.setMargins(10, 10, 10, 10);
- childLayout.setLayoutConfig(layoutConfig);
- return childLayout;
- }
獲取屏幕的寬度,代碼如下:
- private void getParentWidthAndHeight() {
- Optional<Display> display = DisplayManager.getInstance().getDefaultDisplay(mContext);
- Point pt = new Point();
- display.get().getSize(pt);
- mParentWidth = (int) pt.getPointX();
- }
動態(tài)布局:
- private void initChildViews() {
- for (int i = 0; i < mNames.length; i++) {
- Text text = new Text(mContext);
- text.setId(i);
- text.setText(mNames[i]);
- text.setTextSize(100);
- text.setSelected(false);
- text.setTextColor(Color.WHITE);
- text.setPadding(10, 10, 10, 10);
- ShapeElement background = new ShapeElement();
- background.setRgbColor(new RgbColor(205, 92, 92));
- text.setBackground(background);
- DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_CONTENT);
- layoutConfig.setMargins(20, 10, 20, 10);
- text.setLayoutConfig(layoutConfig);
- if (i == 0) {
- childLayout = initDirtLayout();
- mLineWidth = measureChild(text);
- childLayout.addComponent(text);
- } else {
- mLineWidth = mLineWidth + measureChild(text);
- if (mLineWidth > (mParentWidth - childLayout.getMarginLeft() - childLayout.getMarginRight())) {
- mParentLayout.addComponent(childLayout);
- childLayout = initDirtLayout();
- mLineWidth = measureChild(text);
- }
- childLayout.addComponent(text);
- if (i == mNames.length - 1) {
- mParentLayout.addComponent(childLayout);
- }
- }
- ComponentBean bean = new ComponentBean(text, false);
- list.add(bean);
- text.setClickedListener(component -> {
- text.setSelected(!text.isSelected());
- mOnItemClickListener.onItemClick(text);
- });
- }
- }
定義接口,實現(xiàn)item的點擊事件
- public interface OnItemClickListener {
- void onItemClick(Component view);
- }
- public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
- mOnItemClickListener = onItemClickListener;
- }
按照思路看下來,是不是很簡單呢?我們只需要把握住如何計算childview 的寬度,以及什么情況下添加新的一行即可。
更多原創(chuàng),請關注:https://harmonyos.51cto.com/column/30