草庐IT

android - 对象动画 - 如何让动画按顺序播放而不是一次全部播放

coder 2023-12-24 原文

我正在动画演示冒泡排序。单击按钮时,它应该:

  • 按长度顺序输出 10 个柱 - 这是使用 XML 中的 ImageViews 完成的。
  • 创建一个包含 1 到 10 之间的整数的 ArrayList,然后使用 Collections.shuffle()
  • 对其进行洗牌
  • 使用屏幕上的对象动画来打乱条形。
  • 运行冒泡排序时,通过交换界面中的两个条来显示每次交换。

当我运行该应用程序时,它不会显示每个交换,而是似乎同时播放所有内容,包括所有交换,甚至随机播放和一起交换。他们最终都排序了,但这不是视觉演示。这是下面的 java(从早期的实验中导入了许多不必要的库):` 包 com.propertyanimationtester;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LightingColorFilter;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.support.v7.app.ActionBarActivity;
import java.lang.*;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.widget.ImageView;
import java.util.Timer;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.TimeUnit;


public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}



public void startAnimation(View view) {

    ImageView[] bars = new ImageView[10];

    ImageView bar1 = (ImageView) this.findViewById((R.id.bar1));
    ImageView bar2 = (ImageView) this.findViewById((R.id.bar2));
    ImageView bar3 = (ImageView) this.findViewById((R.id.bar3));
    ImageView bar4 = (ImageView) this.findViewById((R.id.bar4));
    ImageView bar5 = (ImageView) this.findViewById((R.id.bar5));
    ImageView bar6 = (ImageView) this.findViewById((R.id.bar6));
    ImageView bar7 = (ImageView) this.findViewById((R.id.bar7));
    ImageView bar8 = (ImageView) this.findViewById((R.id.bar8));
    ImageView bar9 = (ImageView) this.findViewById((R.id.bar9));
    ImageView bar10 = (ImageView) this.findViewById((R.id.bar10));

    bars[0] = bar1;
    bars[1] = bar2;
    bars[2] = bar3;
    bars[3] = bar4;
    bars[4] = bar5;
    bars[5] = bar6;
    bars[6] = bar7;
    bars[7] = bar8;
    bars[8] = bar9;
    bars[9] = bar10;

    ArrayList<Integer> lengthslist = new ArrayList<Integer>(10);

    for (int lengthsfiller = 0; lengthsfiller < 10; lengthsfiller++) {
        lengthslist.add(lengthsfiller);
    }

    Collections.shuffle(lengthslist);

    for (int shuffleReplacement = 0; shuffleReplacement < 10; shuffleReplacement++) {
        MoveBar(view, bars[shuffleReplacement], shuffleReplacement, lengthslist.get(shuffleReplacement));
    }

    bubbleSort(lengthslist, view, bars);
}

public void bubbleSort(ArrayList<Integer> list, View view, ImageView[] bars)
{
    for(int outerloop=0; outerloop<10; outerloop++)
    {
        for(int innerloop=0; innerloop < 9; innerloop++)
        {
            if(list.get(innerloop) > list.get(innerloop+1))
            {


                SwapBars(view, bars[list.get(innerloop)], bars[list.get(innerloop+1)], innerloop, innerloop + 1);


                Collections.swap(list, innerloop, innerloop + 1);

            }
        }

    }
}

public void MoveBar(View view, View bar, int currentArrayPosition, int newArrayPosition) {
    float scale = getResources().getDisplayMetrics().density;

    ObjectAnimator animation = ObjectAnimator.ofFloat(bar,"y", (20.0f + 30.0f*(currentArrayPosition)) * scale, (20.0f+ 30.0f*(newArrayPosition)) * scale);

    AnimatorSet moveSingleBarAnimSet = new AnimatorSet();

    moveSingleBarAnimSet.play(animation);

    moveSingleBarAnimSet.setDuration(1000);
    moveSingleBarAnimSet.setInterpolator(new  AccelerateDecelerateInterpolator());
    moveSingleBarAnimSet.start();


}

public void SwapBars(View view, ImageView bar1, ImageView bar2, int position1, int position2) {
    float scale = getResources().getDisplayMetrics().density;

    ObjectAnimator anim1 = ObjectAnimator.ofFloat(bar1,"x", 20.0f * scale, 220.0f * scale);
    ObjectAnimator anim2 = ObjectAnimator.ofFloat(bar1,"y", (20.0f + 30.0f* position1) * scale, (20.0f + 30.0f * position2) * scale);
    ObjectAnimator anim3 = ObjectAnimator.ofFloat(bar1,"x", 220.0f * scale, 20.0f * scale);

    ObjectAnimator anim4 = ObjectAnimator.ofFloat(bar2,"x", 20.0f * scale, 220.0f * scale);
    ObjectAnimator anim5 = ObjectAnimator.ofFloat(bar2,"y", (20.0f + 30.0f * position2) * scale, (20.0f + 30.0f * position1) * scale);
    ObjectAnimator anim6 = ObjectAnimator.ofFloat(bar2,"x", 220.0f * scale, 20.0f * scale);

    AnimatorSet animSet = new AnimatorSet();


    animSet.play(anim1).before(anim2).before(anim5).with(anim4);
    animSet.play(anim2).before(anim3).before(anim6).with(anim5);
    animSet.play(anim3).with(anim6);


    animSet.setDuration(1000);
    animSet.setInterpolator(new AccelerateDecelerateInterpolator());
    animSet.start();
}

} `

还有 XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"        android:layout_width="match_parent"
android:layout_height="match_parent"       android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"   tools:context=".MainActivity">

<ImageView
    android:id="@+id/bar1"
    android:layout_width="50dp"
    android:layout_height="30dp"
    android:src="@drawable/bar"
    android:scaleType="centerCrop"
    android:layout_alignParentTop="true"
    android:layout_marginLeft="20dp" />

<ImageView
    android:id="@+id/bar2"
    android:layout_width="75dp"
    android:layout_height="30dp"
    android:layout_marginLeft="20dp"
    android:scaleType="centerCrop"
    android:layout_below="@id/bar1"
    android:src="@drawable/bar"
    />

<ImageView
    android:scaleType="centerCrop"
    android:id="@+id/bar3"
    android:layout_width="100dp"
    android:layout_height="30dp"
    android:layout_marginLeft="20dp"
    android:layout_below="@id/bar2"
    android:src="@drawable/bar"
    />

<ImageView
    android:scaleType="centerCrop"
    android:id="@+id/bar4"
    android:layout_width="125dp"
    android:layout_height="30dp"
    android:layout_marginLeft="20dp"
    android:layout_below="@id/bar3"
    android:src="@drawable/bar"
    />

<ImageView
    android:scaleType="centerCrop"
    android:id="@+id/bar5"
    android:layout_width="150dp"
    android:layout_height="30dp"
    android:layout_marginLeft="20dp"
    android:layout_below="@id/bar4"
    android:src="@drawable/bar"
    />

<ImageView
    android:id="@+id/bar6"
    android:layout_width="175dp"
    android:layout_height="30dp"
    android:layout_marginLeft="20dp"
    android:scaleType="centerCrop"
    android:layout_below="@id/bar5"
    android:src="@drawable/bar"
    />

<ImageView
    android:id="@+id/bar7"
    android:layout_width="200dp"
    android:layout_height="30dp"
    android:layout_marginLeft="20dp"
    android:scaleType="centerCrop"
    android:layout_below="@id/bar6"
    android:src="@drawable/bar"
    />

<ImageView
    android:id="@+id/bar8"
    android:layout_width="225dp"
    android:layout_height="30dp"
    android:layout_marginLeft="20dp"
    android:scaleType="centerCrop"
    android:layout_below="@id/bar7"
    android:src="@drawable/bar"
    />

<ImageView
    android:id="@+id/bar9"
    android:layout_width="250dp"
    android:layout_height="30dp"
    android:layout_marginLeft="20dp"
    android:scaleType="centerCrop"
    android:layout_below="@id/bar8"
    android:src="@drawable/bar"
    />

<ImageView
    android:id="@+id/bar10"
    android:layout_width="275dp"
    android:layout_height="30dp"
    android:layout_marginLeft="20dp"
    android:scaleType="centerCrop"
    android:layout_below="@id/bar9"
    android:src="@drawable/bar"
    />


<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="New Button"
    android:id="@+id/button"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:layout_marginBottom="93dp"
    android:onClick="startAnimation"
    />


</RelativeLayout>

我怎样才能停止所有动画同时播放?对于 MoveBars 过程而言,它不太重要,但绝对需要为 SwapBars 过程显示单独的交换。任何帮助将不胜感激:)

回答问题后编辑:

使用了 animSet.setStartDelay(以毫秒为单位的时间)

最佳答案

您可以通过设置 setStartDelay() 为每个动画设置不同的延迟对于您创建的每个 ObjectAnimator。

关于android - 对象动画 - 如何让动画按顺序播放而不是一次全部播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28408838/

有关android - 对象动画 - 如何让动画按顺序播放而不是一次全部播放的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  6. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  7. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  8. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  9. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  10. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

随机推荐