美文网首页简化开发鸿蒙开发入门
【学习Demo】TabList+PageSlider实现首页切换

【学习Demo】TabList+PageSlider实现首页切换

作者: 红尘丶 | 来源:发表于2021-02-18 11:59 被阅读0次

    学习使用鸿蒙基础控件,实现类似新闻类app顶部tab效果。
    先上demo图:


    image.png
    image.png

    实现步骤:

    1、使用模板创建项目,自带开屏页;

    2、修改main布局文件,添加tabList,pageSlider控件,tabList相关属性设置,也可在代码中实现;

    <?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:orientation="vertical">
    
        <TabList
            ohos:id="$+id:title_tabs"
            ohos:height="48vp"
            ohos:width="match_parent"
            ohos:background_element="$color:copyright_text_color"
            ohos:fixed_mode="false"
            ohos:normal_text_color="#ffffff"
            ohos:orientation="horizontal"
            ohos:selected_tab_indicator_color="#ff0000"
            ohos:selected_tab_indicator_height="2vp"
            ohos:selected_text_color="#ff0000"
            ohos:tab_margin="5vp"
            ohos:text_alignment="center"
            ohos:text_size="18fp"
            />
    
        <PageSlider
            ohos:id="$+id:pager"
            ohos:height="match_parent"
            ohos:width="match_parent"
            />
    
    </DirectionalLayout>
    

    3、鸿蒙支持各类数据xml定义,与安卓类似,数组资源文件定义(base/element/strarray.json);

    {
      "strarray": [
        {
          "name": "tab_title",
          "value": [
            {
              "value": "推荐"
            },
            {
              "value": "热点"
            },
            {
              "value": "NBA"
            },
            {
              "value": "美图"
            },
            {
              "value": "疫情"
            },
            {
              "value": "本地"
            },
            {
              "value": "军事"
            },
            {
              "value": "投资"
            },
            {
              "value": "金融"
            }
          ]
        }
      ]
    }
    

    4、开发实现,代码较为基础,不做多解释,如有疑问或想法可在评论区交流;

    原本期望使用fraction+pageSlider实现整体页面切换,查阅官方资料,暂不支持。无奈用component代替fraction。

        @Override
        public void onStart(Intent intent) {
            super.onStart(intent);
            super.setUIContent(ResourceTable.Layout_ability_main);
    
            initView();
            initData();
        }
    
    //初始化控件
     private void initView() {
            tabList = (TabList) findComponentById(ResourceTable.Id_title_tabs);
            pageSlider = (PageSlider) findComponentById(ResourceTable.Id_pager);
    
            tabList.addTabSelectedListener(this);
            pageSlider.addPageChangedListener(this);
        }
    
    // tab与page数据初始化
    private void initData() {
            try {
                String[] tabsTitle = getResourceManager().getElement(ResourceTable.Strarray_tab_title).getStringArray();
                for (String title: tabsTitle){
                    TabList.Tab tab = tabList.new Tab(getContext()); 
                    tab.setText(title);
                    tabList.addTab(tab);
                }
                tabList.selectTabAt(0);  //选中0位置
    
                pageSlider.setProvider(new MainPagerAdapter(initPageSliderViewData())); 
                pageSlider.setCurrentPage(0);
                pageSlider.setReboundEffect(true);
                pageSlider.setCentralScrollMode(true);
            } catch (IOException | NotExistException | WrongTypeException e) {
                e.printStackTrace();
            }
        }
    
        private ArrayList<Component> initPageSliderViewData() {
            int pageSize = tabList.getTabCount();
            ArrayList<Component> pages = new ArrayList<>();
           ViewCreateHelper viewCreateHelper = new ViewCreateHelper(getContext());
            for (int i = 0; i < pageSize; i++) {
                pages.add(viewCreateHelper.createView(tabList.getTabAt(i).getText()));
            }
            return pages;
        }
    
    
    ①PageSlider适配器,使用方式与viewPager类似;
    public class MainPagerAdapter extends PageSliderProvider {
    
        private List<Component> pages;
    
    
        public MainPagerAdapter(ArrayList<Component> pages) {
            this.pages = pages;
        }
    
        @Override
        public int getCount() {
            return pages == null ? 0 : pages.size();
        }
    
    
        @Override
        public Object createPageInContainer(ComponentContainer componentContainer, int i) {
            componentContainer.addComponent(pages.get(i));
            return componentContainer;
        }
    
        @Override
        public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) {
            componentContainer.removeComponent(pages.get(i));
        }
    
        @Override
        public boolean isPageMatchToObject(Component component, Object o) {
            return component == o;
        }
        
    }
    

    ②ViewCreaterHelper用于创建page页;

    public final class ViewCreateHelper {
    
        private Context slice;
        private HashMap<String, ListAdapter> cache;
    
        public ViewCreateHelper(Context abilitySlice) {
            this.slice = abilitySlice;
            cache = new HashMap<>();
        }
    
        public Component createView(String title) {
            Component mainComponent =
                    LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_pager_item, null, false);
            if (!(mainComponent instanceof ComponentContainer)) {
                return null;
            }
            ComponentContainer rootLayout = (ComponentContainer) mainComponent;
            initView(mainComponent,title);
            return rootLayout;
        }
    
        public void initView(Component mainComponent,String title) {
            // 列表
            ListContainer  listContainer = (ListContainer) mainComponent.findComponentById(ResourceTable.Id_list_main);
            ListAdapter<NewsInfo> listAdapter = new ListAdapter<NewsInfo>(slice, ResourceTable.Layout_item_news_layout, getData(0, title)) {
                @Override
                public void convert(ViewHolder viewHolder, NewsInfo item, int position) {
                    viewHolder.setText(ResourceTable.Id_item_news_title, item.getTitle());
                    viewHolder.setText(ResourceTable.Id_item_news_desc, item.getDescription());
    
                }
            };
            listContainer.setItemProvider(listAdapter);
            listContainer.setItemClickedListener((list, component, i, l) -> {
    //            Intent in = new Intent();
    //            in.setElementName("", component.getContext().getBundleName(), DetailAbility.class.getName());
    //            slice.startAbility(in, 0);
            });
    
            cache.put(title, listAdapter);
        }
    
    
        public List<NewsInfo> getData(int tab, String title) {
            List<NewsInfo> curData = new ArrayList<>();
            for (int i = 0; i < 20; i++) {
                NewsInfo info = new NewsInfo();
                info.setTitle("标题:" + title + i);
                info.setDescription("我是描述啦" + title + Math.random());
                curData.add(info);
            }
            return curData;
        }
    
    }
    

    ③list适配器;

    public abstract class ListAdapter<T> extends BaseItemProvider {
    
        private List<T> data;
        private Context ct;
        private int itemId;
    
        public ListAdapter(Context ct, int itemId, List<T> data) {
            this.data = data;
            this.ct = ct;
            this.itemId = itemId;
        }
    
        public abstract void convert(ViewHolder viewHolder, T item, int position);
    
        @Override
        public int getCount() {
            return data == null ? 0 : data.size();
        }
    
        @Override
        public T getItem(int i) {
            return data.get(i);
        }
    
        @Override
        public long getItemId(int i) {
            return i;
        }
    
        @Override
        public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
            ViewHolder viewHolder = null;
            if (component == null) {
                Component itemView = LayoutScatter.getInstance(ct).parse(itemId, componentContainer, false);
                viewHolder = new ViewHolder(ct, itemView, componentContainer, i);
                viewHolder.layoutId = itemId;
            } else {
                Object object = component.getTag();
                if (object instanceof ViewHolder) {
                    viewHolder = (ViewHolder) object;
                    viewHolder.position = i;
                }
            }
            convert(viewHolder, getItem(i), i);
            return viewHolder == null ? null : viewHolder.getComponentView();
        }
    }
    

    ④ViewHolder,可自行添加其他逻辑;

    public class ViewHolder {
        int position;
        int layoutId;
        private Component component;
        private Context context;
        private HashMap<Integer, Component> views;
    
        ViewHolder(Context context, Component itemView, ComponentContainer parent, int position) {
            this.context = context;
            this.component = itemView;
            this.position = position;
            views = new HashMap<>(0);
            component.setTag(this);
        }
    
        @SuppressWarnings("unchecked")
        public <T extends Component> T getView(int viewId) {
            Component view = views.get(viewId);
            if (view == null) {
                view = component.findComponentById(viewId);
                views.put(viewId, view);
            }
            return (T) view;
        }
    
        Component getComponentView() {
            return component;
        }
    
        public void setText(int viewId, String text) {
            Text tv = getView(viewId);
            tv.setText(text);
        }
    
        public void setImageResource(int viewId, int resId) {
            Image image = getView(viewId);
            image.setPixelMap(resId);
            image.setScaleMode(Image.ScaleMode.STRETCH);
        }
    
    }
    

    End

    其他资源文件未列举出,请参考完整demo。
    github Demo源码

    遗留问题思考

    1、当点击tab切换时,若tab未完全显示,最好可以自动滑动展示完整tab;
    2、未做下拉刷新与加载更多,涉及到滑动事件冲突;

    相关文章

      网友评论

        本文标题:【学习Demo】TabList+PageSlider实现首页切换

        本文链接:https://www.haomeiwen.com/subject/wsegxltx.html