草庐IT

android - 动画在 api 响应成功回调中不起作用

coder 2023-12-29 原文

如果在 api 调用的成功 block 中,展开动画将不起作用。但是,如果我将它从成功 block 中取出,那么它运行良好。

我必须在成功 block 中调用动画 block 。因为数据来自 api

这是示例。

getWeeklyWaterDate 方法:

public void getWeeklyWaterData(final WaterDataCallBack callBack)
{

    // Find last monday
    Calendar lastMonday = Calendar.getInstance();
    while (lastMonday.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY)
    {
        lastMonday.add(Calendar.DATE, -1);
    }

    Calendar now = Calendar.getInstance();

    lastMonday.add(Calendar.DAY_OF_YEAR, -1);
    lastMonday.set(Calendar.HOUR, 24);
    lastMonday.set(Calendar.MINUTE, 0);
    lastMonday.set(Calendar.SECOND, 0);
    lastMonday.set(Calendar.MILLISECOND, 0);


    HashMap<String, String> params = new HashMap<>();
    params.put("startDate", Utils.formatYYMMDDDTHHMMSSz(lastMonday.getTimeInMillis()));
    params.put("endDate", Utils.formatYYMMDDDTHHMMSSz(now.getTimeInMillis()));

    ServiceConnector.groupamaAPI.getMyWaters(params).enqueue(new SuccessCallback<MyWaterResponse>() {
        @Override
        public void onSuccess(Response<MyWaterResponse> response) {
            super.onSuccess(response);

            callBack.onWaterDataReceived(response.body());



        }
    });
}

从 fragment 中调用 getWeeklyWaterDataMethod。

WaterHelper.getCurrent().getWeeklyWaterData(new WaterHelper.WaterDataCallBack() {
        @Override
        public void onWaterDataReceived(MyWaterResponse waterResponse) {

            Collections.reverse(waterResponse.waterLogs);
            for (Integer i = 0 ; i < waterResponse.waterLogs.size() ; i++)
            {
                WaterLog waterLog = waterResponse.waterLogs.get(i);

                Calendar calendar = Calendar.getInstance();
                calendar.setTime(waterLog.LogDate);
                dates.add(calendar);
                waterAmounts.add(new WaterAmount(calendar, waterLog.WaterMililiter.intValue()));

            }

            prepareTotalAndAverage(waterResponse.waterAverage);
            prepareGraph2();
        }

    });

这是动画代码:

final Integer finalGraphMaxY = 6000;
            chartContainerLL.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
            {
         @Override
                public void onGlobalLayout()
                {
                    chartContainerLL.getViewTreeObserver().removeOnGlobalLayoutListener(this);

                    // Animate Bars
                    Integer totalHeight = chartContainerLL.getHeight();

                    ExpandHeightAnimation expandHeightAnimation = new ExpandHeightAnimation(barMonday, 55);
                    expandHeightAnimation.setDuration(800/* animation time */);
                    barMonday.startAnimation(expandHeightAnimation);

                    ExpandHeightAnimation expandHeightAnimation2 = new ExpandHeightAnimation(barTuesday, 30);
                    expandHeightAnimation2.setDuration(800/* animation time */);
                    barTuesday.startAnimation(expandHeightAnimation2);

                    ExpandHeightAnimation expandHeightAnimation3 = new ExpandHeightAnimation(barWednesday, 40);
                    expandHeightAnimation3.setDuration(800/* animation time */);
                    barWednesday.startAnimation(expandHeightAnimation3);


                    ExpandHeightAnimation expandHeightAnimation4 = new ExpandHeightAnimation(barThursday, 30);
                    expandHeightAnimation4.setDuration(800/* animation time */);
                    barThursday.startAnimation(expandHeightAnimation4);


                    ExpandHeightAnimation expandHeightAnimation5 = new ExpandHeightAnimation(barFriday, 40);
                    expandHeightAnimation5.setDuration(800/* animation time */);
                    barFriday.startAnimation(expandHeightAnimation5);

                    if(dates.size() >= 6 && dates.get(5).get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY)
                    {
                        ExpandHeightAnimation expandHeightAnimation6 = new ExpandHeightAnimation(barSaturday, totalHeight * getNeededDayWaterAmount(Calendar.SATURDAY).mililiter / finalGraphMaxY);
                        expandHeightAnimation6.setDuration(800/* animation time */);
                        barSaturday.startAnimation(expandHeightAnimation6);
                    }


                    if(dates.size() >= 7 && dates.get(6).get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY)
                    {
                        ExpandHeightAnimation expandHeightAnimation7 = new ExpandHeightAnimation(barSunday, totalHeight * getNeededDayWaterAmount(Calendar.SUNDAY).mililiter / finalGraphMaxY);
                        expandHeightAnimation7.setDuration(800/* animation time */);
                        barSunday.startAnimation(expandHeightAnimation7);
                    }
                }
            });

ExpandHeightAnimation 类

public class ExpandHeightAnimation extends Animation
{
    int targetHeight;
    View view;

    public ExpandHeightAnimation(View view, int targetHeight) {
        this.view = view;
        this.targetHeight = targetHeight;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        view.getLayoutParams().height = (int) (targetHeight * interpolatedTime);
        view.requestLayout();
    }

    @Override
    public void initialize(int width, int height, int parentWidth,
            int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
    }

    @Override
    public boolean willChangeBounds() {
        return true;
    }
}

最佳答案

在调用onCreate()onCreateView() 时需要添加GlobalLayoutListener

首先为动画添加两个标志。如果这两个都是真的,你的动画就会开始。

boolean animateFlag1 = false;
boolean animateFlag2 = false;

其次,在 onCreate() 中添加您的全局布局监听器:

llContainer.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
    {
        @Override
        public void onGlobalLayout()
        {
            llContainer.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            animateFlag1 = true;
            animate();

        }
    });

你可以看到当 onGlobalLayout() 调用时,移除监听器,将第一个标志设置为 true 并调用 animate 方法。

在这些之后,对开始动画的回调执行相同的操作。将您的第二个标志设置为 true,

@Override
public void success(Result result) {

    animateFlag2 = true;
    animate();

}

这里是 animate 方法,其中包含您之前编写的 onGlobalLayout() 方法代码。

private void animate(){
    if(animateFlag1 && animateFlag2){

        // Animate Bars
        ExpandHeightAnimation expandHeightAnimation = new ExpandHeightAnimation(view, 500);
        expandHeightAnimation.setDuration(800/* animation time */);
        view.startAnimation(expandHeightAnimation);

        //More your codes to animate


        //Set your all flags to false to prevent animating again
        animateFlag1 = animateFlag2 = false;

    }
}

关于android - 动画在 api 响应成功回调中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48825693/

有关android - 动画在 api 响应成功回调中不起作用的更多相关文章

  1. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  2. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  3. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  4. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  5. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  6. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

  7. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  8. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  9. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  10. ruby-on-rails - Mandrill API 模板 - 2

    我正在使用Mandrill的RubyAPIGem并使用以下简单的测试模板:testastic按照Heroku指南中的示例,我有以下Ruby代码:require'mandrill'm=Mandrill::API.newrendered=m.templates.render'test-template',[{:header=>'someheadertext',:main_section=>'Themaincontentblock',:footer=>'asdf'}]mail(:to=>"JaysonLane",:subject=>"TestEmail")do|format|format.h

随机推荐