鸿蒙自定义一个GifImage组件

创建一个空的工程

image-20210228112344661

在这个空工程下创建一个空的Module,指定Module为一个HarmonyOS libraryModule名称为Gif

image-20210228112528838

新建一个Gif类,继承自Image

package com.example.timestory.slice.Utils;

import com.example.timestory.slice.Utils.decoder.GifDecoder;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Image;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.RawFileEntry;
import ohos.global.resource.ResourceManager;
import ohos.global.resource.WrongTypeException;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author PengHuAnZhi
 * @createTime 2021/3/2 19:48
 * @projectName TimeStory
 * @className Gif.java
 * @description TODO
 */
public class Gif extends Image {
    
    

    private List<PixelMap> pixelMapList = new ArrayList<>();

    private static HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x000110, "GifImage");
    // 动画
    private AnimatorValue animatorValue;
    private ImageSource imageSource;
    private GifDecoder gifDecoder;
    private Boolean ispaused = false;
    private int duration;
    private float speed = 1;

    public void setSpeed(float speed1) {
    
    
        float EPSINON = (float) 0.00001;
        if (speed1 > EPSINON) {
    
    
            this.speed = speed1;
        }
        HiLog.info(label, "speed数据值" + (speed));
        animatorValue.stop();
        animatorValue.setDuration((long) (speed * duration));
        animatorValue.start();
        invalidate();
    }

    public Gif(Context context) {
    
    
        super(context);
    }

    public Gif(Context context, AttrSet attrSet) throws IOException, NotExistException, WrongTypeException {
    
    
        super(context, attrSet);
        gifDecoder = new GifDecoder();
        ResourceManager resourceManager = context.getResourceManager();
        ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
        sourceOptions.formatHint = "image/gif";

        if (attrSet.getAttr("image_src").isPresent()) {
    
    
            String id = attrSet.getAttr("image_src").get().getStringValue();
            Pattern pattern = Pattern.compile("[^0-9]");
            Matcher matcher = pattern.matcher(id);
            String all = matcher.replaceAll("");
            RawFileEntry rawFileEntry = resourceManager.getRawFileEntry(resourceManager.getMediaPath(Integer.parseInt(all)));
            ImageSource imageSource = ImageSource.create(rawFileEntry.openRawFile(), sourceOptions);
            gifDecoder.read(rawFileEntry.openRawFile(), (int) rawFileEntry.openRawFileDescriptor().getFileSize());

            if (imageSource != null) {
    
    
                init(imageSource);
            }
        } else {
    
    
            invalidate();
        }

    }


    private int i;
    // 动画侦听函数
    private final AnimatorValue.ValueUpdateListener mAnimatorUpdateListener
            = (animatorValue, v) -> {
    
    
        setPixelMap(pixelMapList.get((int) (v * pixelMapList.size())));
        invalidate();
    };

    private void init(ImageSource imageSource) {
    
    
        pixelMapList.clear();
        duration = 0;
        //  invalidate();
        ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
        decodingOptions.allowPartialImage = true;
        i = 1;
        if (gifDecoder.getFrameCount() > 0) {
    
    
            while (i < gifDecoder.getFrameCount()) {
    
    
                pixelMapList.add(imageSource.createPixelmap(i, decodingOptions));
                duration += gifDecoder.getDelay(i);
                i++;
            }
        } else {
    
    
            while (imageSource.createPixelmap(i, decodingOptions) != null) {
    
    
                pixelMapList.add(imageSource.createPixelmap(i, decodingOptions));
                duration += gifDecoder.getDelay(i);
                i++;
            }
        }
        // 启动动画
        HiLog.info(label, "持续时间" + duration);
        animatorValue = new AnimatorValue();
        animatorValue.setCurveType(Animator.CurveType.LINEAR);
        animatorValue.setDelay(100);
        animatorValue.setLoopedCount(Animator.INFINITE);
        animatorValue.setDuration(duration == 0 ? 3000 : duration);
        animatorValue.setValueUpdateListener(mAnimatorUpdateListener);
        animatorValue.start();
    }

    public void load(RawFileEntry rawFileEntry) throws IOException {
    
    
        gifDecoder.read(rawFileEntry.openRawFile(), (int) rawFileEntry.openRawFileDescriptor().getFileSize());
        ImageSource.SourceOptions sourceOption = new ImageSource.SourceOptions();
        imageSource = ImageSource.create(rawFileEntry.openRawFile(), sourceOption);
        if (imageSource != null) {
    
    
            init(imageSource);
        }
    }

    public void pause() {
    
    
        if (!ispaused) {
    
    
            ispaused = true;
        }
        animatorValue.pause();
        invalidate();
    }

    public void play() {
    
    
        if (ispaused) {
    
    
            ispaused = false;
        }
        animatorValue.start();
    }
}

然后引入解码工具包(工具包代码总计上千行,不贴出了,需要可私信我)

image-20210302195135090

然后在布局文件引用即可

image-20210302195417789

便于组件分享,使用Gradle工具发布har包,PackageDebugHarPackageDebugHar都可

image-20210228114933204

生成的har包可以在build/ourputs/har/debug/harbuild/ourputs/har/release/har目录下找到

image-20210228115051412

har包复制,粘贴到需要使用的工程的lib目录下(没有自己创建)

image-20210302195911692

由于build.gradle配置文件本身配置了扫描har包,所以完全不需其他配置即可使用

image-20210302200026548

猜你喜欢

转载自blog.csdn.net/qq_43509535/article/details/114293666