IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 【达内课程】音乐播放器4.0(列表播放底部增加歌曲信息展示) -> 正文阅读

[移动开发]【达内课程】音乐播放器4.0(列表播放底部增加歌曲信息展示)

上一节实现了播放的功能,下面实现播放音乐时底部显示对应歌曲信息的功能。

【效果图】
在这里插入图片描述

【开发步骤】
1、xml 界面
2、当点击 ListView 中的 item 时,把播放列表和 position 存入 application
3、每当 service 开始播放音乐时,发送自定义广播
4、在Activity 中编写广播接收器接受该广播,获取当前正在播放的歌曲信息,更新界面(注意在 onCreate 及 onDestroy中注册以及取消注册)
5、更新 UI 时,我们需要通过 path 路径,获取 Bitmap

BitmapUtils.loadBitmap(String path,Callback){
	异步发送http请求
	调用 callback 回调方法 执行后续业务
}

按照开发步骤写代码:

主要布局中 activity_test.xml 中增加

<androidx.viewpager.widget.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#ffffff" />
<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:background="#2894FF"
        android:gravity="center_vertical"
        android:paddingLeft="10dp"
        android:paddingRight="10dp">

        <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/img_music_thumb"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_marginRight="10dp"
            android:src="@mipmap/ic_launcher" />

        <TextView
            android:id="@+id/tv_music_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="歌名"
            android:textColor="@android:color/white" />

    </LinearLayout>

这里的圆形头像用的是 CircleImageView

需要在 build.gradle 中引入依赖

implementation 'de.hdodenhof:circleimageview:3.1.0'

在点击播放歌曲后,底部显示对应歌曲信息,需要知道当前播放的歌曲是哪一首,我们可以存歌曲列表和点击的 position 来确定歌曲,可以用Application 实现

创建 MusicApplication

public class MusicApplication extends Application {
    private List<MusicItem> musicList;
    private int position;
    public static MusicApplication app;

    @Override
    public void onCreate() {
        super.onCreate();
        app = this;
    }

    public static MusicApplication getApp() {
        return app;
    }

    public List<MusicItem> getMusicList() {
        return musicList;
    }

    public void setMusicList(List<MusicItem> musicList) {
        this.musicList = musicList;
    }

    public int getPosition() {
        return position;
    }

    public void setPosition(int position) {
        this.position = position;
    }

    /**
     * 获取当前正在播放的音乐
     *
     * @return
     */
    public MusicItem getCurrentMusic() {
        return musicList.get(position);
    }
}

AndroidManifest 中注册

<application
       android:name=".application.MusicApplication"
        ......
        android:theme="@android:style/Theme.Light.NoTitleBar">
        <service android:name=".service.PlayMusicService"/>
        ......
    </application>

NewMusicListFragment 中,在点击 listview 时,在 application 中存入音乐播放列表和 position

private void setListeners() {
        listView.setOnItemClickListener((adapterView, view, i, l) -> {
            final MusicItem music = musics.get(i);
            String songId = music.id;
            Toast.makeText(getActivity(), "position:" + i, Toast.LENGTH_SHORT).show();
            //执行业务层 加载这首歌曲的基本信息
            model.loadMusicInfoBySongId(songId, new MusicInfoCallback() {
                @Override
                public void onMusicInfoLoaded(MusicItem musicItem) {
                    music.url = musicItem.url;
                    Log.d("TTT", music.url);
                    //把当前播放列表和position都存入application
                    MusicApplication app = MusicApplication.getApp();
                    app.setMusicList(musics);
                    app.setPosition(i);
                    //准备通过url地址执行播放业务
                    //播放音乐
                    binder.playMusic(music.url);
                }
            });
        });
    }

当音乐播放开始时,service 通知 activity 播放开始,因此我们需要发送广播,PlayMusicService 中修改:

 /**
     * 当service实例创建时执行
     */
    @Override
    public void onCreate() {
        super.onCreate();
        //给mediaPlayer加监听
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            //音乐已经准备好
            @Override
            public void onPrepared(MediaPlayer mediaPlayer) {
                mediaPlayer.start();
                //发送广播,通知activity音乐已经开始播放
                Intent intent = new Intent (Globalconsts.ACTION_MUSIC_STARTED);
                sendBroadcast(intent);
            }
        });
    }

创建常量类 GlobalConsts

/**
 * 常量类
 */
public class Globalconsts {
    //音乐开始播放 广播action
    public static final String ACTION_MUSIC_STARTED = "ACTION_MUSIC_STARTED";
}

BitmapUtils 中增加根据图片路径加载 bitmap 的方法

public static void loadBitmap(final String path, final BitmapCallback bitmapCallback){
        AsyncTask<String,String,Bitmap> task = new AsyncTask<String, String, Bitmap>() {
            @Override
            protected Bitmap doInBackground(String... strings) {
                try {
                    //先从内存缓存中读
                    //再从文件中读
                    String filename = path.substring(path.lastIndexOf("/")+1);
                    File file = new File(MusicApplication.getApp().getCacheDir(),"images/"+filename);
                    Bitmap b = bitmap(file);
                    if(b!=null){
                        return b;
                    }
                    InputStream is = HttpUtils.getInputStream(path);
                    b = BitmapFactory.decodeStream(is);
                    //下载下来的图片,存入缓存中
                    save(b,file);
                    return b;
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }

            //主线程中执行回调方法
            @Override
            protected void onPostExecute(Bitmap bitmap) {
                bitmapCallback.onBitmapLoaded(bitmap);
            }
        };
        task.execute();
    }

增加接口 BitmapCallback

public interface BitmapCallback {
    /**
     * 当图片下载成功之后的回调方法
     * @param bitmap
     */
    void onBitmapLoaded(Bitmap bitmap);
}

Activity 中注册接收器

    MusicInfoBroadCastReceiver receiver;
    private ImageView imgMusicThumb;
    private TextView tvMusicTitle;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
		......
        //绑定Service
        bindMusicService();
        //注册广播接收器
        registMusicReceiver();
    }
    
  private void setViews() {
       	......
        viewPager = findViewById(R.id.viewpager);
        imgMusicThumb = findViewById(R.id.img_music_thumb);
        tvMusicTitle = findViewById(R.id.tv_music_title);
    }

    /**
     * 注册广播接收器
     */
    private void registMusicReceiver() {
        receiver = new MusicInfoBroadCastReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Globalconsts.ACTION_MUSIC_STARTED);
        this.registerReceiver(receiver,intentFilter);
    }

   class MusicInfoBroadCastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if(action.equals(Globalconsts.ACTION_MUSIC_STARTED)){
                //开始播放音乐,获取当前音乐对象
                MusicApplication app = MusicApplication.getApp();
                MusicItem music = app.getCurrentMusic();
                String pic = music.albumPic;
                final String title = music.name;
                BitmapUtils.loadBitmap(pic, new BitmapCallback() {
                    @Override
                    public void onBitmapLoaded(Bitmap bitmap) {
                        if(bitmap != null){
                            imgMusicThumb.setImageBitmap(bitmap);
                        }
                    }
                });
                tvMusicTitle.setText(title);
            }
        }
    }

    @Override
    protected void onDestroy() {
        this.unbindService(conn);
        this.unregisterReceiver(receiver);
        super.onDestroy();
    }

现在让图片转起来,MusicInfoBroadCastReceiver 中在设置完图片后,设置动画:

BitmapUtils.loadBitmap(pic, new BitmapCallback() {
                    @Override
                    public void onBitmapLoaded(Bitmap bitmap) {
                        if(bitmap != null){
                           imgMusicThumb.setImageBitmap(bitmap);
                           //执行旋转动画
                            RotateAnimation animation = new RotateAnimation(0,360,imgMusicThumb.getWidth()/2,imgMusicThumb.getWidth()/2);
                            animation.setDuration(10000);
                            animation.setRepeatCount(Animation.INFINITE);
                            animation.setInterpolator(new LinearInterpolator());//匀速旋转
                            imgMusicThumb.startAnimation(animation);
                        }
                        tvMusicTitle.setText(title);
                    }
                });
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-29 23:11:58  更:2022-01-29 23:14:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:56:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码