Android Studio 开发实践——简易版音游APP(二)

歌单页面 (MusicViewActivity)

 

 

1. Music类

package com.example.free.Classes;

public class Music {

    private String name="";//歌曲名
    private String path="";//歌曲在存储中的路径
    private long size=0;//歌曲大小
    private long time=0;//歌曲时长

    public Music(String _name,String _path,long _size,long _time){
        name=_name;
        path=_path;
        size=_size;
        time=_time;
    }

    public String getName(){
        return name;
    }

    public String getPath(){
        return path;
    }
    public long getSize(){
        return size;
    }
    public long getTime(){
        return time;
    }
}

 

2. activity_music_view.xml

RecyclerView的样式,后面活动页面通过访问它的id,适配adapter来传递子项item的样式和数据。比ListView更灵活,具体区别不做赘述。

<?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"
    tools:context=".MusicViewActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/recyclerView">
    </androidx.recyclerview.widget.RecyclerView>

</LinearLayout>

 

3. music_item.xml

RecyclerView的每一个item的具体样式,在MusicAdapter向ViewHolder传该样式。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    ><!--注意这里的height是不是match_parent,不然会是一个子项占了一整个页面-->

    <ImageView
        android:id="@+id/imageLeft"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_marginTop="5dp"
        android:src="@drawable/_note"
        /><!--这里是一个音符符号的图片-->

    <TextView
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:id="@+id/textView"
        android:textColor="@color/colorBlack"
        android:gravity="center_vertical"
        android:textIsSelectable="false"
        android:layout_margin="5dp"
        android:padding="5dp"
        android:textSize="18dp">
    </TextView>

</LinearLayout>

 

4. MusicAdapter

为RecyclerView分配每一个子项。

package com.example.free.Classes;

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.free.OriginChoiceActivity;
import com.example.free.R;

import java.util.List;

//以下都是沿袭了RecyclerView.Adapter的结构,具体原理不做赘述
public class MusicAdapter extends RecyclerView.Adapter<MusicAdapter.ViewHolder> {

    private List<Music> musicList;

    //传入Music音乐列表,方面后面ViewHolder更新当前页面数据
    public MusicAdapter(List<Music> _musicList) {
        musicList=_musicList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        
        //得到每一项的样式view,不继承parent
        View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.music_item,parent,false);

        //只在adapter创建的时候向ViewHolder传一次子项样式
        final ViewHolder viewHolder=new ViewHolder(view);
        final Context context=parent.getContext();//得到当前上下文活动,方便后面intent传会话
        
        //实现每个子项的点击效果(点击完把音乐信息传给下一个界面)
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position=viewHolder.getAdapterPosition();//得到当前音乐index
                Music music=musicList.get(position);//得到音乐信息
                String musicPath=music.getPath();
                long musicSize=music.getSize();
                long musicTime=music.getTime();

                Intent intent=new Intent(context, OriginChoiceActivity.class);//转入模式选择界面
                intent.putExtra("musicPath",musicPath);//会话同时传递歌曲信息,下个活动选完模式后再把信息继续传给游戏界面
                intent.putExtra("musicSize", musicSize);
                intent.putExtra("musicTime",musicTime);
                context.startActivity(intent);
            }
        });

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
        Music music=musicList.get(position);
        viewHolder.textView.setText(music.getName());
    }

    @Override
    public int getItemCount() {
        return musicList.size();
    }


    //内部类ViewHolder,就是实现了一层封装
    class ViewHolder extends RecyclerView.ViewHolder{
        //ViewHolder在adapter新建时储存控件实例/样式,这样在后面就不用一直findViewById查找子样式

        TextView textView;//子项文本内容,对应onBindViewHolder里的setText,adapter及时更新当前页面子项信息

        ViewHolder(View view){
            super(view);
            textView=view.findViewById(R.id.textView);
        }
    }

}

 

5. MusicViewActivity

具体歌单页面,适配MusicAdapter,初始化musicList,将音乐信息传给adapter。

通过调用本地数据库MediaStore.Audio.Media.EXTERNAL_CONTENT_URI来查找所有音乐文件,不用自己写代码过滤全部的目录。

package com.example.free;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.MediaStore;
import com.example.free.Classes.BaseActivity;
import com.example.free.Classes.Music;
import com.example.free.Classes.MusicAdapter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MusicViewActivity extends BaseActivity {
//该项目的所有活动(除首页)都继承自BaseActivity,方便调试及实现广播,避免一个活动点击多次出现重复页面的情况

    List<Music> musicList=new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_music_view);//通过啊id加载进来activity_music_view.xml的视图

        setTitle("选择歌曲");//当前页面bar的标题,就是页面最上方的位置

        initMusics();//调用后面初始化音乐列表的方法

        RecyclerView recyclerView=findViewById(R.id.recyclerView);//找到里面的瀑布流视图

        LinearLayoutManager layoutManager=new LinearLayoutManager(this);//线性布局管理器,可自行设置布局
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);//设置垂直分布布局
        recyclerView.setLayoutManager(layoutManager);//将布局管理器配给该瀑布流

        MusicAdapter musicAdapter=new MusicAdapter(musicList);//新建adapter,将音乐列表参数传进去
        recyclerView.setAdapter(musicAdapter);//瀑布流运用该适配器



    }

    //初始化音乐列表方法
    public void initMusics() {

        Cursor cursor = null;//初始化游标,(同访问数据库的query用法)

        try {
            //这里是利用了自带的数据库,不用从sd卡里过滤目录
            cursor = getApplicationContext().getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
                    , null, null, null, MediaStore.Audio.AudioColumns.IS_MUSIC);//查看外存是音乐的文件;

            if (cursor != null) {
                while (cursor.moveToNext()) {
//得到音乐名字
                    String name=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
//得到音乐文件路径
                    String path=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
//得到音乐文件大小
                    long size=cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));
//得到音乐时长
                    long time=cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));

                    if(name!=null)//这里一定要先判断是否为空,否则后面的.contains方法会报错
                        if(name.contains(".wav")||name.contains(".mp3"))
                            musicList.add(new Music(name,path,size,time));
//本项目只实现了wav和mp3格式音乐文件的自动识别节奏
                }
            }
            Collections.reverse(musicList);//倒置按时间顺序排序,使最新下载的音乐在最上方

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null)
                cursor.close();//这里记得finally关闭游标
        }
    }


}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值