<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 10512字,需瀏覽 22分鐘

           ·

          2021-08-18 08:57

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



          1


          ScrollView嵌套ListContainer


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


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


          2


          思路


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


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


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

          但是在HarmonyOS中,ScrollView繼承自ComponentContainer,而且在ComponentContainer中沒(méi)有類似于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)部組件的高度,那么問(wèn)題來(lá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,問(wèn)題找到了,解決ListContainer的動(dòng)態(tài)高度就解決的滑動(dòng)沖突。


          3


          解決問(wèn)題


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


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

          下面開始寫代碼首先整體布局文件,很簡(jiǎn)單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 布局,這里很簡(jiǎn)單就放一個(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,作為L(zhǎng)istContainer的數(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)。還沒(méi)有加動(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)效果:

          出問(wèn)題了,不能滑動(dòng)!?。。。。。?/p>


          ==找到了,問(wèn)題在布局中==


          重新運(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)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久婷婷五月综合 | 操操操操操操操操操逼 | 亚洲日韩欧美另类 | 成人AV三级 | 国产激情无码视频网站 |