HarmonyOS 通用的應(yīng)用引導(dǎo)功能
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
手機APP的引導(dǎo)頁是一個常見的功能,今天和大家一起分享在鴻蒙系統(tǒng)的擼引導(dǎo)頁代碼的經(jīng)驗。
一.應(yīng)用引導(dǎo)頁的功能
1.1為什么要做應(yīng)用的引導(dǎo)功能?
幾乎所有的App都會有做一些界面引導(dǎo),有的是頁面交互的引導(dǎo),有的是為了介紹新功能。
1.2通用的功能性引導(dǎo)大概分哪些呢?
主功能引導(dǎo)、新功能引導(dǎo)和功能轉(zhuǎn)移或改名引導(dǎo)。
1.3.通用的應(yīng)用引導(dǎo),需要注意哪些?
引導(dǎo)的內(nèi)容文字不宜太長,適當加入一些圖案可以方便用戶理解。言歸正傳吧,開始咱們今天的主題,如何實現(xiàn)應(yīng)用的引導(dǎo)功能吧!
二.實現(xiàn)應(yīng)用的引導(dǎo)功能具體步驟:
首先來看看討論的引導(dǎo)功能的效果吧!點擊引導(dǎo)頁,向上滑動過程,第一個界面圖案和文字漸變消失的過程。而第二頁界面的圖片和文字漸漸清晰可見。底部Next 圖標會下滑隱藏再彈出的動畫效果。
開發(fā)準備
搭建鴻蒙開發(fā)環(huán)境,這里就不做介紹了,如果沒有環(huán)境沒有搭建好的同學(xué)可以進入學(xué)習(xí)安裝環(huán)境, 安裝好環(huán)境以后接下來我們就可以進行開發(fā)工作了。
2.1 設(shè)計思路
首先我們做的是公用的組件,我們需要使用組件化思想去搭建我們的項目框架,接下來根據(jù)組件的需求我們先去設(shè)計一下界面,設(shè)計好之后我們需要對頁面添加數(shù)據(jù),添加完數(shù)據(jù)之后組件的大體界面已經(jīng)展示給我們,下來就是在滑動page的時候添加底部button的回彈動畫,并且在此時我們需要操作page的子view。最后我們要去使用我們的組件。
2.2 設(shè)計步驟
2.2.1 設(shè)計界面
根據(jù)我們要實現(xiàn)的功能,我們可以使用PageSlider控件去實現(xiàn)界面布局文件,實現(xiàn)代碼為:
- <PageSlider
- ohos:id="$+id:vertical_view_pager"
- ohos:width="match_parent"
- ohos:height="match_parent" >
- </PageSlider>
(1)添加數(shù)據(jù)、初始化數(shù)據(jù)
- public void setData() {
- super.setData();
- pageColors = new ArrayList<>();
- pageColors.add(getString(ResourceTable.Color_colorAccent));
- pageColors.add(getString(ResourceTable.Color_color2));
- pageColors.add(getString(ResourceTable.Color_colorPrimary));
- pageColors.add(getString(ResourceTable.Color_color3));
- pageMoudles = getData();
- }
- private List<PageMoudle> getData() {
- String textValue = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.";
- PageMoudle pageMoudleOne = new PageMoudle();
- pageMoudleOne.setRecoureId(ResourceTable.Graphic_intro_second_vector);
- pageMoudleOne.setBackGroudRgbColor(RgbColor.fromArgbInt(Color.getIntColor(pageColors.get(0))));
- pageMoudleOne.setTitle("Lorem Ipsum Lorem Ipsum");
- pageMoudleOne.setText(textValue + textValue + textValue);
- pageMoudleOne.setTitleSize(17);
- pageMoudleOne.setTextSize(14);
- List<PageMoudle> datas = new ArrayList<>();
- datas.add(pageMoudleOne);
- PageMoudle pageMoudleTwo = new PageMoudle();
- pageMoudleTwo.setRecoureId(ResourceTable.Graphic_four);
- pageMoudleTwo.setBackGroudRgbColor(RgbColor.fromArgbInt(Color.getIntColor(pageColors.get(1))));
- pageMoudleTwo.setTitle("Lorem Ipsum Lorem Ipsum ");
- pageMoudleTwo.setText(textValue + textValue);
- datas.add(pageMoudleTwo);
- PageMoudle pageMoudleThree = new PageMoudle();
- pageMoudleThree.setRecoureId(ResourceTable.Graphic_ohos);
- pageMoudleThree.setBackGroudRgbColor(RgbColor.fromArgbInt(Color.getIntColor(pageColors.get(2))));
- pageMoudleThree.setTitle("Lorem Ipsum");
- pageMoudleThree.setText(textValue);
- datas.add(pageMoudleThree);
- PageMoudle pageMoudleFour = new PageMoudle();
- pageMoudleFour.setRecoureId(ResourceTable.Media_new_intro);
- pageMoudleFour.setBackGroudRgbColor(RgbColor.fromArgbInt(Color.getIntColor(pageColors.get(3))));
- pageMoudleFour.setTitle("Lorem Ipsum");
- pageMoudleFour.setText(textValue + textValue + textValue);
- datas.add(pageMoudleFour);
- return datas;
- }
(2)設(shè)置provider
- pageSlider = (PageSlider) findComponentById(ResourceTable.Id_vertical_view_pager);
- pageSlider.setOrientation(Component.VERTICAL);
- pageSlider.addPageChangedListener(this);
- pageSlider.setTouchEventListener(this::onTouchEvent);
- adapter = new VerticalIntroPagerAdapter(this, pageMoudles);
- pageSlider.setProvider(adapter);
2.2.2 添加動畫
這里我們使用屬性動畫去完成底部button的上彈和下彈操作,上彈和下彈是和我們手指滑動的方向是有關(guān)系的,所以這里我們必須實現(xiàn)手指的觸摸事件,在觸摸事件中獲取我們手機滑動的距離,如果距離大于0則是下滑,如果小于0則是下滑.
(1) 獲取是上滑還是下滑代碼如下:
- @Override
- public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
- int action = touchEvent.getAction();
- switch (action) {
- case TouchEvent.PRIMARY_POINT_DOWN:
- pageSlider.setSlidingPossible(true);
- startPointY = getTouchY(touchEvent, 0, component);
- return true;
- case TouchEvent.POINT_MOVE:
- movePointY = getTouchY(touchEvent, touchEvent.getIndex(), component) - startPointY;
- if (page != 0 && movePointY > 0) {
- WindowManager.getInstance().getTopWindow().get().setStatusBarColor(getColorByString(pageColors.get(page - 1)));
- }
- return true;
- case TouchEvent.PRIMARY_POINT_UP:
- return true;
- default:
- }
- return false;
- }
(2) 獲取到上滑還是下滑后,接下來就去給底部button設(shè)置動畫.動畫用的是屬性動畫,屬性動畫大體實現(xiàn)是初始化動畫,設(shè)置動畫持續(xù)時間,實現(xiàn)動畫屬性值變化監(jiān)聽事件,最后啟動動畫。大體代碼如下:
- private void startChangeButtonBg(int direction, int duration) {
- if (animatorValue == null) {
- animatorValue = new AnimatorValue();
- }
- animatorValue.setCurveType(Animator.CurveType.LINEAR);
- animatorValue.setDuration(duration);
- animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
- @Override
- public void onUpdate(AnimatorValue animatorValue, float v) {
- if (direction <= 0) {
- double value = ((1 - (double)v) * nextHeight) * direction;
- next.setMarginBottom((int) value);
- } else {
- float value = -(v * nextHeight);
- next.setMarginBottom((int) value);
- if (v > 0.9) {
- if (page == 3) {
- skip.setVisibility(Component.INVISIBLE);
- next.setText("DONE");
- next.setNormalColor(pageColors.get(1));
- } else {
- skip.setVisibility(Component.VISIBLE);
- next.setText("NEXT");
- next.setNormalColor(pageColors.get(page + 1));
- }
- next.setMarginBottom(0);
- }
- }
- }
- });
- setAnimStateChangeList(direction);
- animatorValue.start();
- }
- private void setAnimStateChangeList(int direction) {
- animatorValue.setStateChangedListener(new Animator.StateChangedListener() {
- @Override
- public void onStart(Animator animator) {
- if (direction <= 0) {
- if (page == 3) {
- skip.setVisibility(Component.INVISIBLE);
- next.setText("DONE");
- next.setNormalColor(pageColors.get(1));
- } else {
- skip.setVisibility(Component.VISIBLE);
- next.setText("NEXT");
- next.setNormalColor(pageColors.get(page + 1));
- }
- }
- }
- @Override
- public void onStop(Animator animator) {
- }
- @Override
- public void onCancel(Animator animator) {
- }
- @Override
- public void onEnd(Animator animator) {
- movePointY = 0;
- }
- @Override
- public void onPause(Animator animator) {
- }
- @Override
- public void onResume(Animator animator) {
- }
- });
- }
2.2.3 操作子view
如何去操作子view呢?首先我們先去看看PageSlider是否有子view的操作監(jiān)聽接口,查看api后沒有這樣的接口獲取方法,那就得我們自己去考慮怎么實現(xiàn)呢,我這里的實現(xiàn)思路是在PageSlider設(shè)置provider的時候保存所有的子view對象,然后再使用的時候拿出子view再進行操作。我們這里例子是改變子view的透明度.代碼實現(xiàn)如下:
(1) 保存子view
- public class VerticalIntroPagerAdapter extends PageSliderProvider {
- LinkedHashMap<Integer, Component> pageComonents;
- public VerticalIntroPagerAdapter(Context context, List<PageMoudle> datas) {
- this.context = context;
- this.datas = datas;
- pageComonent = new ArrayList<>();
- // 初始化用來添加子view的集合,注意這里是一個有序集合
- pageComonents = new LinkedHashMap<Integer, Component>();
- }
- //添加子view
- @Override
- public Object createPageInContainer(ComponentContainer componentContainer, int i) {
- if (!pageComonents.containsValue(component)) {
- pageComonents.put(i, component);
- }
- }
- }
(2) 操作子view
- private void setPageApale(int currentPage, int targetPage, float offset) {
- if (adapter.pageComonents != null && adapter.pageComonents.get(currentPage) != null
- && adapter.pageComonents.get(targetPage) != null) {
- float alpha = new BigDecimal(1.0f).subtract(new BigDecimal(offset).multiply(new BigDecimal(2))).floatValue();
- if (offset >= 0.4 && offset <= 0.9) {
- offset = new BigDecimal(offset).subtract(new BigDecimal( 0.4f)).floatValue();
- } else if (offset < 0.4) {
- offset = 0.0f;
- } else {
- offset = 1.0f;
- }
- setApale(currentPage, targetPage, alpha, offset);
- }
- }
到這里我們的豎直引導(dǎo)工具組件就已經(jīng)封裝好了。
2.2.4 使用組件
如何去使用我們的組件呢?這里我們用的是組件化思想.所以我們呢只需要在我們的項目中引入我們的組件,然后再我們的ablity中集成我們封裝好的VerticalIntroSlice對象就行,最后我們再把封裝一個添加數(shù)據(jù)的接口,把我們的數(shù)據(jù)變成動態(tài)添加的就行。
三. 結(jié)語
到此我們的整個設(shè)計流程就完了,通過上面的操作,相信小伙伴們就可以實現(xiàn)應(yīng)用引導(dǎo)功能了。
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)