返回顶部
首页 > 资讯 > 精选 >如何在Android中自定义一个音乐波动特效图
  • 957
分享到

如何在Android中自定义一个音乐波动特效图

2023-06-14 19:06:15 957人浏览 薄情痞子
摘要

今天就跟大家聊聊有关如何在Android中自定义一个音乐波动特效图,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Android是什么Android是一种基于linux内核的自由及开放

今天就跟大家聊聊有关如何在Android中自定义一个音乐波动特效图,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

Android是什么

Android是一种基于linux内核的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由美国Google公司和开放手机联盟领导及开发

自定义属性:

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="musicPlayViewAttr">        <!--指针颜色-->        <attr name="point_color" fORMat="color" />        <!--指针数量-->        <attr name="point_num" format="integer" />        <!--指针宽度-->        <attr name="point_width" format="float" />        <!--指针波动速度-->        <attr name="point_speed" format="integer" />    </declare-styleable></resources>

编写自定义MusicPlayview

 public class MusicPlayView extends View {    //坐标原点x    private float mBasePointX;     //坐标原点y    private float mBasePointY;     //指针的数量 默认10    private int mPointNum;     //指针间的间隙  默认5dp    private float mPointSpace;     //每个指针的宽度 默认5dp    private float mPointWidth;     //指针的颜色    private int mPointColor = Color.RED;     //指针的集合    private List<Pointer> mPoints;     //控制开始/停止    private boolean mIsPlaying = false;     //播放线程    private Thread mPlayThread;     //指针波动速度    private int mPointSpeed;     //画笔    private Paint mPaint;     public MusicPlayView(Context context) {        super(context);        init();    }     public MusicPlayView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        //取出自定义属性        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.musicPlayViewAttr);        mPointNum = ta.getInt(R.styleable.musicPlayViewAttr_point_num, 10);        mPointWidth = dp2px(getContext(),                ta.getFloat(R.styleable.musicPlayViewAttr_point_width, 5f));        mPointColor = ta.getColor(R.styleable.musicPlayViewAttr_point_color, Color.RED);        mPointSpeed = ta.getInt(R.styleable.musicPlayViewAttr_point_speed, 40);        init();    }     public MusicPlayView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.musicPlayViewAttr);        mPointNum = ta.getInt(R.styleable.musicPlayViewAttr_point_num, 10);        mPointWidth = dp2px(getContext(), ta.getFloat(R.styleable.musicPlayViewAttr_point_width, 5f));        mPointColor = ta.getColor(R.styleable.musicPlayViewAttr_point_color, Color.RED);        mPointSpeed = ta.getInt(R.styleable.musicPlayViewAttr_point_speed, 40);        init();    }         private void init() {        mPoints = new ArrayList<>();        //绘制虚线        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mPaint.setColor(mPointColor);        mPaint.setAntiAlias(true);        mPaint.setStrokeWidth(mPointWidth);        mPaint.setPathEffect(new DashPathEffect(new float[]{25, 15}, 0));//虚线间隔        setLayerType(LAYER_TYPE_SOFTWARE, null);    }         @Override    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        super.onLayout(changed, left, top, right, bottom);        //获取逻辑原点的Y        mBasePointY = getHeight() - getPaddingBottom();        Random random = new Random();        if (mPoints != null)            mPoints.clear();        for (int i = 0; i < mPointNum; i++) {            //随机高度            mPoints.add(new Pointer((float) (0.1 * (random.nextInt(10) + 1) * (getHeight() - getPaddingBottom() - getPaddingTop()))));        }        //计算每个指针之间的间隔  view宽度 - 左右的padding - 所有指针总共宽度   再除以多少个间隔        mPointSpace = (getWidth() - getPaddingLeft() - getPaddingRight() - mPointWidth * mPointNum) / (mPointNum - 1);     }          @Override    protected void onDraw(canvas canvas) {        super.onDraw(canvas);        //指针x位置        mBasePointX = 0f + getPaddingLeft() + mPointWidth / 2;        //绘制每一个指针。        for (int i = 0; i < mPoints.size(); i++) {            //绘制虚线            float[] pts = {mBasePointX, getHeight(), mBasePointX, (mBasePointY - mPoints.get(i).getHeight())};//重下往上动画            canvas.drawLines(pts, mPaint);            //更新指针x位置            mBasePointX += (mPointSpace + mPointWidth);        }    }         public void start() {        setVisibility(VISIBLE);        if (!mIsPlaying) {            if (mPlayThread == null) {                mPlayThread = new Thread(new PlayRunnable());                mPlayThread.start();            }            mIsPlaying = true;//控制子线程中的循环        }    }         public void stop() {        setVisibility(INVISIBLE);        mIsPlaying = false;        invalidate();    }         private Handler myHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            invalidate();        }    };         public class PlayRunnable implements Runnable {         @Override        public void run() {            for (float i = 0; i < Integer.MAX_VALUE; ) {                try {                    for (int j = 0; j < mPoints.size(); j++) {                        float rate = (float) Math.abs(Math.sin(i + j));//随机数                        mPoints.get(j).setHeight((mBasePointY - getPaddingTop()) * rate); //每个指针的高度                    }                    Thread.sleep(mPointSpeed);//控制动画速度                    //开始/暂停                    if (mIsPlaying) {                        myHandler.sendEmptyMessage(0);                        i += 0.1;                    }                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }         public class Pointer {        private float height;         public Pointer(float height) {            this.height = height;        }         public float getHeight() {            return height;        }         public void setHeight(float height) {            this.height = height;        }    }         public static int dp2px(Context context, float dpVal) {        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, context.getResources()                .getDisplayMetrics());    }}

在activity_main2布局中使用MusicPlayView

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="Http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context=".MainActivity">     <com.hk.testapplication.MusicPlayView        android:id="@+id/music_play"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1"        android:visibility="invisible"        android:padding="10dp"        app:point_color="#F44336"        app:point_num="10"        app:point_width="14" />    <LinearLayout        android:orientation="horizontal"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1">        <Button            android:id="@+id/bt_play"            android:layout_marginLeft="20dp"            android:layout_marginRight="20dp"            android:layout_width="0dp"            android:layout_weight="1"            android:layout_height="wrap_content"            android:text="播放"/>        <Button            android:id="@+id/bt_stop"            android:layout_width="0dp"            android:layout_weight="1"            android:layout_height="wrap_content"            android:layout_marginLeft="20dp"            android:layout_marginRight="20dp"            android:text="停止"/>     </LinearLayout> </LinearLayout>

MainActivity中使用

public class MainActivity2 extends AppCompatActivity implements View.OnClickListener {    private Button mBtPlay,mBtStop;    private MusicPlayView mMusicPlayView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);        mMusicPlayView = findViewById(R.id.music_play);        mBtPlay = findViewById(R.id.bt_play);        mBtStop = findViewById(R.id.bt_stop);        mBtPlay.setOnClickListener(this);        mBtStop.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()){            case R.id.bt_play:                //开始播放                mMusicPlayView.start();                break;            case R.id.bt_stop:                //停止播放                mMusicPlayView.stop();                break;         }    }}

看完上述内容,你们对如何在Android中自定义一个音乐波动特效图有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注编程网精选频道,感谢大家的支持。

--结束END--

本文标题: 如何在Android中自定义一个音乐波动特效图

本文链接: https://lsjlt.com/news/274406.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何在Android中自定义一个音乐波动特效图
    今天就跟大家聊聊有关如何在Android中自定义一个音乐波动特效图,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Android是什么Android是一种基于Linux内核的自由及开放...
    99+
    2023-06-14
  • Android简单自定义音乐波动特效图
    本文实例为大家分享了Android简单自定义音乐波动特效图的具体代码,供大家参考,具体内容如下 最终效果: 思路:就是绘制一个不断变化高度的矩形或者是宽虚线 1.自定义属性: ...
    99+
    2024-04-02
  • 如何在Android中实现一个音乐播放器
    如何在Android中实现一个音乐播放器?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。实现过程导入项目所需的音乐文件、图标、背景等创建一个raw文件夹,将音乐文...
    99+
    2023-06-15
  • Android自定义一个图形单点移动缩小的效果
    先给大家展示下效果图,如果大家感觉不错,请参考实现代码效果图如下所示:代码如下所示:public class MainActivity extends Activity { View view; public static final ...
    99+
    2023-05-30
    android 自定义 图形
  • 如何在Android应用中自定义一个控件
    本篇文章为大家展示了如何在Android应用中自定义一个控件,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。开发自定义控件的步骤:了解View的工作原理 2、 编写继承自View的子类3、 为自定义V...
    99+
    2023-05-31
    android roi
  • 通过在Android中自定义StickinessView实现一个粘性滑动效果
    这篇文章给大家介绍通过在Android中自定义StickinessView实现一个粘性滑动效果,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、首先,要确定HeadLayout什么时候可以拦截事件,那么就要确定List...
    99+
    2023-05-31
    android stickinessview roi
  • 如何在Android中实现一个动画效果的自定义下拉菜单功能
    如何在Android中实现一个动画效果的自定义下拉菜单功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。要实现的功能及思路如下:下拉菜单样式是自定义的、非原生效果:需要使用...
    99+
    2023-06-06
  • 怎么在Android中实现一个动态滚动波形图
    这期内容当中小编将会给大家带来有关怎么在Android中实现一个动态滚动波形图,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。(一)绘制背景网格为了让他看上去像示波器上的数据,我们先绘制一层网格背景,看上去...
    99+
    2023-06-14
  • 如何在Android中自定义一个圆环式进度条
    如何在Android中自定义一个圆环式进度条?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Android是什么Android是一种基于Linux内核的自由及开放源代码的操作系统...
    99+
    2023-06-14
  • 如何在Android项目中创建一个自定义控件
    本篇文章为大家展示了如何在Android项目中创建一个自定义控件,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。仿iPhone 的风格,在界面的顶部放置一个标题栏。<&#63;xml v...
    99+
    2023-05-31
    android roi 目中
  • 如何在Android应用中添加一个自定义弹框
    如何在Android应用中添加一个自定义弹框?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。实现步骤:1.xml布局实现<&#63;xml vers...
    99+
    2023-05-31
    android roi
  • 怎么在Android中自定义一个控件
    怎么在Android中自定义一个控件?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。代码class SleepDayChart(context: Contex...
    99+
    2023-06-14
  • 怎么在Android中自定义一个圆形进度条效果
    怎么在Android中自定义一个圆形进度条效果?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Android是什么Android是一种基于Linux内核的自由及开放源代码的操作系...
    99+
    2023-06-14
  • 怎么在C#中创建一个自定义特性
    这期内容当中小编将会给大家带来有关怎么在C#中创建一个自定义特性,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。实现方式声明自定义特性,一个新的自定义特性应派生自 System.Attribute 类。//...
    99+
    2023-06-14
  • Android中怎么自定义一个环形LoadingView效果
    这期内容当中小编将会给大家带来有关Android中怎么自定义一个环形LoadingView效果,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。控件实现:这个控件继承Rela...
    99+
    2024-04-02
  • 如何在Android中自定义ProgressBar
    如何在Android中自定义ProgressBar?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。具体如下:<xml version="...
    99+
    2023-05-30
    android progressbar
  • 如何在Android中自定义Dialog
    本篇文章为大家展示了如何在Android中自定义Dialog,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。功能:android 提供给我们的只有2种Dialog 即 AlertDialog &...
    99+
    2023-05-31
    android roi dialog
  • 如何在Android中使用PopupWindow制作一个自定义弹窗
    本篇文章给大家分享的是有关如何在Android中使用PopupWindow制作一个自定义弹窗,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。代码:PopupWindow ...
    99+
    2023-05-31
    android popupwindow
  • 怎么在android中自定义一个PagerAdapter方法
    这篇文章给大家介绍怎么在android中自定义一个PagerAdapter方法,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。首先,如果继承pageradapter,至少必须重写下面的四个方法  &n...
    99+
    2023-05-30
    android pageradapter
  • 怎么在Android中自定义一个ProgressBar控件
    这篇文章将为大家详细讲解有关怎么在Android中自定义一个ProgressBar控件,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。首先加载Drawable,在onMeasure设置好其区域...
    99+
    2023-05-30
    android progressbar
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作