我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android开机动画

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android开机动画

Android开机动画

android12-release
推荐 Android 12 开机动画代码与流程详解


在这里插入图片描述

1、BootLoader开机图片

一般使用rle格式图片;例如放在splash分区

adb reboot bootloaderfastboot flash splash splash.imgfastboot reboot

2、Kernel开机图片

记录 kernel/drivers/video/msm/msm_fb.c 也是读出根目录下的xx.rle,并显示为开机画面

3、系统启动时(BootAnimation)动画

使用BootAnimation程序显示开机画面,如需修改开机画面,不用修改代码,只需按格式要求做bootanimation.zip包,放在系统的/system/media目录中,或/oem/media/product/media等目录。

代码路径:frameworks/base/cmds/bootanimation

3.1 bootanimation.zip位置

frameworks/base/cmds/bootanimation/BootAnimation.cpp,例如bootanimation.zip
在这里插入图片描述

3.2 bootanimation启动

frameworks/base/cmds/bootanimation/Android.bp
frameworks/base/cmds/bootanimation/bootanim.rc
frameworks/base/cmds/bootanimation/bootanimation_main.cpp
frameworks/base/cmds/bootanimation/BootAnimation.cpp
frameworks/base/cmds/bootanimation/BootAnimationUtil.cpp

SurfaceFlinger进程名:bootanim
bin文件:/system/bin/bootanimation
对应启动入口:/frameworks/base/cmds/bootanimation/bootanimation_main.cpp

bootAnimationDisabled()检测系统属性(debug.sf.nobootanimation、ro.boot.quiescent、ro.bootanim.quiescent.enabled),noBootAnimation 是否启动开机动画。注意init进程在启动bootanimation服务是disable的,不会主动将应用程序bootanimation启动起来。启动bootanimation是从surfaceFlinger这边来启动的

frameworks/base/cmds/bootanimation/bootanimation_main.cpp

int main(){    setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);    bool noBootAnimation = bootAnimationDisabled();    ALOGI_IF(noBootAnimation,  "boot animation disabled");    if (!noBootAnimation) {        sp<ProcessState> proc(ProcessState::self());        ProcessState::self()->startThreadPool();        // create the boot animation object (may take up to 200ms for 2MB zip)        sp<BootAnimation> boot = new BootAnimation(audioplay::createAnimationCallbacks());        waitForSurfaceFlinger();        boot->run("BootAnimation", PRIORITY_DISPLAY);        ALOGV("Boot animation set up. Joining pool.");        IPCThreadState::self()->joinThreadPool();    }    return 0;}

frameworks/base/cmds/bootanimation/BootAnimationUtil.cpp

bool bootAnimationDisabled() {    char value[PROPERTY_VALUE_MAX];    property_get("debug.sf.nobootanimation", value, "0");    if (atoi(value) > 0) {        return true;    }    property_get("ro.boot.quiescent", value, "0");    if (atoi(value) > 0) {        // Only show the bootanimation for quiescent boots if this system property is set to enabled        if (!property_get_bool("ro.bootanim.quiescent.enabled", false)) {            return true;        }    }    return false;}

3.3 SurfaceFlinger启动bootanimation

SurfaceFlinger启动-Android12 初始化时候 mStartPropertySetThread->Start() 在线程中设置property_set("ctl.start", "bootanim")启动开机动画

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
frameworks/native/services/surfaceflinger/StartPropertySetThread.cpp

#include #include "StartPropertySetThread.h"namespace android {StartPropertySetThread::StartPropertySetThread(bool timestampPropertyValue):        Thread(false), mTimestampPropertyValue(timestampPropertyValue) {}status_t StartPropertySetThread::Start() {    return run("SurfaceFlinger::StartPropertySetThread", PRIORITY_NORMAL);}bool StartPropertySetThread::threadLoop() {    // Set property service.sf.present_timestamp, consumer need check its readiness    property_set(kTimestampProperty, mTimestampPropertyValue ? "1" : "0");    // Clear BootAnimation exit flag    property_set("service.bootanim.exit", "0");    property_set("service.bootanim.progress", "0");    // Start BootAnimation if not started    property_set("ctl.start", "bootanim");    // Exit immediately    return false;}} // namespace android

3.4 播放开机动画playAnimation

  • result = android()android原生动画;result = movie()自动动画
  • playAnimation(*mAnimation)播放动画;releaseAnimation(mAnimation)释放动画资源
  • 播放动画过程:initTexture(frame.map, &w, &h)drawClock(animation.clockFont, part.clockPosX, part.clockPosY)drawProgress(lastDisplayedProgress, animation.progressFont, posX, posY)checkExit()
  • checkExit()检测属性"service.bootanim.exit"退出动画
bool BootAnimation::threadLoop() {    bool result;    // We have no bootanimation file, so we use the stock android logo    // animation.    if (mZipFileName.isEmpty()) {        result = android();    } else {        result = movie();    }    mCallbacks->shutdown();    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);    eglDestroyContext(mDisplay, mContext);    eglDestroySurface(mDisplay, mSurface);    mFlingerSurface.clear();    mFlingerSurfaceControl.clear();    eglTerminate(mDisplay);    eglReleaseThread();    IPCThreadState::self()->stopProcess();    return result;}
bool BootAnimation::movie() {    if (mAnimation == nullptr) {        mAnimation = loadAnimation(mZipFileName);    }    if (mAnimation == nullptr)        return false;    // mCallbacks->init() may get called recursively,    // this loop is needed to get the same results    for (const Animation::Part& part : mAnimation->parts) {        if (part.animation != nullptr) {            mCallbacks->init(part.animation->parts);        }    }    mCallbacks->init(mAnimation->parts);    bool anyPartHasClock = false;    for (size_t i=0; i < mAnimation->parts.size(); i++) {        if(validClock(mAnimation->parts[i])) {            anyPartHasClock = true;            break;        }    }    if (!anyPartHasClock) {        mClockEnabled = false;    }    // Check if npot textures are supported    mUseNpotTextures = false;    String8 gl_extensions;    const char* exts = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));    if (!exts) {        glGetError();    } else {        gl_extensions.setTo(exts);        if ((gl_extensions.find("GL_ARB_texture_non_power_of_two") != -1) ||            (gl_extensions.find("GL_OES_texture_npot") != -1)) {            mUseNpotTextures = true;        }    }    // Blend required to draw time on top of animation frames.    glBlendFunc(GL_class="lazy" data-src_ALPHA, GL_ONE_MINUS_class="lazy" data-src_ALPHA);    glShadeModel(GL_FLAT);    glDisable(GL_DITHER);    glDisable(GL_SCISSOR_TEST);    glDisable(GL_BLEND);    glBindTexture(GL_TEXTURE_2D, 0);    glEnable(GL_TEXTURE_2D);    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    bool clockFontInitialized = false;    if (mClockEnabled) {        clockFontInitialized =            (initFont(&mAnimation->clockFont, CLOCK_FONT_ASSET) == NO_ERROR);        mClockEnabled = clockFontInitialized;    }    initFont(&mAnimation->progressFont, PROGRESS_FONT_ASSET);    if (mClockEnabled && !updateIsTimeAccurate()) {        mTimeCheckThread = new TimeCheckThread(this);        mTimeCheckThread->run("BootAnimation::TimeCheckThread", PRIORITY_NORMAL);    }    playAnimation(*mAnimation);    if (mTimeCheckThread != nullptr) {        mTimeCheckThread->requestExit();        mTimeCheckThread = nullptr;    }    if (clockFontInitialized) {        glDeleteTextures(1, &mAnimation->clockFont.texture.name);    }    releaseAnimation(mAnimation);    mAnimation = nullptr;    return false;}
bool BootAnimation::playAnimation(const Animation& animation) {    const size_t pcount = animation.parts.size();    nsecs_t frameDuration = s2ns(1) / animation.fps;    SLOGD("%sAnimationShownTiming start time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",            elapsedRealtime());    int fadedFramesCount = 0;    int lastDisplayedProgress = 0;    for (size_t i=0 ; i<pcount ; i++) {        const Animation::Part& part(animation.parts[i]);        const size_t fcount = part.frames.size();        glBindTexture(GL_TEXTURE_2D, 0);        // Handle animation package        if (part.animation != nullptr) {            playAnimation(*part.animation);            if (exitPending())                break;            continue; //to next part        }        // process the part not only while the count allows but also if already fading        for (int r=0 ; !part.count || r<part.count || fadedFramesCount > 0 ; r++) {            if (shouldStopPlayingPart(part, fadedFramesCount, lastDisplayedProgress)) break;            mCallbacks->playPart(i, part, r);            glClearColor(                    part.backgroundColor[0],                    part.backgroundColor[1],                    part.backgroundColor[2],                    1.0f);            // For the last animation, if we have progress indicator from            // the system, display it.            int currentProgress = android::base::GetIntProperty(PROGRESS_PROP_NAME, 0);            bool displayProgress = animation.progressEnabled &&                (i == (pcount -1)) && currentProgress != 0;            for (size_t j=0 ; j<fcount ; j++) {                if (shouldStopPlayingPart(part, fadedFramesCount, lastDisplayedProgress)) break;                processDisplayEvents();                const int animationX = (mWidth - animation.width) / 2;                const int animationY = (mHeight - animation.height) / 2;                const Animation::Frame& frame(part.frames[j]);                nsecs_t lastFrame = systemTime();                if (r > 0) {                    glBindTexture(GL_TEXTURE_2D, frame.tid);                } else {                    if (part.count != 1) {                        glGenTextures(1, &frame.tid);                        glBindTexture(GL_TEXTURE_2D, frame.tid);                        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);                        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);                    }                    int w, h;                    initTexture(frame.map, &w, &h);                }                const int xc = animationX + frame.trimX;                const int yc = animationY + frame.trimY;                Region clearReg(Rect(mWidth, mHeight));                clearReg.subtractSelf(Rect(xc, yc, xc+frame.trimWidth, yc+frame.trimHeight));                if (!clearReg.isEmpty()) {                    Region::const_iterator head(clearReg.begin());                    Region::const_iterator tail(clearReg.end());                    glEnable(GL_SCISSOR_TEST);                    while (head != tail) {                        const Rect& r2(*head++);                        glScissor(r2.left, mHeight - r2.bottom, r2.width(), r2.height());                        glClear(GL_COLOR_BUFFER_BIT);                    }                    glDisable(GL_SCISSOR_TEST);                }                // specify the y center as ceiling((mHeight - frame.trimHeight) / 2)                // which is equivalent to mHeight - (yc + frame.trimHeight)                const int frameDrawY = mHeight - (yc + frame.trimHeight);                glDrawTexiOES(xc, frameDrawY, 0, frame.trimWidth, frame.trimHeight);                // if the part hasn't been stopped yet then continue fading if necessary                if (exitPending() && part.hasFadingPhase()) {                    fadeFrame(xc, frameDrawY, frame.trimWidth, frame.trimHeight, part,  ++fadedFramesCount);                    if (fadedFramesCount >= part.framesToFadeCount) {                        fadedFramesCount = MAX_FADED_FRAMES_COUNT; // no more fading                    }                }                if (mClockEnabled && mTimeIsAccurate && validClock(part)) {                    drawClock(animation.clockFont, part.clockPosX, part.clockPosY);                }                if (displayProgress) {                    int newProgress = android::base::GetIntProperty(PROGRESS_PROP_NAME, 0);                    // In case the new progress jumped suddenly, still show an                    // increment of 1.                    if (lastDisplayedProgress != 100) {                      // Artificially sleep 1/10th a second to slow down the animation.                      usleep(100000);                      if (lastDisplayedProgress < newProgress) {                        lastDisplayedProgress++;                      }                    }                    // Put the progress percentage right below the animation.                    int posY = animation.height / 3;                    int posX = TEXT_CENTER_VALUE;                    drawProgress(lastDisplayedProgress, animation.progressFont, posX, posY);                }                handleViewport(frameDuration);                eglSwapBuffers(mDisplay, mSurface);                nsecs_t now = systemTime();                nsecs_t delay = frameDuration - (now - lastFrame);                //SLOGD("%lld, %lld", ns2ms(now - lastFrame), ns2ms(delay));                lastFrame = now;                if (delay > 0) {                    struct timespec spec;                    spec.tv_sec  = (now + delay) / 1000000000;                    spec.tv_nsec = (now + delay) % 1000000000;                    int err;                    do {                        err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, nullptr);                    } while (err<0 && errno == EINTR);                }                checkExit();            }            usleep(part.pause * ns2us(frameDuration));            if (exitPending() && !part.count && mCurrentInset >= mTargetInset &&                !part.hasFadingPhase()) {                if (lastDisplayedProgress != 0 && lastDisplayedProgress != 100) {                    android::base::SetProperty(PROGRESS_PROP_NAME, "100");                    continue;                }                break; // exit the infinite non-fading part when it has been played at least once            }        }    }    // Free textures created for looping parts now that the animation is done.    for (const Animation::Part& part : animation.parts) {        if (part.count != 1) {            const size_t fcount = part.frames.size();            for (size_t j = 0; j < fcount; j++) {                const Animation::Frame& frame(part.frames[j]);                glDeleteTextures(1, &frame.tid);            }        }    }    return true;}

3.6 开机动画退出检测

  • checkExit()检测属性"service.bootanim.exit"退出动画;在playAnimation方法和android方法中都有一个checkExit方法来负责检查是否退出动画
  • WMS中performEnableScreen()设置SystemProperties.set("service.bootanim.exit", "1")
void BootAnimation::checkExit() {    // Allow surface flinger to gracefully request shutdown    char value[PROPERTY_VALUE_MAX];    property_get(EXIT_PROP_NAME, value, "0");    int exitnow = atoi(value);    if (exitnow) {        requestExit();    }}

在这里插入图片描述

private void performEnableScreen() {    synchronized (mGlobalLock) {        ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: mDisplayEnabled=%b"                        + " mForceDisplayEnabled=%b" + " mShowingBootMessages=%b"                        + " mSystemBooted=%b mOnlyCore=%b. %s", mDisplayEnabled,                mForceDisplayEnabled, mShowingBootMessages, mSystemBooted, mOnlyCore,                new RuntimeException("here").fillInStackTrace());        if (mDisplayEnabled) {            return;        }        if (!mSystemBooted && !mShowingBootMessages) {            return;        }        if (!mShowingBootMessages && !mPolicy.canDismissBootAnimation()) {            return;        }        // Don't enable the screen until all existing windows have been drawn.        if (!mForceDisplayEnabled) {            if (mBootWaitForWindowsStartTime < 0) {                // First time we will start waiting for all windows to be drawn.                mBootWaitForWindowsStartTime = SystemClock.elapsedRealtime();            }            for (int i = mRoot.getChildCount() - 1; i >= 0; i--) {                if (mRoot.getChildAt(i).shouldWaitForSystemDecorWindowsOnBoot()) {                    return;                }            }            long waitTime = SystemClock.elapsedRealtime() - mBootWaitForWindowsStartTime;            mBootWaitForWindowsStartTime = -1;            if (waitTime > 10) {                ProtoLog.i(WM_DEBUG_BOOT,                        "performEnableScreen: Waited %dms for all windows to be drawn",                        waitTime);            }        }        if (!mBootAnimationStopped) {            Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);            // stop boot animation            // formerly we would just kill the process, but we now ask it to exit so it            // can choose where to stop the animation.            SystemProperties.set("service.bootanim.exit", "1");            mBootAnimationStopped = true;        }        if (!mForceDisplayEnabled && !checkBootAnimationCompleteLocked()) {            ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: Waiting for anim complete");            return;        }        try {            IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");            if (surfaceFlinger != null) {                ProtoLog.i(WM_ERROR, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");                Parcel data = Parcel.obtain();                data.writeInterfaceToken("android.ui.ISurfaceComposer");                surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED                        data, null, 0);                data.recycle();            }        } catch (RemoteException ex) {            ProtoLog.e(WM_ERROR, "Boot completed: SurfaceFlinger is dead!");        }        EventLogTags.writeWmBootAnimationDone(SystemClock.uptimeMillis());        Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);        mDisplayEnabled = true;        ProtoLog.i(WM_DEBUG_SCREEN_ON, "******************** ENABLING SCREEN!");        // Enable input dispatch.        mInputManagerCallback.setEventDispatchingLw(mEventDispatchingEnabled);    }    try {        mActivityManager.bootAnimationComplete();    } catch (RemoteException e) {    }    mPolicy.enableScreenAfterBoot();    // Make sure the last requested orientation has been applied.    updateRotationUnchecked(false, false);}

3.7 简易时序图

在这里插入图片描述

4、bootanimation.zip文件

bootanimation.zip
在这里插入图片描述 在这里插入图片描述
bootanimation.zip\desc.txt:

1080 2400 5p 0 5 part0

bootanimation.zip\part0:
在这里插入图片描述

来源地址:https://blog.csdn.net/qq_23452385/article/details/132639363

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android开机动画

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android开机动画制作的方法是什么

Android开机动画通常是通过修改系统文件来实现的。具体方法如下:获取Root权限:首先需要获取Root权限,以便能够修改系统文件。可以通过Root手机或使用Root工具(如Magisk、SuperSU等)来获取Root权限。查找系统文件
2023-10-26

Android模拟开关按钮点击打开动画(属性动画之平移动画)

在Android里面,一些炫酷的动画确实是很吸引人的地方,让然看了就赏心悦目,一个好看的动画可能会提高用户对软件的使用率。另外说到动画,在Android里面支持两种动画:补间动画和属性动画,至于这两种动画的区别这里不再介绍,希望开发者都能在
2022-06-06

Android动画-属性动画

属性动画 所谓属性动画,就是改变对象Object的属性来实现动画过程。属性动画是对View的动画的扩展,通过它可以实现更多漂亮的动画效果。同时属性动画的作用对象不仅仅是View,任何对象都可以。 属性动画的作用效果就是:在一个指定的时间段内
2022-06-06

Android动画 实现开关按钮动画(属性动画之平移动画)实例代码

Android动画 实现开关按钮动画(属性动画之平移动画),最近做项目,根据项目需求,有一个这样的功能,实现类似开关的动画效果,经过自己琢磨及上网查找资料,终于解决了,这里就记录下:在Android里面,一些炫酷的动画确实是很吸引人的地方,
2022-06-06

Android 开机充电图标和充电动画效果

首先驱动需要先获取到2个power supply kernel\msm-3.18\drivers\usb\phy\phy-msm-usb.cmotg->usb_psy.name = "usb"; motg->usb_psy.type = P
2022-06-06

Android动画

源码地址: https://download.csdn.net/download/dreams_deng/12236355 1. 理论知识 1.1 动画类型: View动画 :   View本身在动 Drawable动画:  View中内容
2022-06-06

Android开场动画怎么实现

要实现Android开场动画,可以使用以下方法:1. 使用帧动画(Frame Animation):创建一个包含多个帧图片的动画资源文件,然后通过ImageView在XML布局文件中引用该动画资源文件,并设置动画属性。在代码中通过Image
2023-08-08

Android 动画(View动画,帧动画,属性动画)详细介绍

0. 前言 Android动画是面试的时候经常被问到的话题。我们都知道Android动画分为三类:View动画、帧动画和属性动画。先对这三种动画做一个概述:View动画是一种渐进式动画,通过图像的平移、缩放、旋转和透明度等各种渐进式变换完
2022-06-06

Android开发之动画实现方法

本文实例讲述了Android开发之动画实现方法。分享给大家供大家参考。具体分析如下: 动画分为三种: 逐帧动画、布局动画和控件动画 控件动画实现 通过重写Animation的 applyTransformation (float inter
2022-06-06

Android开场动画代码怎么写

Android开场动画可以通过使用Android的动画框架来实现。以下是一个例子,展示如何在Android开场动画中淡入一个ImageView:1. 首先,在布局文件中添加一个ImageView并设置相应的属性:```xmlandroid:
2023-08-18

Win8系统怎么取消掉开机动画?取消掉开机动画的办法

Win8系统取消开机动画的步骤:1、Win8系统传统桌面,右键点击【计算机】,选择【属性】,接着在打开的计算机属性窗口上点击【高级系统设置】项;2、在系统属性窗口上,点击性能后面的“设置”按钮,打开【性能选项】窗口;
2022-06-04

win11开机动画如何关闭

这篇文章主要介绍了win11开机动画如何关闭的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇win11开机动画如何关闭文章都会有所收获,下面我们一起来看看吧。1、首先我们按下键盘上的“Win+R”调出“运行” 2
2023-07-01

Android动画探索之属性动画

这篇文章来总结下属性动画,通过下面几点来了解下属性动画的内容: 属性动画概述 属性动画工作原理 ValueAnimator ObjectAnimator ValueAnimator和ObjectAnimator区别 插值器 估值期 插值器和
2022-06-06

我的Android开发之旅(四):Android三种动画效果的浅入之帧动画

我的Android开发之旅(四):Android三种动画效果的浅入之帧动画1. 前言2. 帧动画3. 如何使用3.1 AnimationDrawable3.2 Xml实现3.3 Java实现4. 淡入淡出动画5. 尾声 1. 前言 ​ A
2022-06-06

我的Android开发之旅(二):Android三种动画效果的浅入之View动画

我的Android开发之旅(二):Android三种动画效果的浅入之View动画前言View动画Animation类1. 平移动画2. 缩放动画3. 旋转动画4. 透明动画AnimationSet 动画集合自定义View动画补充 前言 在A
2022-06-06

Android 动画之帧动画用法详解

本文目录帧动画概念帧动画实现方法1:xml实现帧动画第一步:导入帧动画素材第二步:创建帧动画文件第三步:布局文件和Activity方法2:用Java代码实现帧动画 帧动画概念 在Android中,帧动画的本质是把一组预先准备好的图片循环切换
2022-06-06

Android属性动画

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。 目录 一、导读二、概览三、常用API3.1 Valu
Android属性动画
2023-12-22

Android帧动画、补间动画、属性动画用法详解

在安卓开发中,经常会使用到一些动画,那么在开发中,如何使用这些动画呢? 帧动画:不是针对View做出一些形状上的变化,而是用于播放一张张的图片,例如一些开机动画,类似于电影播放,使用的是AnimationDrawable来播放帧动画 res
2022-06-06

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录