对象动画师不删除更新监听器android

2024-04-23

美好的一天。我有一个场景,这个半正常的对象动画师不断地反复触发,导致堆增长,当然在某些时候还会出现内存不足问题。这是如何进行的。我为这样的彩虹动画制作了静态方法。

  public static ObjectAnimator startRainbowAnimation(Context context,
                                                   String textToShow,
                                                   final TextView textViewToAttach) {
    AnimatedColorSpan span = new AnimatedColorSpan(context);
    final SpannableString spannableString = new SpannableString(textToShow);
    String substring = textToShow;
    int start = textToShow.indexOf(substring);
    int end = start + substring.length();
    spannableString.setSpan(span, start, end, 0);

    ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(
            span, ANIMATED_COLOR_SPAN_FLOAT_PROPERTY, 0, 100);
    objectAnimator.setEvaluator(new FloatEvaluator());
    objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            System.gc();
            Log.d("Fafasfasfas", "onAnimationUpdate: inside true");
            textViewToAttach.setText(spannableString);
        }
    });
    objectAnimator.setInterpolator(new LinearInterpolator());
    objectAnimator.setDuration(DURATION);
    objectAnimator.setRepeatCount(ValueAnimator.INFINITE);
    objectAnimator.start();
    return objectAnimator;
}

private static final Property<AnimatedColorSpan, Float> ANIMATED_COLOR_SPAN_FLOAT_PROPERTY
        = new Property<AnimatedColorSpan, Float>(Float.class, "ANIMATED_COLOR_SPAN_FLOAT_PROPERTY") {
    @Override
    public void set(AnimatedColorSpan span, Float value) {
        span.setTranslateXPercentage(value);
    }

    @Override
    public Float get(AnimatedColorSpan span) {
        return span.getTranslateXPercentage();
    }
};

我在 recyclerview 适配器中这样调用这个方法

 @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        ChatModel chatModel = chatModelList.get(position);

        System.gc();

        String messageBody = chatModel.getMessage().replaceAll("userid=" + chatModel.getUserId() + ":" + Constants.TYPE_MESSAGE_ATTACHMENT, "").replaceAll("userid=" + chatModel.getOpponentId() + ":" + Constants.TYPE_MESSAGE_ATTACHMENT, "");
        holder.message.setText(messageBody);
         if (showAsRainbow) {
                if (holder.message.getTag() == null) {
                    objectAnimator = RainbowAnimation.startRainbowAnimation(mContext, messageBody, holder.message);
                    holder.message.setTag(ANIMATED);
                }
            } else {
                objectAnimator.removeAllUpdateListeners();
                objectAnimator.removeAllListeners();
                objectAnimator.end();
                objectAnimator.cancel();
                holder.message.setTag(null);
            }

        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) holder.chatViewBubble.getLayoutParams();
        LinearLayout.LayoutParams deliveryStatusParams = (LinearLayout.LayoutParams) holder.deliveryStatus.getLayoutParams();
        LinearLayout.LayoutParams gifChatViewLayoutParams = (LinearLayout.LayoutParams) holder.imageViewWrapper.getLayoutParams();

        checkForGif(chatModel, holder);

        if (mCurrentUserId.equals(chatModel.getUserId())) {
            layoutParams.gravity = Gravity.RIGHT;
            layoutParams.rightMargin = Dp.toDps(mContext, 16);
            deliveryStatusParams.gravity = Gravity.RIGHT;
            gifChatViewLayoutParams.gravity = Gravity.RIGHT;

            holder.chatViewBubble.setLayoutParams(layoutParams);
            holder.imageView.setLayoutParams(gifChatViewLayoutParams);

            holder.chatViewBubble.setBackground(ContextCompat.getDrawable(mContext, R.drawable.outgoing_message_bg));
            if (chatModel.getDeliveryStatus().equals(Constants.STATUS_DELIVERED)) {
                if (position >= chatModelList.size() - 1) {
                    holder.deliveryStatus.setVisibility(View.VISIBLE);
                } else {
                    holder.deliveryStatus.setVisibility(View.INVISIBLE);
                }
                holder.deliveryStatus.setText(mContext.getString(R.string.sentText));
            } else if (chatModel.getDeliveryStatus().equals(Constants.STATUS_NOT_DELIVERED)) {
                holder.deliveryStatus.setVisibility(View.VISIBLE);
                if (updating) {
                    holder.deliveryStatus.setText(mContext.getString(R.string.sendingNowText) + percentage + " %");
                } else {
                    holder.deliveryStatus.setText(mContext.getString(R.string.sendingNowText));
                }

            }
        } else {
            holder.chatViewBubble.setBackground(ContextCompat.getDrawable(mContext, R.drawable.incoming_message_bg));
            layoutParams.gravity = Gravity.LEFT;
            gifChatViewLayoutParams.gravity = Gravity.LEFT;

            holder.chatViewBubble.setLayoutParams(layoutParams);
            holder.imageView.setLayoutParams(gifChatViewLayoutParams);
            holder.deliveryStatus.setVisibility(View.INVISIBLE);
        }

    }

这个问题是,如果您注意到Log.d()即使在 objectAnimator 上调用取消和结束后仍然会触发,是的,我已经检查了取消和结束正在被调用。所以我不知道我做错了什么。有人可以帮助我吗?


我看到很多人都在看这篇文章,这意味着他们也遇到了这个问题,所以我以某种方式解决了解决方案...问题是,即使使用静态方法,这个该死的 ObjectAnimator 在循环内完成时,每次都会创建新的引用所以你必须做这样的事情。有一个对象动画师的数组列表,在每次调用时将项目添加到数组列表中。每当你想停止它时,只需简单地循环数组并停止所有对象动画师。这是代码

private ArrayList<ObjectAnimator> objectAnimators = new ArrayList<>();
  public void startRainbowAnimation(Context context,
                                  final String textToShow,
                                  final TextView textViewToAttach) {
    stopCalled = false;
    AnimatedColorSpan span = new AnimatedColorSpan(context);
    final SpannableString spannableString = new SpannableString(textToShow);
    String substring = textToShow;
    int start = textToShow.indexOf(substring);
    int end = start + substring.length();
    spannableString.setSpan(span, start, end, 0);

    ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(
            span, animatedColorSpanFloatProperty, 0, 100);
    objectAnimator.setEvaluator(new FloatEvaluator());

    objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            System.gc();
            if (!stopCalled) {
                textViewToAttach.setText(spannableString);
            }
        }
    });
    objectAnimator.setInterpolator(new LinearInterpolator());
    objectAnimator.setDuration(DateUtils.MINUTE_IN_MILLIS * 3);
    objectAnimator.setRepeatCount(ValueAnimator.INFINITE);
    objectAnimator.start();
    objectAnimators.add(objectAnimator);
}
objectAnimators here is an array list of object animators like this

以下是如何停止所有这些以摆脱无限更新侦听器调用触发的方法。

 public void stopRainbowAnimation() {
    System.gc();
    stopCalled = true;
    if (!objectAnimators.isEmpty()) {
        for (int i = 0; i < objectAnimators.size(); i++) {
            ObjectAnimator eachAnimator = objectAnimators.get(i);
            eachAnimator.setRepeatCount(0);
            eachAnimator.end();
            eachAnimator.cancel();
            eachAnimator.removeAllListeners();
            eachAnimator.removeAllUpdateListeners();
        }
        objectAnimators.clear();
    }
}

希望这会对某人有所帮助

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对象动画师不删除更新监听器android 的相关文章

  • android 网格视图从右到左放置项目

    我正在开发一个 Android 应用程序阿拉伯文版本 在其中一个界面中 我有 gridView 因此 要以正确的顺序显示项目 我必须从右到左显示 GridView 中的项目 当然是从上到下 为此 我尝试在 GridView 中添加这些属性
  • 将 APK 移动到 /system/priv-app/ 时出现 java.lang.UnsatisfiedLinkError

    成功调试我的应用程序后 我想将应用程序移动到系统应用程序 以便我可以使用系统权限 例如 REBOOT 和 SET TIME 但是 当将我的 APK 移动到 system priv app 文件夹或将 APK 添加到 ROM 编译中的第三方系
  • OneSignal 推送通知 单击以打开活动

    我集成了一个用于推送通知的信号库 我想在应用程序未运行时通过单击推送通知来打开特定活动 我收到推送通知 但当我单击通知时 应用程序崩溃了 这是我的通知接收器代码 public class ExampleNotificationOpenedH
  • 加载内容时在 ImageView 中使用“动画圆圈”

    我目前在我的应用程序中使用一个列表视图 可能需要一秒钟才能显示 我目前所做的是使用列表视图的 id android empty 属性来创建 正在加载 文本
  • 单击按钮重复动画

    我想每次单击按钮时都重复动画 我尝试做某事像这样 https jsfiddle net 91raod7e const dist document querySelector dist document querySelector butto
  • XmlPullParser 异常 - 无法解决

    我有一个基本方法 ReadXML 从资产文件夹中读取 xml 文件 运行时不会引发任何异常 但在这个方法中 我调用了 doXML 方法 该方法尝试从 xml 文件中提取文本并将该文本设置到文本视图中 当 doXML 方法运行时 我不断收到以
  • Firebase 云消息传递 - 目标到 Firebase 控制台中不可见的单个设备

    我正在尝试向 android 中的单个设备发送通知 但是当我从 Firebase 控制台执行此操作时 它在 Firebase 新视图中不可见 谁能帮助我从哪里向单个设备发送通知 仔细尝试以下步骤 Tap 新通知 Fill up 通知标题 可
  • 为什么 Android Eclipse 不断刷新外部文件夹并花费很长时间?

    我只有一部新的 Android 手机 我一直在修补一些基本的应用程序 每当我保存任何内容时 Eclipse 的 Android 插件就会刷新外部文件夹 这让我抓狂 通常我不会介意 但当需要 10 秒才能刷新时 我开始注意到 我已经搜索过 其
  • Gradle 构建无法解析生成的类

    我刚刚将 Android Studio 从 1 5 更新到 2 2 1 Gradle 也是如此 我有一个项目 它使用注释处理器框架 由我制作 来执行类似 Dagger 的依赖注入 这在更新之前工作得很好 但现在 Gradle 无法解析生成的
  • 如何使用Multipart将图像上传到php服务器

    我一直很头疼 如何将图像上传到服务器 这对我来说是新任务 但对我来说很困惑 我在 stackoverflow 上搜索并用谷歌搜索 但我遇到了问题 我的意图是从 SD 卡上传照片并从相机拍照并上传到服务器 在ios中 这个任务已经完成 在io
  • 防止滚动时自定义 ListView 刷新。我想停止刷新

    我在我的 Android 应用程序中使用自定义 ListView 问题是当我滚动 ListView 时 它会自动清除从 EditText Edittext 作为 list item 输入的数据 并且 ListView 刷新 我想阻止它停止清
  • 在 Android 模拟器中获取互联网连接

    我有一台带有wifi连接的台式电脑 我的IP地址是192 168 12 95 网关是192 168 10 10 但是我在android模拟器中没有获得互联网连接 也就是说我无法访问internate 我也尝试过 emulator avd w
  • Facebook 好友请求 - 失踪好友

    我请求从我正在开发的 Android 应用程序中获取用户好友 从 Facebook Api V2 0 开始 我知道我应该只获取已经通过我的应用程序登录的用户好友 但是 尽管我知道用户的某些朋友已通过我的应用程序登录 但在请求该用户的朋友时
  • 从前台服务的活动中释放内存

    我有一个带有前台服务和一项活动的应用程序 该服务可以在启动时自行启动 也可以从 Activity 中启动 我注意到当服务在启动时自行启动时 内存使用量约为 3MB 一旦我打开该 Activity 内存使用量就会跃升至约 9mB 一旦 Act
  • 如何为键盘上的 xml 中的功能键设置不同的背景?

    我正在开发 Android 键盘应用程序 我尝试为普通键和功能键设置不同的背景 但它不起作用
  • 安卓浮动键盘

    是否可以通过编程方式更改键盘的位置 我正在开发一个图腾应用程序 如果键盘停靠在底部 则很难使用 我尝试创建一个扩展 InputMethodService 的自定义键盘 并且我能够更改按键的布局 但我无法更改键盘的视图位置 快捷键 https
  • Android Lollipop:将应用程序小部件添加到主屏幕时启动器崩溃

    添加小部件时 启动器在 Android Lollipop 上崩溃 并显示以下消息 在以前的 Android 版本上运行良好 编辑 这只发生在横向方向 12 16 12 35 10 208 E AndroidRuntime 960 java
  • Android 10 通知彩色操作按钮

    I m trying to color the buttons Action in Notification like this So far this is what i m achieved so far 下面是我正在使用的代码 通知服
  • 如何找出每个包含的库的最低 api 级别

    我的项目中包含了很多库 Android Studio 2 0 Preview 4 我想找出它们每个的最低 Android SDK 级别 是否可以不用谷歌搜索每个图书馆的信息 如果您有源形式的库 例如 作为项目中的库模块 请查看其清单 如果您
  • 允许使用 SurfaceTexture 在 GLSurfaceView 渲染器中进行多通道渲染

    我正在显示视频GLSurfaceView使用需要连续应用多个着色器的自定义渲染器 目前 它可以成功地使用一个着色器 但我不确定如何扩展渲染管道以连续应用多个着色器 我知道有一些关于应用多个着色器的示例 使用FrameBuffers and

随机推荐

  • Angular2 Typescript 文件的重复标识符

    在学习 Angular2 TS 快速入门之后 我的项目中的许多文件夹中都出现了重复的文件 对于浏览器 typings browser node modules angular2 typings browser 对于 es6 shim nod
  • 直接将服务注入 AngularJS 指令控制器

    我了解 Angular 依赖注入如何与指令配合使用 但希望澄清一些事情 我有一个虚拟测试指令 如下所示 app directive test function return restrict E scope controller scope
  • 如何在PHP中获取MySQL表结构?加上所有表的列表?

    我需要在 PHP 中运行什么查询才能获取数据库中给定表的结构 我需要运行什么查询才能获取所有表的列表 要获取表的列列表 请使用 DESCRIBE SQL 语句 语法如下 DESCRIBE TableName 要获取数据库上的表列表 请使用以
  • 如何使用 Delphi XE2 IDE 搜索来搜索

    我一直使用搜索来在 庞大的 应用程序源中查找内容 因此搜索有效性对我来说非常重要 目前在 Delphi XE2 IDE 中我喜欢使用 在文件中查找 包括子目录 没有其他花哨的东西 只是一个文本关键字 这工作正常 但我真正想做的是扩展我现在正
  • AFNetworking 3 x-www-form-urlencoded 发布数据

    I m trying to post data with x www form urlencoded body Posting via postman it is ok 但我无法通过 afnetworking 3 做到这一点 这是我的代码
  • 如何将 QtCreator 项目转换为 Visual Studio 项目

    我有一个 QtCreator 项目文件 pro 如何将其转换为Visual Studio 2008项目 sln 您还可以使用 qmake 命令来执行此操作 转到项目目录并输入 qmake tp vc
  • 如何使sequelize.sync()省略一些模型?

    我在数据库 mysql 中使用表和视图 因此对于开发 测试环境我想使用sync 但它在视图上崩溃 我可以以某种方式省略这些模型吗 当我想通过 Sequelize 创建和使用视图时 我使用与 Crusader 的答案非常相似的方法 在这种情况
  • 在 OAuth2.0 中使用 Facebook 访问令牌作为资源所有者凭据

    OAuth 2 0 规范定义了资源所有者密码凭证授予类型 https datatracker ietf org doc html draft ietf oauth v2 26 section 4 3 它允许直接使用资源所有者密码凭据 即用户
  • JSch get() 失败并出现 NullPointerException

    我有一个 Jax RS 服务器 它应该保存可通过 ssh 访问的文件列表 然后我可以通过 HTTP 下载或流式传输 我一直在尝试使用 JSch 的 SFTP 通道读取文件 但我不断收到NullPointerException 这是Messa
  • 如何在 C++ 中前向声明 std::set?

    为了加快编译过程 我正在尝试简化我的头文件MyClass hpp通过前向声明 STL 容器 例如 std vector std set But std set can NOT在以下代码中进行前向声明 同时std vector can be
  • 在地图函数中迭代应用 ggplot 函数

    我想为数据集中的所有变量生成一系列直方图 但显然我没有正确准备数据以便在地图函数中使用 library tidyverse mtcars gt select wt disp hp gt map function x ggplot aes x
  • 仅在特定服务器上调用delayed_job capistrano任务

    我有一个专门的服务器用于delayed job 任务 我想启动 停止和重新启动delayed job工作人员only这个服务器 我正在使用delayed job提供的capistrano食谱 当我只有 1 台服务器时 这是我的配置 befo
  • 仍然无法针对带有 Salat / Casbah 的 Play FakeApp 运行多个测试

    我以为我已经修好了问题 https stackoverflow com questions 12028218 running multiple tests within the same fakeapplication in play 2
  • 为什么 receive_boot_completed 在我的设备上不起作用?

    我正在开发一些需要使用的应用程序receive boot completed重新启动以重置一些警报 它可以在模拟器和 Samsung tab 2 10 1 上正常工作 但它不能在我的 android 版本 2 2 1 的 Galaxy Mi
  • jQuery/javascript 用户单击和以编程方式单击复选框的不同行为

    有点难以解释 所以我设置了一个 jsFiddlehere http jsfiddle net BCECy 基本上 当用户单击复选框时 我会触发一些行为 在另一个地方 我尝试以编程方式单击复选框 我需要看到完全相同的行为 它不起作用 似乎与单
  • Vim 中每行末尾的美元符号(“$”)是什么

    我对 Vim 还比较陌生 每当我启动 Vim 时使用vim LearnRuby rb 每行都会出现一个美元符号 Why set nolist 将关闭当前缓冲区的特殊字符 例如制表符显示为 I和行尾字符显示为 然而 如果它在你跑步时始终如一地
  • .hgignore 语法仅忽略文件,而不忽略目录?

    我有一个我似乎无法理解的问题 我在 Windows 上使用 TortoiseHg 版本 0 7 5 但在 Linux 上我遇到了同样的问题 这里是 My hgignore file syntax regexp 我想要实现的是将 hg 存储库
  • PHP - UPLOAD_ERR_NO_TMP_DIR

    我正在使用 Cbeyond www cbeyond com 你们中的一些人可能熟悉它们 作为启用 PHP 的虚拟主机 当我检查如下时 我的 PHP 上传功能遇到问题 error FILES uploadedfile error echo e
  • Graphql 字段在类型上不存在

    浏览完 Graphql 的文档后 我开始在一个玩具 Rails reactJS 项目上实现它 这些项目允许用户通过设备登录 然后访问显示艺术家列表的虚拟 艺术家路径 一切似乎都工作正常 直到我尝试使用 React 应用程序中的 GraphQ
  • 对象动画师不删除更新监听器android

    美好的一天 我有一个场景 这个半正常的对象动画师不断地反复触发 导致堆增长 当然在某些时候还会出现内存不足问题 这是如何进行的 我为这样的彩虹动画制作了静态方法 public static ObjectAnimator startRainb