鸿蒙初学 使用Fraction和TabList实现切换效果

参考资源:
鸿蒙 TabList 配合Fraction 实现顶部切换效果
鸿蒙开发文档

效果图:

实现效果图

效果视频:

鸿蒙初学 实现tab页切换和从网络加载资源


修改MainAbility, 使其继承自FractionAbility

public class MainAbility extends FractionAbility {
    
    
    @Override
    public void onStart(Intent intent) {
    
    
        super.onStart(intent);
        super.setMainRoute(MainAbilitySlice.class.getName());
    }
}

修改ability_main.xml, 添加TabList和StackLayout

Fraction将会在StackLayout中展示.

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:id="$+id:dl"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:orientation="vertical">
    <TabList
        ohos:id="$+id:tab_list"
        ohos:height="36vp"
        ohos:width="match_parent"
        ohos:layout_alignment="center"
        ohos:normal_text_color="#999999"
        ohos:orientation="horizontal"
        ohos:fixed_mode="true"
        ohos:selected_tab_indicator_color="#FF0000"
        ohos:selected_tab_indicator_height="2vp"
        ohos:selected_text_color="#FF0000"
        ohos:text_alignment="center"
        ohos:text_size="15fp"/>
    <StackLayout
        ohos:id="$+id:stack_layout"
        ohos:height="match_parent"
        ohos:width="match_parent"/>
</DirectionalLayout>

修改MainAbilitySlice.java, 在TabList中添加两个Tab, 分别为Images和Videos

public class MainAbilitySlice extends AbilitySlice {
    
    
    static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG"); //MY_MODULE=0x00201
    TabList mTabList;
    StackLayout mStackLayout;

    @Override
    public void onStart(Intent intent) {
    
    
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        initView();
        initTabList();
    }

    private void initView() {
    
    
        mTabList = (TabList) findComponentById(ResourceTable.Id_tab_list);
        mStackLayout = (StackLayout) findComponentById(ResourceTable.Id_stack_layout);
    }

    private void initTabList() {
    
    
        String[] titles = {
    
    
                "Images", "Videos"
        };
        for (String title : titles) {
    
    
            TabList.Tab tab = mTabList.new Tab(getContext());
            tab.setText(title);
            mTabList.addTab(tab);
        }
    }
}

创建两个Fraction, 分别为ImageFractionVideoFraction

ImageFraction

fraction_image.xml布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:alignment="center"
    ohos:orientation="vertical">
    <ScrollView
        ohos:id="$+id:scroll_view"
        ohos:height="match_parent"
        ohos:width="match_parent"
        ohos:background_element="#FFDEAD"
        ohos:layout_alignment="horizontal_center">
        <!--这里的ohos:height不能写成match_parent, 不然不能滑动了, 不清楚为啥-->
        <DirectionalLayout
            ohos:id="$+id:scroll_view_dl"
            ohos:height="match_content" 
            ohos:width="match_parent"
            ohos:orientation="vertical">
        </DirectionalLayout>
    </ScrollView>

</DirectionalLayout>

单个的图片布局文件layout_image.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_content"
    ohos:width="match_content"
    ohos:orientation="vertical">
    <Image
        ohos:id="$+id:ycy_image"
        ohos:height="300vp"
        ohos:width="match_parent"
        ohos:bottom_margin="20vp"
        ohos:image_src="$media:ycy"
        ohos:scale_mode="center"/>
</DirectionalLayout>

点击图片可以查看大图, 是通过对话框来实现的, 对话框的布局文件layout_image_dialog.xml如下.

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_content"
    ohos:width="match_content"
    ohos:orientation="vertical">

    <Image
        ohos:id="$+id:image"
        ohos:height="match_parent"
        ohos:width="match_parent"
        ohos:clip_alignment="center"
        ohos:scale_mode="center"/>
</DirectionalLayout>

ImageFraction代码如下:
使用了OkHttp3发送请求, 需要加dependence

compile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.14.2'

还需要网络权限:

"reqPermissions": [
  {
    
    
    "name": "ohos.permission.INTERNET"
  }
]
public class ImageFraction extends Fraction {
    
    
    private static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0x01, "MY_TAG");
    private final String[] mYcyUrls = new String[]{
    
    
            "https://wx1.sinaimg.cn/mw2000/006a0Rdhly1gsqqjwj048j31ed2a77wi.jpg",
            "https://wx1.sinaimg.cn/mw2000/006a0Rdhly1gsqqk02u6bj31ru28ce82.jpg",
            "https://wx1.sinaimg.cn/mw2000/006a0Rdhly1gsqqk1elmkj321s29znpd.jpg",
            "https://wx1.sinaimg.cn/mw2000/006a0Rdhly1gsqqk30htkj320p2av7wh.jpg",
            "https://wx1.sinaimg.cn/mw2000/006a0Rdhgy1grs9eyczdrj30u0140qux.jpg",
            "https://wx1.sinaimg.cn/mw2000/006a0Rdhgy3gq7olk8wcsj317h1kwe82.jpg"
    };
    /**
     * 当前Fraction的根布局
     */
    private Component mRootComponent;
    /**
     * 每次切换tab都会执行on start 和 on detach, 按理说切换回来只会执行一个
     * 不太懂它的生命周期,
     * 图片会重复添加 用这个判断一下.
     */
    private boolean mIsUrlLoad = false;
    /**
     * 和安卓的一样 不能在子线程中更新UI, 所以使用这个
     */
    private MyEventHandle mMyEventHandle = new MyEventHandle(EventRunner.current());

    private ScrollView mScrollView;

    public ImageFraction() {
    
    
        HiLog.error(LABEL_LOG, "ImageFraction Create", "");
    }
    /**
     * 在主线程中更新UI
     */
    private class MyEventHandle extends EventHandler {
    
    
        public MyEventHandle(EventRunner runner) throws IllegalArgumentException {
    
    
            super(runner);
        }

        @Override
        protected void processEvent(InnerEvent event) {
    
    
            switch (event.eventId) {
    
    
                case 0x01:
                    PixelMap pixelMap = (PixelMap) event.object;
                    addYcyImage(pixelMap);
                    // 这里的pixelMap 不能realease掉, 弹窗显示还需要用到
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    protected void onStart(Intent intent) {
    
    
        super.onStart(intent);
        HiLog.error(LABEL_LOG, "on start");
        if (!mIsUrlLoad) {
    
    
            loadYcyImages();
        }
    }

    /**
     * 加载图片
     */
    private void loadYcyImages() {
    
    
        for (String ycyUrl : mYcyUrls) {
    
    
            downloadImageAsy(ycyUrl);
        }
        mIsUrlLoad = true;
    }

    /**
     * 应该也不支持在主线程中进行耗时操作吧 没尝试就写成异步的了
     * 异步下载图片, 下载使用的是OkHttp3
     *
     * @param imageUrl 图片链接
     */
    private void downloadImageAsy(String imageUrl) {
    
    
        Request request = new Request.Builder().url(imageUrl).get().build();
        OkHttpClient client = new OkHttpClient();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
    
    
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
    
    
                HiLog.error(LABEL_LOG, e.getMessage());
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
    
    
                HiLog.error(LABEL_LOG, "get ycy image response");
                if (response.body() != null) {
    
    
                    InputStream inputStream = response.body().byteStream();
                    ImageSource source = ImageSource.create(inputStream, null);
                    PixelMap pixelmap = source.createPixelmap(null);
                    InnerEvent normalInnerEvent = InnerEvent.get(0x01, 0x01, pixelmap);
                    mMyEventHandle.sendEvent(normalInnerEvent);
                    inputStream.close();
                }
            }
        });
    }


    @Override
    protected Component onComponentAttached(LayoutScatter scatter, ComponentContainer container, Intent intent) {
    
    
        HiLog.error(LABEL_LOG, "attached");
        if (mRootComponent == null) {
    
    
            mRootComponent = scatter.parse(ResourceTable.Layout_fraction_image, container, false);
        }
        initView();
        initActionListener();
        return mRootComponent;
    }

    private void initActionListener() {
    
    
    }

    private void initView() {
    
    
        mScrollView = (ScrollView) mRootComponent.findComponentById(ResourceTable.Id_scroll_view);
    }

    /**
     * 添加图片的到布局
     *
     * @param pixelMap pixMap
     */
    private void addYcyImage(PixelMap pixelMap) {
    
    
        HiLog.error(LABEL_LOG, "add ycy image");
        DirectionalLayout directionalLayout = (DirectionalLayout) mRootComponent.findComponentById(ResourceTable.Id_scroll_view_dl);
        LayoutScatter scatter = LayoutScatter.getInstance(directionalLayout.getContext());
        DirectionalLayout imageDL = (DirectionalLayout) scatter.parse(ResourceTable.Layout_layout_image, directionalLayout, false);
        Image ycyImage = (Image) imageDL.findComponentById(ResourceTable.Id_ycy_image);
        ycyImage.setPixelMap(pixelMap);
        ycyImage.setClickedListener(new ImageClickListener(ycyImage));
        directionalLayout.addComponent(imageDL);
    }

    class ImageClickListener implements Component.ClickedListener {
    
    
        private Image mYcyImage;

        public ImageClickListener() {
    
    
            super();
        }

        public ImageClickListener(Image ycyImage) {
    
    
            super();
            mYcyImage = ycyImage;
        }


        @Override
        public void onClick(Component component) {
    
    
            PopupDialog popupDialog = new PopupDialog(mRootComponent.getContext(), mRootComponent);
            Component dialogComponent = LayoutScatter.getInstance(mRootComponent.getContext()).parse(ResourceTable.Layout_layout_image_dialog, (ComponentContainer) mRootComponent, false);
            popupDialog.setCustomComponent(dialogComponent);
            Image image = (Image) dialogComponent.findComponentById(ResourceTable.Id_image);
            image.setPixelMap(mYcyImage.getPixelMap());
            // 1 是居中 亲测
            // 2 是居左 亲测
            // 3 是居右 没试过
            popupDialog.showOnCertainPosition(2, 0, 0);
            popupDialog.show();
        }
    }
}

VideoFraction

fraction_vedio.xml

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:alignment="center"
    ohos:orientation="vertical">

    <ScrollView
        ohos:height="match_parent"
        ohos:width="match_parent"
        ohos:background_element="#FFDEAD"
        ohos:layout_alignment="horizontal_center">

        <DirectionalLayout
            ohos:id="$+id:video_dl"
            ohos:height="match_content"
            ohos:width="match_parent"
            ohos:orientation="vertical">
            <!-- $media:plant为在media目录引用的图片资源 -->
        </DirectionalLayout>
    </ScrollView>
</DirectionalLayout>

写单个的布局layout_video.xml

只用图片模拟一下, 还不会播放视频

<?xml version="1.0" encoding="utf-8"?>
<StackLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_content"

    ohos:width="match_content">

    <Image
        ohos:id="$+id:ycy_image"
        ohos:height="200vp"
        ohos:width="match_parent"
        ohos:bottom_margin="20vp"
        ohos:image_src="$media:ycy"
        ohos:scale_mode="center"/>

    <Image
        ohos:height="60vp"
        ohos:width="60vp"
        ohos:image_src="$media:start"
        ohos:layout_alignment="center"/>
</StackLayout>

单个的效果图

VideoFraction.java


public class VideoFraction extends Fraction {
    
    
    private static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0x01, "MY_TAG");
    Component mRoutComponent;
    DirectionalLayout mVideoDirectionalLayout;

    @Override
    protected void onStart(Intent intent) {
    
    
        super.onStart(intent);
        HiLog.error(LABEL_LOG, "on start");
    }

    @Override
    protected Component onComponentAttached(LayoutScatter scatter, ComponentContainer container, Intent intent) {
    
    
        HiLog.error(LABEL_LOG, "attached");
        mRoutComponent = scatter.parse(ResourceTable.Layout_fraction_vedio, container, false);
        initView();
        return mRoutComponent;
    }

    private void initView() {
    
    
        mVideoDirectionalLayout = (DirectionalLayout) mRoutComponent.findComponentById(ResourceTable.Id_video_dl);
        Component component = LayoutScatter.getInstance(mRoutComponent.getContext()).parse(ResourceTable.Layout_layout_video, mVideoDirectionalLayout, false);
        mVideoDirectionalLayout.addComponent(LayoutScatter.getInstance(mRoutComponent.getContext()).parse(ResourceTable.Layout_layout_video, mVideoDirectionalLayout, false));
        mVideoDirectionalLayout.addComponent(LayoutScatter.getInstance(mRoutComponent.getContext()).parse(ResourceTable.Layout_layout_video, mVideoDirectionalLayout, false));
        mVideoDirectionalLayout.addComponent(LayoutScatter.getInstance(mRoutComponent.getContext()).parse(ResourceTable.Layout_layout_video, mVideoDirectionalLayout, false));
    }

}

修改MainAbilitySlice.java

初始化两个Fraction, 添加TabList的点击事件, 使其实现切换Fraction的效果.

public class MainAbilitySlice extends AbilitySlice {
    
    
    static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG"); //MY_MODULE=0x00201
    ArrayList<Fraction> mFractions = new ArrayList<>();
    TabList mTabList;
    StackLayout mStackLayout;

    @Override
    public void onStart(Intent intent) {
    
    
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        initView();
        initFraction();
        initTabList();
        initActionListener();
    }

    private void initView() {
    
    
        mTabList = (TabList) findComponentById(ResourceTable.Id_tab_list);
        mStackLayout = (StackLayout) findComponentById(ResourceTable.Id_stack_layout);
    }

    private void initFraction() {
    
    
        ImageFraction imageFraction = new ImageFraction();
        VideoFraction videoFraction = new VideoFraction();
        mFractions.add(imageFraction);
        mFractions.add(videoFraction);
    }

    private void initActionListener() {
    
    
        mTabList.addTabSelectedListener(new TabList.TabSelectedListener() {
    
    
            @Override
            public void onSelected(TabList.Tab tab) {
    
    
                int position = tab.getPosition();
                HiLog.error(LABEL_LOG, "tab %{public}d is on selected", position);
                ((FractionAbility) getAbility()).getFractionManager()
                        .startFractionScheduler()
                        .replace(ResourceTable.Id_stack_layout, mFractions.get(position))
                        .submit();
            }

            @Override
            public void onUnselected(TabList.Tab tab) {
    
    

            }

            @Override
            public void onReselected(TabList.Tab tab) {
    
    

            }
        });
        mTabList.selectTabAt(0);
    }

    private void initTabList() {
    
    
        String[] titles = {
    
    
                "Images", "Videos"
        };
        for (String title : titles) {
    
    
            TabList.Tab tab = mTabList.new Tab(getContext());
            tab.setText(title);
            mTabList.addTab(tab);
        }
    }
}

结束Peace!

鸿蒙教程很少啊!!!
不会的先搜搜安卓怎么实现…

猜你喜欢

转载自blog.csdn.net/qq_41359651/article/details/119301488
今日推荐