热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android实现旋转木马的音乐效果

大家一定在百度音乐上在线听过歌,有没有注意到那个旋转的唱片,本篇文章主要介绍在Android上如何实现这样的功能,有需要的小伙伴可以参考下

一、百度在线音乐旋转木马效果

就上面那个,当音乐在播放的时候,那个光碟轮子在转,就想旋转木马一般。感觉好好玩啊。
碰巧想起前阵子做音乐播放器,哎,那这个也可以做在手机的音乐播放器上,这样就代替了进度条了。
一想到,就兴奋,于是,首先画圆形,然后放置背景图片,然后使用动画旋转。当音乐播放时,同时
开始播放圆形图片的动画,当音乐暂停时,暂停旋转;当音乐停止播放时,就停止动画,图片回到原点。

二、效果

三、实现代码

(1)MainActivity  

public class MainActivity extends Activity {
  MediaPlayer m1;
  ImageView infoOperatingIV;
 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    infoOperatingIV = (ImageView) findViewById(R.id.infoOperating);
 
    Button play = (Button) findViewById(R.id.play);
    Button stop = (Button) findViewById(R.id.stop);
 
    play.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        playMusic();
      }
    });
 
    stop.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        stopMusic();
      }
    });
 
  }
 
  private void playMusic() {
    m1 = MediaPlayer.create(this, R.raw.quiet);
    m1.start();
 
    Animation operatingAnim = AnimationUtils.loadAnimation(this, R.anim.tip);
    LinearInterpolator lin = new LinearInterpolator();
    operatingAnim.setInterpolator(lin);
    if (operatingAnim != null) {
      infoOperatingIV.startAnimation(operatingAnim);
    }
 
    m1.setOnCompletionListener(new OnCompletionListener() {
      @Override
      public void onCompletion(MediaPlayer mp) {
        mp.stop();
        infoOperatingIV.clearAnimation();
      }
    });
  }
 
  private void stopMusic() {
    m1.stop();
    infoOperatingIV.clearAnimation();
  }
 
}

(2)画圆的控件,这部分代码参考了网友的。

  public class RoundImageView extends ImageView {
  private int mBorderThickness = 0;
  private Context mContext;
  private int defaultColor = 0xFFFFFFFF;
  // 如果只有其中一个有值,则只画一个圆形边框
  private int mBorderOutsideColor = 0;
  private int mBorderInsideColor = 0;
  // 控件默认长、宽
  private int defaultWidth = 0;
  private int defaultHeight = 0;
 
  public RoundImageView(Context context) {
    super(context);
    mCOntext= context;
  }
 
  public RoundImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    mCOntext= context;
    setCustomAttributes(attrs);
  }
 
  public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mCOntext= context;
    setCustomAttributes(attrs);
  }
 
  private void setCustomAttributes(AttributeSet attrs) {
    TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.roundedimageview);
    mBorderThickness = a.getDimensionPixelSize(R.styleable.roundedimageview_border_thickness, 0);
    mBorderOutsideColor = a.getColor(R.styleable.roundedimageview_border_outside_color, defaultColor);
    mBorderInsideColor = a.getColor(R.styleable.roundedimageview_border_inside_color, defaultColor);
  }
 
  @Override
  protected void onDraw(Canvas canvas) {
    Drawable drawable = getDrawable();
    if (drawable == null) {
      return;
    }
 
    if (getWidth() == 0 || getHeight() == 0) {
      return;
    }
    this.measure(0, 0);
    if (drawable.getClass() == NinePatchDrawable.class)
      return;
    Bitmap b = ((BitmapDrawable) drawable).getBitmap();
    Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
    if (defaultWidth == 0) {
      defaultWidth = getWidth();
 
    }
    if (defaultHeight == 0) {
      defaultHeight = getHeight();
    }
    // 保证重新读取图片后不会因为图片大小而改变控件宽、高的大小(针对宽、高为wrap_content布局的imageview,但会导致margin无效)
    // if (defaultWidth != 0 && defaultHeight != 0) {
    // LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
    // defaultWidth, defaultHeight);
    // setLayoutParams(params);
    // }
    int radius = 0;
    if (mBorderInsideColor != defaultColor && mBorderOutsideColor != defaultColor) {// 定义画两个边框,分别为外圆边框和内圆边框
      radius = (defaultWidth  bmpWidth) {// 高大于宽
      squareWidth = squareHeight = bmpWidth;
      x = 0;
      y = (bmpHeight - bmpWidth) / 2;
      // 截取正方形图片
      squareBitmap = Bitmap.createBitmap(bmp, x, y, squareWidth, squareHeight);
    } else if (bmpHeight 

以上就是Android 实现旋转木马的音乐效果,有需要的朋友可以参考下。


推荐阅读
  • 华为捐赠欧拉操作系统,承诺不推商用版
    华为近日宣布将欧拉开源操作系统捐赠给开放原子开源基金会,并承诺不会推出欧拉的商用发行版。此举旨在推动欧拉和鸿蒙操作系统的全场景融合与生态发展。 ... [详细]
  • 本文介绍了Go语言中正则表达式的基本使用方法,并提供了一些实用的示例代码。 ... [详细]
  • 本文详细介绍了 com.apollographql.apollo.api.internal.Optional 类中的 orNull() 方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。 ... [详细]
  • malloc 是 C 语言中的一个标准库函数,全称为 memory allocation,即动态内存分配。它用于在程序运行时申请一块指定大小的连续内存区域,并返回该区域的起始地址。当无法预先确定内存的具体位置时,可以通过 malloc 动态分配内存。 ... [详细]
  • 本文介绍了多种开源数据库及其核心数据结构和算法,包括MySQL的B+树、MVCC和WAL,MongoDB的tokuDB和cola,boltDB的追加仅树和mmap,levelDB的LSM树,以及内存缓存中的一致性哈希。 ... [详细]
  • Python多线程详解与示例
    本文介绍了Python中的多线程编程,包括僵尸进程和孤儿进程的概念,并提供了具体的代码示例。同时,详细解释了0号进程和1号进程在系统中的作用。 ... [详细]
  • 本文将介绍如何在混合开发(Hybrid)应用中实现Native与HTML5的交互,包括基本概念、学习目标以及具体的实现步骤。 ... [详细]
  • 本文详细介绍了Linux系统中用于管理IPC(Inter-Process Communication)资源的两个重要命令:ipcs和ipcrm。通过这些命令,用户可以查看和删除系统中的消息队列、共享内存和信号量。 ... [详细]
  • 一个建表一个执行crud操作建表代码importandroid.content.Context;importandroid.database.sqlite.SQLiteDat ... [详细]
  • A*算法在AI路径规划中的应用
    路径规划算法用于在地图上找到从起点到终点的最佳路径,特别是在存在障碍物的情况下。A*算法是一种高效且广泛使用的路径规划算法,适用于静态和动态环境。 ... [详细]
  • NX二次开发:UFUN点收集器UF_UI_select_point_collection详解
    本文介绍了如何在NX中使用UFUN库进行点收集器的二次开发,包括必要的头文件包含、初始化和选择点集合的具体实现。 ... [详细]
  • 解决SQL Server数据库sa登录名无法连接的问题
    在安装SQL Server数据库后,使用Windows身份验证成功,但使用SQL Server身份验证时遇到问题。本文将介绍如何通过设置sa登录名的密码、启用登录名状态以及开启TCP协议来解决这一问题。 ... [详细]
  • MySQL 数据库连接方法
    本文介绍了如何使用 MySQL 命令行工具连接到指定的数据库。 ... [详细]
  • 在 Mac 上配置 NDK
    本文详细介绍了如何在 Mac 上配置 Android NDK,包括设置环境变量和解决常见问题的方法。 ... [详细]
  • 如何解决8080端口被占用问题
    本文介绍了如何通过命令行和任务管理器查找并终止占用8080端口的进程,以确保该端口能够正常使用。 ... [详细]
author-avatar
mobiledu2502891413
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有