Tabs和同方向滑动的子组件的滑动动作隔离
=====================

#### 问题现象

如何设置在横向拖动子组件中的第三方图标时，禁止触发Tabs的切换功能。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/cf/v3/IkeT1TvPRI69HfQ4YYKeEQ/zh-cn_image_0000002658838299.png?HW-CC-KV=V1&HW-CC-Date=20260709T134055Z&HW-CC-Expire=86400&HW-CC-Sign=DE3963127320A70A177848A2E7A89E5AE9D36432AC8CC9194D78709975F50459 "点击放大")

#### 背景知识

*   [!!双向绑定语法](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-binding)：在状态管理V2中，提供!!语法糖统一处理双向绑定。
*   [Tabs.scrollable](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-tabs#scrollable)：设置是否可以通过滑动页面进行页面切换。
*   [TouchType](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-appendix-enums#touchtype)：触摸事件的类型。
*   [@ohos/mpchart](https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Fmpchart)：MPChart是一个包含各种类型图表的图表库，主要用于业务数据汇总，包括线形图、柱状图、饼状图、蜡烛图、气泡图、雷达图、瀑布图等自定义图表库。

#### 解决方案

1.  该方案基于@ohos/mpchart，执行ohpm i @ohos/mpchart命令安装MPChart三方库。
2.  使用!!语法，把判断Tabs是否可以通过滑动页面进行页面切换的isAllowScroll属性，在主页面和子组件中关联。
3.  子组件中图表触摸时，设置isAllowScroll属性为false，触摸结束手指抬起时，设置isAllowScroll属性为true。

import {
  JArrayList, _// 工具类：数据集合_
  EntryOhos,_/__/ 图表数据结构基础类_
  LineDataSet, _//线形图数据集合_
  ILineDataSet, _// 线形图数据集合的操作类_
  LineData, _//线形图数据包_
  LineChart, _// 线形图图表类_
  LineChartModel,_// 线形图配置构建类_
  MarkerView, _//图例形状_
} from '@ohos/mpchart';


@Entry
@ComponentV2
struct Index {
  @Local fontColor: string = '#182431';
  @Local selectedFontColor: string = '#007DFF';
  @Local currentIndex: number = 0;
  @Local selectedIndex: number = 0;
  @Local isAllowScroll: boolean = true;
  private controller: TabsController = new TabsController();


  private model: LineChartModel = new LineChartModel();
 _ // 构造数据选择监听器_

  @Builder tabBuilder(index: number, name: string) {
    Column() {
      Text(name)
        .fontColor(this.selectedIndex === index ? this.selectedFontColor : this.fontColor)
        .fontSize(16)
        .fontWeight(this.selectedIndex === index ? 500 : 400)
        .lineHeight(22)
        .margin({ top: 17, bottom: 7 })
      Divider()
        .strokeWidth(2)
        .color('#007DFF')
        .opacity(this.selectedIndex === index ? 1 : 0)
    }.width('100%')
  }


  build() {
    Column() {
      Tabs({ barPosition: BarPosition.Start, index: this.selectedIndex, controller: this.controller }) {
        TabContent() {
          Column().width('100%').height('100%').backgroundColor('#007DFF')
        }.tabBar(this.tabBuilder(0, 'blue'))


        TabContent() {
          Star({ isAllowScroll: this.isAllowScroll!! })
        }.tabBar(this.tabBuilder(1, 'LineChart'))


        TabContent() {
          Column().width('100%').height('100%').backgroundColor('#FFBF00')
        }.tabBar(this.tabBuilder(2, 'yellow'))
      }
      .scrollable(this.isAllowScroll)
      .vertical(false)
      .barMode(BarMode.Fixed)
      .barWidth(360)
      .barHeight(56)
      .animationDuration(400)
      .animationMode(AnimationMode.CONTENT\_FIRST)
      .onChange((index: number) => {
        console.log(\`onChange index:${index}\`);
        this.selectedIndex = index;
      })
      .width('100%')
      .height('100%')
      .backgroundColor('#F1F3F5')
    }.width('100%')
  }


}




@ComponentV2
struct Star {
  private model: LineChartModel = new LineChartModel();
  @Param isAllowScroll: boolean = true;
  @Event $isAllowScroll: (val: boolean) => void = () => {};

  _// 图表数据初始化_
  aboutToAppear() {


  _  // 初始化图表配置构建类_
    this.model = new LineChartModel();
    this.model.setDragEnabled(true);
    this.model.setScaleEnabled(true);
   _ // 为图表设置markerView_
    let normalMarker = new MarkerView();
    this.model.setMarker(normalMarker);
    _// 也可设置定义图表MarkerView_
    _// 生成图表数据_
    let lineData: LineData = this.getLineData();
    _// 将数据与图表配置类绑定_
    this.model.setData(lineData);
   _ // 设置图表最大的X轴显示范围，如不设置，则默认显示全部数据_
    this.model.setVisibleXRangeMaximum(20);
  }


  private getLineData(): LineData {


    let start: number = 1;
    let values: JArrayList<EntryOhos> = new JArrayList<EntryOhos>();
    for (let i = start; i < 30; i++) {
      values.add(new EntryOhos(i, i));
    }
    let dataSet = new LineDataSet(values, 'DataSet');
    let dataSetList: JArrayList<ILineDataSet> = new JArrayList<ILineDataSet>();
    dataSetList.add(dataSet);


    let lineData: LineData = new LineData(dataSetList);
    return lineData;
  }


  build() {
    Column() {
      LineChart({ model: this.model })
        .width('100%')
        .height('30%')
        .onTouch((event) => {
          if (event.type === TouchType.Down || event.type === TouchType.Move) {
            this.$isAllowScroll(false);
          } else if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
            this.$isAllowScroll(true);
          }
        })
    }


  }
}