1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        HarmonyOS組件開發(fā) ScrollView嵌套ListContainer 滑動(dòng)沖突問題

        共 10512字,需瀏覽 22分鐘

         ·

        2021-08-18 08:57

        點(diǎn)擊上方藍(lán)色字體,關(guān)注我們



        1


        ScrollView嵌套ListContainer


        就ScrollView嵌套ListContainer的滑動(dòng)問題,社區(qū)問答中也是遇見了兩次提問的小伙伴。在幫助第一個(gè)小伙解決這個(gè)問題的時(shí)候,我提供了一個(gè)思路和以前在寫Android ScrollView嵌套ListView滑動(dòng)問題的解決方法。


        經(jīng)過方法的修改也是解決了他的問題,后續(xù)沒有再把這個(gè)問題解決的全過程記錄下來,直到發(fā)現(xiàn)有第二個(gè)小伙伴也遇到了同樣的問題,準(zhǔn)備把這個(gè)小問題寫成一篇帖子,希望后面再遇到“ScrollView嵌套ListContainer 滑動(dòng)問題”的同學(xué)可以幫助到你們。


        2


        思路


        一、ScrollView嵌套ListContainer  想讓ListContainer不滑動(dòng),只滑動(dòng)ScrollView。在Android中有個(gè)東西叫做攔截器,ScrollView的攔截器,通過對(duì)攔截器的賦值達(dá)到只滑動(dòng)ScrollView,不滑動(dòng)ListView。


        調(diào)用方式如下:


        因?yàn)镾crollView繼承自ViewGroup,在ViewGroup中有dispatchTouchEvent()這個(gè)方法,

        但是在HarmonyOS中,ScrollView繼承自ComponentContainer,而且在ComponentContainer中沒有類似于dispatchTouchEvent的攔截器方法,那么攔截器不能搞就得換方法。


        二、這時(shí)第二個(gè)思路也成型了,因?yàn)镾crollView的高度是根據(jù)它內(nèi)部的組件的高度變化的,當(dāng)內(nèi)部的組件高度大于手機(jī)屏幕的高度時(shí)會(huì)出現(xiàn)ScrollView的滾動(dòng),反之不會(huì)出現(xiàn)。


        那么就只能從ScrollView的高度入手了,要改變ScrollView的高度就必須去改變它內(nèi)部組件的高度,那么問題來了ScrollView嵌套ListContainer,ListContainer的高度最大只能到屏幕大小或者是固定于屏幕內(nèi)部,一旦高度達(dá)到所設(shè)置的高度,ListContainer就會(huì)出現(xiàn)自動(dòng)滾動(dòng)此時(shí)ScrollView的滾動(dòng)也會(huì)失效,這里是焦點(diǎn)的關(guān)系滑動(dòng)動(dòng)作取到的焦點(diǎn)會(huì)在它當(dāng)前組件上。

        思路到這里也就清晰了,ListContainer的高度大于原始設(shè)置的高度時(shí)會(huì)發(fā)生滑動(dòng),ScrollView在內(nèi)部組件高度大于手機(jī)屏幕時(shí)才會(huì)滑動(dòng)。那么如果把ListContainer的高度設(shè)置成一個(gè)動(dòng)態(tài)的固定值,ListContainer的數(shù)據(jù)永遠(yuǎn)不會(huì)被填充滿,ListContainer就不會(huì)出現(xiàn)滑動(dòng)。隨即ListContainer的高度如果大于了屏幕的高度ScrollView就會(huì)滑動(dòng)。


        OK,問題找到了,解決ListContainer的動(dòng)態(tài)高度就解決的滑動(dòng)沖突。


        3


        解決問題


        首先我找到了當(dāng)初寫Android時(shí)動(dòng)態(tài)Listview高度的方法。這里就粘一下圖


        思路沒有變,將每次listview的Item高度相加作為listview的整體高度,listview的高度就是動(dòng)態(tài)的變化,listview的高度會(huì)根據(jù)數(shù)據(jù)的增加而變化。

        下面開始寫代碼首先整體布局文件,很簡單ScrollView嵌套ListContainer為了效果明顯加入了一個(gè)圖片:

        <?xml version="1.0" encoding="utf-8"?>
        <DirectionalLayout
        xmlns:ohos="http://schemas.huawei.com/res/ohos"
        ohos:height="match_parent"
        ohos:width="match_parent">
        <ScrollView
        ohos:id="$+id:view"
        ohos:height="match_parent"
        ohos:width="match_parent">
        <!--設(shè)置DirectionalLayout的高度為match_parent-->
        <DirectionalLayout
        ohos:height="match_parent"
        ohos:width="match_parent"
        ohos:alignment="center"
        ohos:orientation="vertical">
        <Image
        ohos:id="$+id:img"
        ohos:height="100vp"
        ohos:width="100vp"
        ohos:image_src="$media:icon"></Image>
        <ListContainer
        ohos:id="$+id:list"
        ohos:height="match_parent"
        ohos:width="match_parent"
        ></ListContainer>
        </DirectionalLayout>
        </ScrollView>
        </DirectionalLayout>


        ListContainer的Item 布局,這里很簡單就放一個(gè)文本:

        <?xml version="1.0" encoding="utf-8"?>
        <DirectionalLayout
        xmlns:ohos="http://schemas.huawei.com/res/ohos"
        ohos:height="match_content"
        ohos:width="match_parent"
        ohos:left_margin="16vp"
        ohos:right_margin="16vp"
        ohos:orientation="vertical">
        <Text
        ohos:id="$+id:item_index"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:padding="4vp"
        ohos:text="Item0"
        ohos:text_size="20fp"
        ohos:layout_alignment="center"/>
        </DirectionalLayout>


        創(chuàng)建SampleItem.java,作為ListContainer的數(shù)據(jù)包裝類:

        public class SampleItem {
            private String name;
            public SampleItem(String name) {
                this.name = name;
            }
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
        }


        寫一個(gè)ListContainer的適配器用于放數(shù)據(jù):

        public class SampleItemProvider extends BaseItemProvider {

            private List<SampleItem> list;
            private AbilitySlice slice;

            public SampleItemProvider(List<SampleItem> list, AbilitySlice slice) {
                this.list = list;
                this.slice = slice;
            }

            @Override
            public int getCount() {
                return list == null ? 0 : list.size();
            }

            @Override
            public Object getItem(int position) {
                if (list != null && position >= 0 && position < list.size()){
                    return list.get(position);
                }
                return null;
            }

            @Override
            public long getItemId(int position) {
                return position;
            }

            @Override
            public Component getComponent(int position, Component component, ComponentContainer componentContainer) {
                final Component cpt;
                if (component == null) {
                    cpt = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_item_sample, nullfalse);
                } else {
                    cpt = component;
                }
                SampleItem sampleItem = list.get(position);
                Text text = (Text) cpt.findComponentById(ResourceTable.Id_item_index);
                text.setText(sampleItem.getName());
                return cpt;
            }
        }


        在Java代碼中添加ListContainer的數(shù)據(jù),并適配其數(shù)據(jù)結(jié)構(gòu)。還沒有加動(dòng)態(tài)高度的方法:

        public class MainAbilitySlice extends AbilitySlice {

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

            private void initListContainer() {
                ListContainer listContainer = (ListContainer) findComponentById(ResourceTable.Id_list);
                List<SampleItem> list = getData();
                listContainer.setBoundarySwitch(true);  //添加分界線
                SampleItemProvider sampleItemProvider = new SampleItemProvider(list, this);
                listContainer.setItemProvider(sampleItemProvider);
            }

            private ArrayList<SampleItem> getData() {
                ArrayList<SampleItem> list = new ArrayList<>();
                for (int i = 0; i < 30; i++) {
                    list.add(new SampleItem("Item" + i));
                }
                return list;
            }
        }


        查看效果:

        編寫自定義高度方法:

        private void setListContainerHeight(ListContainer listContainer) {
                //獲取當(dāng)前l(fā)istContainer的適配器
                BaseItemProvider BaseItemProvider = listContainer.getItemProvider();
               if (BaseItemProvider == null){
                   return;
               }
                int itemHeight = 0;
                for (int i = 0; i < BaseItemProvider.getCount(); i++) {
                    //循環(huán)將listContainer適配器的Item數(shù)據(jù)進(jìn)行累加
                    Component listItem = BaseItemProvider.getComponent(i, null, listContainer);
                    itemHeight += listItem.getHeight();
                }
                //對(duì)當(dāng)前l(fā)istContainer進(jìn)行高度賦值
                ComponentContainer.LayoutConfig config = listContainer.getLayoutConfig();
                //這邊加上(listContainer.getBoundaryThickness() * (BaseItemProvider.getCount()+1))
                //listContainer.getBoundaryThickness() 就是分界線的高度
                //(BaseItemProvider.getCount()+1) 是Item的數(shù)量  加1  是因?yàn)轫敳窟€有一條分界線
                config.height = itemHeight
                        + (listContainer.getBoundaryThickness() * (BaseItemProvider.getCount()+1));
                //賦值
                listContainer.setLayoutConfig(config);
            }


        調(diào)用方法:

        實(shí)現(xiàn)效果:

        出問題了,不能滑動(dòng)!?。。。。?!


        ==找到了,問題在布局中==


        重新運(yùn)行,查看結(jié)果:


        OK了,以達(dá)到了最終的效果。代碼放在了下面的閱讀原文鏈接里,大家可以點(diǎn)擊參考。


        往期推薦



        點(diǎn)擊閱讀原文,更精彩~
        瀏覽 43
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            日逼黄片 | 小sao货怎么这么欠cao 岳今晚让你弄个够丝袜腿视频 | 国产精品久久久婷婷五月 | 欧美国产综合福利在线 | 射射射综合网 | 小泽玛利亚黑人初体验 | 性爱网站在线观看 | 草b视频| 狠狠操狠狠干 | 蜜桃在线码无精品秘 入口九色 |