# Image组件根据不同状态设置不同资源

#### 问题现象

如何根据三种不同状态设置不同的资源，如正常态，显示图片1，按压态显示图片2，不可用态显示图片3？

#### 背景知识

*   对于需要在应用中显示图片的场景，例如：按钮中的icon、网络图片、本地图片等。可以使用Image组件实现，Image支持多种图片格式，包括png、jpg、bmp、svg、gif和heif类型的图片格式，具体用法请参考Image组件。
*   stateStyles可以依据组件的内部状态的不同，快速设置不同样式，目前提供了以下六种状态：
    *   focused：获焦态。
    *   normal：正常态。
    *   pressed：按压态。
    *   disabled：不可用态。
    *   clicked：点击态。
    *   selected：选中态。
*   触摸事件onTouch可以识别手指在屏幕上的各种状态，如按压、抬起、移动等，更多状态请参考TouchType。
*   长按手势LongPressGesture在识别成功后会触发onAction事件回调，更多参考回调事件。

#### 解决方案

*   **方案一**：通过stateStyles的normal、pressed、disabled实现，对三种状态设置不同的背景图。
    
    ```
    @Entry
    @Component
    struct Solution1 {
      @State imageEnable: boolean = true;
    
      // 正常态
      @Styles
      normalStyle() {
        .backgroundImage($r('app.media.normalStyle')); // 运行时替换为实际图片资源
      }
    
      // 按压态
      @Styles
      pressedStyle() {
        .backgroundImage($r('app.media.pressedStyle')); // 运行时替换为实际图片资源
      }
    
      // 不可用态
      @Styles
      unableStyle() {
        .backgroundImage($r('app.media.unableStyle')); // 运行时替换为实际图片资源
      }
    
      build() {
        Column() {
          Button('控制是否可用')
            .onClick(() => {
              this.imageEnable = !this.imageEnable;
            })
            .margin({ bottom: 30 }); // 按钮和图片之间的间距
    
          // 使用stateStyles控制不同状态的图片显示
          Column()
            .width(200)
            .height(200)
            .enabled(this.imageEnable)
            .backgroundImageSize({ width: 200, height: 200 })
            .backgroundImagePosition(Alignment.Center)
            .stateStyles({
              normal: this.normalStyle,
              disabled: this.unableStyle,
              pressed: this.pressedStyle
            });
        }
        .width('100%')
        .height('100%')
        .justifyContent(FlexAlign.Center)
        .alignItems(HorizontalAlign.Center);
      }
    }
    ```
    
*   **方案二**：通过onTouch的TouchType.Up与TouchType.Down实现正常态和按压态图片的切换。
    
    ```
    @Entry
    @Component
    struct Solution2 {
      @State imageSrc: Resource | string = $r('app.media.normalStyle'); // 运行时替换为实际图片资源
    
      build() {
        Column() {
          // 通过onTouch控制不同状态的图片显示
          Image(this.imageSrc)
            .onTouch((e) => {
              if (e.type === TouchType.Up) {
                // 手指抬起后切换为常态图片
                this.imageSrc = $r('app.media.normalStyle'); // 运行时替换为实际图片资源
              } else if (e.type === TouchType.Down) {
                // 手指按下后切换为按压态图片
                this.imageSrc = $r('app.media.pressedStyle'); // 运行时替换为实际图片资源
              }
            })
            .width(200)
            .height(200);
        }
        .height('100%')
        .width('100%')
        .justifyContent(FlexAlign.Center)
        .alignItems(HorizontalAlign.Center)
        .backgroundColor(Color.White);
      }
    }
    ```
    
*   **方案三**：通过LongPress手势识别成功回调修改展示的图片。在onAction中更改为按压态图片资源，在onActionEnd中改回正常态图片资源。
    
    ```
    @Entry
    @Component
    struct Solution3 {
      @State imageSrc: Resource | string = $r('app.media.normalStyle'); // 运行时替换为实际图片资源
    
      build() {
        Row() {
          Image(this.imageSrc)
            .width(200).height(200)
            .gesture(
              LongPressGesture({ repeat: true, duration: 100 })
                .onAction(() => {
                  this.imageSrc = $r('app.media.pressedStyle'); // 运行时替换为实际图片资源
                })
                .onActionEnd(() => {
                  this.imageSrc = $r('app.media.normalStyle'); // 运行时替换为实际图片资源
                })
            );
        }
        .height('100%')
        .width('100%')
        .justifyContent(FlexAlign.Center)
        .alignItems(VerticalAlign.Center);
      }
    }
    ```