Android:更改 APIDemo 示例 AnimateDrawable.java 以拥有 ClickEvent-Handler

发布于 2024-09-30 21:58:33 字数 2814 浏览 2 评论 0 原文

我喜欢 Android 网页上的 API 演示示例,并使用了 AnimateDrawable.java 到 从 WaterfallView 开始,它有几个直落的图像,效果很好。现在我喜欢图像在被点击时停止。我发现 Drawable 无法处理事件,因此我将 AnimateDrawable 和 ProxyDrawable 更改为从 View 扩展,并在父 WaterfallView 上添加了 Click-Event-Listener 和 Handler。动画仍然可以很好地工作,但处理程序却不能,可能是因为在 AnimateDrawable 中,当可绘制对象进行动画处理时,整个画布会发生移动。我如何更改该示例以便可以实现事件处理程序?或者有没有办法找出我的 AnimateDrawables 在视图中的确切位置?

所以更普遍的问题是:如何向动画视图添加事件侦听器/处理程序?

以下是我对上面示例的更改:

  • AnimateView 和 ProxyView 而不是
  • 从 View 和 all 扩展的 AnimateDrawable 和 ProxyDrawable ProxyView super 调用更改为 mProxy
  • 我注释掉了 mutate()
  • 上下文仍然是在构造函数中传递下来的主要 Activity
  • 在 AnimateView 的构造函数中调用了 setClickable(true) 和 setFocusable(true)

这里是重要的源代码父/主瀑布视图:

  public class WaterfallView extends View implements OnClickListener {

  private Context mContext;
  // PictureEntry is just a value object to manage the pictures
  private Vector<PictureEntry> pictures = new Vector<PictureEntry>();

  public WaterfallView(Context context) {
  super(context);
  mContext = context;

  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_0)));
  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_1)));
  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_2)));
  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_3)));
  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_4)));
  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_5)));
  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_6)));
  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_7)));
  }

  @Override
  protected void onDraw(Canvas canvas) {
  if(!setup) {
  for(PictureEntry pic : pictures) pic.setAnimation(createAnimation(pic));
  setup = true;
  }

  canvas.drawColor(Color.BLACK);
  for(PictureEntry pic : pictures) pic.getAnimateView().draw(canvas);
  invalidate();
  }

  private Animation createAnimation(PictureEntry picture) {
  Drawable dr = picture.getDrawable();
  dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
  Animation an = new TranslateAnimation(0, 0, -1*dr.getIntrinsicHeight(), this.getHeight());
  an.setRepeatCount(-1);
  an.initialize(10, 10, 10, 10);
  AnimateView av = new AnimateView(mContext, dr, an);
  av.setOnClickListener(this);
  picture.setAnimateView(av);
  an.startNow();
  return an;
  }

  @Override
  public void onClick(View v) {
  Log.i("MyLog", "clicked "+v);
  }
  }

I love the API Demo examples from the Android webpage and used the AnimateDrawable.java to
get started with a WaterfallView with several straight falling images which works great. Now I like the images to stop when they are clicked. I found out that Drawables can't handle events so I changed AnimateDrawable and ProxyDrawable to be extended from View instead and added a Click-Event-Listener and Handler on the parent WaterfallView. The animation still works great, but the handler doesn't, probably because in AnimateDrawable the whole canvas is shifted when the drawabled are animated. How can I change that example so that I can implement an event handler? Or is there a way to find out where exactly my AnimateDrawables are in the view?

So the more general question is: How to add an Event Listener / Handler to an animated View?

Here are my changes to the example above:

  • AnimateView and ProxyView instead of AnimateDrawable and ProxyDrawable
  • ProxyView extended from View and all super calls changed to mProxy
  • I commented out mutate()
  • The context is still the main Activity which is passed down in the constructors
  • In the constructors of AnimateView setClickable(true) and setFocusable(true) are called

And here is the important source code of the parent/main WaterfallView:

  public class WaterfallView extends View implements OnClickListener {

  private Context mContext;
  // PictureEntry is just a value object to manage the pictures
  private Vector<PictureEntry> pictures = new Vector<PictureEntry>();

  public WaterfallView(Context context) {
  super(context);
  mContext = context;

  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_0)));
  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_1)));
  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_2)));
  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_3)));
  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_4)));
  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_5)));
  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_6)));
  pictures.add(new PictureEntry(context.getResources().getDrawable(R.drawable.sample_7)));
  }

  @Override
  protected void onDraw(Canvas canvas) {
  if(!setup) {
  for(PictureEntry pic : pictures) pic.setAnimation(createAnimation(pic));
  setup = true;
  }

  canvas.drawColor(Color.BLACK);
  for(PictureEntry pic : pictures) pic.getAnimateView().draw(canvas);
  invalidate();
  }

  private Animation createAnimation(PictureEntry picture) {
  Drawable dr = picture.getDrawable();
  dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
  Animation an = new TranslateAnimation(0, 0, -1*dr.getIntrinsicHeight(), this.getHeight());
  an.setRepeatCount(-1);
  an.initialize(10, 10, 10, 10);
  AnimateView av = new AnimateView(mContext, dr, an);
  av.setOnClickListener(this);
  picture.setAnimateView(av);
  an.startNow();
  return an;
  }

  @Override
  public void onClick(View v) {
  Log.i("MyLog", "clicked "+v);
  }
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

落叶缤纷 2024-10-07 21:58:33

您要点击小部件(按钮、复选框等)吗?或者您希望能够点击任何地方?我想你想要后者。所以在这种情况下你需要这个方法:


@覆盖

public boolean onTouchEvent(MotionEvent event) {

    // do stuff with your event

}

当事件由视图处理时调用此方法,因此我认为您可能必须删除一些 onClickListener 内容。请参阅此处了解更多信息信息。一如既往地进行实验。

Are you going to be clicking widgets(buttons, checkboxes, etc)? Or do you want to be able to click anywhere? I think you want the latter. So in that case you'll need this method:


@Override

public boolean onTouchEvent(MotionEvent event) {

    // do stuff with your event

}

This method is ONLY called when the event is NOT handled by a view, so I think you may have to remove some of your onClickListener stuff. Refer to here for more info. And as always, experiment.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文