鸿蒙提供的新闻客户端代码,默认是先加载所有数据的,不过现在新闻分类中,一般是没有‘所有/All’这个分类标签选项,都是具体的分类标签选项,而且初始化的时候就会显示默认分类标签选项是显示选中状态的(一般默认是第一个分类标签),笔者在鸿蒙代码的基础上进行了修改。

目标:默认加载显示第一个新闻分类标签的列表数据,并且第一个新闻分类标签显示被选中状态,点击其他分类标签后,加载显示对应数据,被点击的分类标签显示被选中状态,其他分类标签未选中状态。

1、删除所有/All选项

找到resource/rawfile/news_type_datas.json文件,这是一个json格式的数组,直接修改文件保存就可以了。

 

2、数据初始化第一个选项

源码中的initListener方法中的‘selectorListContainer.setItemClickedListener’设置新闻分类控件单击事件中,就有根据选择的分类选项重新生成新闻列表明细数据的代码,可以把它抽取出来做成函数也可以直接拿来用。笔者把它抽取出来做成了函数。

/**
     * 根据新闻标签自动加载更新列表数据
     * @param news_type
     */
    private void updateNewsListData(String news_type){
        newsDataList.clear();
        for(NewsInfo newsInfo : totalNewsDataList){
            if(newsInfo.getType().equals(news_type)){
                newsDataList.add(newsInfo);
            }
        }
    }

3、初始化默认选项的样式

笔者将源码的被选中的样式修改成了比较简单的设置字体颜色成红色,各位读者可以根据自己的喜好和技术来修改。

一开始,笔者的思路是找到第一个选项的控件变量,把它设置成被选择中的颜色,不过一直无法找到方法在初始化后通过已有的变量来定位,而且现在鸿蒙的debug模式也不好用,无法分析初始化后各变量的具体数据。

笔者转换思路,初始化时显示的值,是我们news_type_datas.json文件里的值,这表明肯定是读取了文件的数据来初始化,从在哪读取文件开始,一步步定位到provider类里的getComponent方法,我在这个方法加上一个步骤,在处理第一个元素时,字体颜色显示成红色。果然,加上后效果就出来了。

@Override
    public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
        Component temp = component;
        if (temp == null) {
            temp = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_item_news_type_layout, null, false);
        }

        Text text = (Text) temp.findComponentById(ResourceTable.Id_news_type_text);
        text.setText(newsTypeList.get(i).getName());
        if(0 == i){//初始化第一个新闻类型的样式为已选择
            text.setTextColor(Color.RED);
        }
        return temp;
    }

不过还有一个问题,就是这个元素会一直显示成红色,即便选择了其他选项,它仍然显示红色,而且被选择的选项也会显示红色。这是因为第一个被选中的分类标签没有被修改。

笔者思考,在点击事件中,是可以获取到当前被点击的元素,那是否可以通过点击事件函数的变量来定位第一个元素

selectorListContainer.setItemClickedListener(
            (listContainer, component, position, id) -> {
                if(null == selectText){//获取第一个新闻类型控件
                    selectText = (Text) listContainer.getComponentAt(0).findComponentById(ResourceTable.Id_news_type_text);
                }
                setCategorizationFocus(false);
                selectText = (Text) component.findComponentById(ResourceTable.Id_news_type_text);
                setCategorizationFocus(true);
                updateNewsListData(selectText.getText());
                updateListView();
            }
        );

这么一修改,可以实现第一次点击后,默认的新闻标签显示成非选择状态,不过笔者测试发现,如果拖动新闻标签列表,第一个标签在隐藏后再显示,又会变成红色,还是没能满足我一开始的需求。继续分析~

笔者思考,这应该是因为隐藏后再显示重新加载的原因,每次重新加载,就会走getComponent函数。

增加一个变量,只有在第一次初始化的时候才会将第一个元素显示成红色。

@Override
    public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
        Component temp = component;
        if (temp == null) {
            temp = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_item_news_type_layout, null, false);
        }

        Text text = (Text) temp.findComponentById(ResourceTable.Id_news_type_text);
        text.setText(newsTypeList.get(i).getName());
        if(first){//初始化第一个新闻类型的样式为已选择
            text.setTextColor(Color.RED);
            first = false;
        }
        return temp;
    }

最后,终于实现了一开始定下的目标效果。

 

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐