Опять же, какой из упомянутых мной типов масштабирования это? Мне кажется, вы решили растянуть его, то есть соотношение сторон не сохранено, и это означает, что ничего из того, что я написал, я не хочу достичь. Разве я не должен заставить холст двигаться? Что касается ссылки, то, что они называли «Масштабировать по размеру», выглядит как «fit-center», но он помещает содержимое в неправильное для меня место (внизу, а не по центру на портрете). Тот, который называется «Масштабирование до заливки», является центральным кадром, но я даже не вижу его нарисованным (на портрете). Пожалуйста, попробуйте.

меня есть небольшое приложение с живыми обоями, которое я хочу добавить для поддержки GIF-анимации.

Для этого я нашел различные решения. Есть решение показа GIF-анимации в виде (

Вот), и есть даже решение для показа его в живых обоях (Вот).Тем не менее, для них обоих я не могу найти, как правильно вписать содержимое анимации GIF в имеющееся пространство, что означает любое из следующего:

посев по центру - подходит для 100% контейнера (в данном случае экрана), обрезая по бокам (сверху и снизу или слева и справа) при необходимости Ничего не растягивает. Это означает, что содержимое выглядит нормально, но не все из него могут быть показаны.

Fit-Center - растянуть, чтобы соответствовать ширине / высотеcenter-inside - задайте исходный размер, отцентрируйте и растяните по ширине / высоте, только если они слишком велики.ПроблемаНа самом деле ни один из них не касается ImageView, поэтому я не могу просто использовать атрибут scaleType.

Что я нашел

Есть решение, которое дает вам GifDrawable (

Вот), который вы можете использовать в ImageView, но в некоторых случаях он кажется довольно медленным, и я не могу понять, как использовать его в LiveWallpaper, а затем подогнать его.Основной код обработки LiveWallpaper GIF как таковой (

Вот):Основной код для обработки GIF-анимации в представлении таков:

class GIFWallpaperService : WallpaperService() {
    override fun onCreateEngine(): WallpaperService.Engine {
        val movie = Movie.decodeStream(resources.openRawResource(R.raw.cinemagraphs))
        return GIFWallpaperEngine(movie)
    }

    private inner class GIFWallpaperEngine(private val movie: Movie) : WallpaperService.Engine() {
        private val frameDuration = 20

        private var holder: SurfaceHolder? = null
        private var visible: Boolean = false
        private val handler: Handler = Handler()
        private val drawGIF = Runnable { draw() }

        private fun draw() {
            if (visible) {
                val canvas = holder!!.lockCanvas()
                canvas.save()
                movie.draw(canvas, 0f, 0f)
                canvas.restore()
                holder!!.unlockCanvasAndPost(canvas)
                movie.setTime((System.currentTimeMillis() % movie.duration()).toInt())

                handler.removeCallbacks(drawGIF)
                handler.postDelayed(drawGIF, frameDuration.toLong())
            }
        }

        override fun onVisibilityChanged(visible: Boolean) {
            this.visible = visible
            if (visible)
                handler.post(drawGIF)
            else
                handler.removeCallbacks(drawGIF)
        }

        override fun onDestroy() {
            super.onDestroy()
            handler.removeCallbacks(drawGIF)
        }

        override fun onCreate(surfaceHolder: SurfaceHolder) {
            super.onCreate(surfaceHolder)
            this.holder = surfaceHolder
        }
    }
}

Вопросы

class CustomGifView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : View(context, attrs, defStyleAttr) {
    private var gifMovie: Movie? = null
    var movieWidth: Int = 0
    var movieHeight: Int = 0
    var movieDuration: Long = 0
    var mMovieStart: Long = 0

    init {
        isFocusable = true
        val gifInputStream = context.resources.openRawResource(R.raw.test)

        gifMovie = Movie.decodeStream(gifInputStream)
        movieWidth = gifMovie!!.width()
        movieHeight = gifMovie!!.height()
        movieDuration = gifMovie!!.duration().toLong()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        setMeasuredDimension(movieWidth, movieHeight)
    }

    override fun onDraw(canvas: Canvas) {

        val now = android.os.SystemClock.uptimeMillis()
        if (mMovieStart == 0L) {   // first time
            mMovieStart = now
        }
        if (gifMovie != null) {
            var dur = gifMovie!!.duration()
            if (dur == 0) {
                dur = 1000
            }
            val relTime = ((now - mMovieStart) % dur).toInt()
            gifMovie!!.setTime(relTime)
            gifMovie!!.draw(canvas, 0f, 0f)
            invalidate()
        }
    }
}
Учитывая анимацию в формате GIF, как я могу масштабировать ее каждым из вышеперечисленных способов?Возможно ли иметь одно решение для обоих случаев?Можно ли использовать библиотеку GifDrawable (или любую другую, пригодную для рисования) для живых обоев вместо класса Movie? Если да, то как?РЕДАКТИРОВАТЬ: после того, как я нашел способ масштабирования для 2-х видов, мне все равно нужно знать, как масштабировать в соответствии с третьим типом, а также узнать, почему происходит сбой после изменения ориентации, и почему он не всегда сразу показывает предварительный просмотр. ,

Я также хотел бы знать, каков наилучший способ показать анимацию GIF здесь, потому что в настоящее время я просто обновляю холст ~ 60 кадров в секунду (1000/60, ожидающий между каждыми 2 кадрами), без учета того, что находится в файле.

Проект доступен

ВотЕсли у вас есть.

Ответы на вопрос(3)

Ваш ответ на вопрос