手把手带你实现一个鸿蒙三方件!
The following article is from 鸿蒙技术社区 Author 软通田可辉
作者 | 软通田可辉
来源 | 鸿蒙技术社区(ID:gh_4d9eccaaf99e)
何为 Flexbox?如果对 Java 的 Swing 比较熟悉的话一定不会陌生,就是控件根据 ViewGroup 的宽,自动的往右添加,如果当前行剩余空间不足,则自动添加到下一行。
有点所有的控件都往左飘的感觉,第一行满了,往第二行飘~所以也叫流式布局。
鸿蒙并没有提供流式布局,但是某些场合中,流式布局还是非常适合使用的,比如关键字标签,搜索热词列表等。
这些都特别适合使用 Flexbox,本篇会带领大家自己实现 Flexbox,然后使用我们自己定义的 Flexbox 实现上面的标签效果。
学会使用一个控件和学会写一个控件,我相信大家都明白,授人以鱼不如授人以渔。
图 2:标签选中状态
01
VideoCache 使用指南
①新建工程, 添加组件 Har 包依赖
在应用模块中添加 HAR,只需要将 flexboxlibrary-debug.har 复制到 entry\libs 目录下即可。
②修改配置文件
<com.istone.flexboxlibrary.HWFlowViewGroup
ohos:id="$+id:viewgroup"
ohos:height="match_content"
ohos:width="match_parent"
ohos:background_element="gray"
ohos:orientation="vertical"
/>
在代码中通过以下方式使用:
//mNames 是item的数据源,可以是任意需要显示的数据类型,根据实际情况去定义
parentLayout = (HWFlowViewGroup) findComponentById(ResourceTable.Id_viewgroup);
parentLayout.HWFlowViewGroup(getContext(), mNames, parentLayout);
parentLayout.setOnItemClickListener((Component view) -> {
//item点击之后的回调
Text text = (Text)view;
if(text.isSelected()){
text.setTextColor(Color.BLACK);
}else{
text.setTextColor(Color.WHITE);
}
});
02
VideoCache 开发指南
以 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;
}
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();
}
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);
});
}
}
public interface OnItemClickListener {
void onItemClick(Component view);
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
mOnItemClickListener = onItemClickListener;
}
按照思路看下来,是不是很简单呢?我们只需要把握住如何计算 childview 的宽度,以及什么情况下添加新的一行即可。
视频号视频推荐
每天送出 红包/编程书籍
推荐阅读:
到底该选择32位还是64位版本的Office?微软为你解答疑惑
为了写论文给 Linux “投毒”,导致整个大学都被 Linux 拉黑!