欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

如何使用AndriodStudio制作音乐播放器音乐列表界面和导入手机音乐资源

程序员文章站 2022-04-19 19:37:25
...

思路:

创建一个空的Activity页面、两个Fragment、两个Adapter适配器、一个实体类、一个行布局文件;

在实体类中定义必要的属性;

配置两个Adapter适配器,其中MusicAdapter要用到缓存原理,配置行控件。

在LocalFragment里获取手机音乐文件资源(歌曲名、歌手名、专辑名、专辑图片),绑定适配器;

在MIanActivity.java里绑定碎片、设置点击事件、绑定适配器。

难点:

动态获取手机权限
获取图片资源

效果图:

如何使用AndriodStudio制作音乐播放器音乐列表界面和导入手机音乐资源

如何使用AndriodStudio制作音乐播放器音乐列表界面和导入手机音乐资源

1.准备工作

实现音乐播放器里的音乐列表必须要使用Activity活动页面和Fragment页面相结合。
在这里我将MainActivity作为主页面,然后新建两个Fragment(LocalMusic和OnlineMusic)分别作为“我的音乐”和“在线音乐”的活动界面。
还需要新建MusicAdapter适配器和MusicPagerAdapater适配器。MusicAdapter配置音乐的ListView和LocalFragment,MusicPagerAdapater是用来配置Fragment和Activity的。再创建一个实体类Music用来接音乐数据,最后新建一个item_list.XML文件,作为ListView的行布局文件
准备工作做好如下图:(MusicActivity是后续需要的工作,可以暂时不用管)

如何使用AndriodStudio制作音乐播放器音乐列表界面和导入手机音乐资源

2.在实体类Music中定义自己需要的属性:

public class Music {

    public String title;//歌曲名称
    public String artist;//歌手名称
    public String album;//专辑名称
    public int length;//歌曲时间长度
    public Bitmap albumbtm;//专辑图片

}

3.设置item_list.XML行布局:

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="60dp">

        <ImageView
            android:id="@+id/song_album"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_centerVertical="true"
            android:layout_margin="10dp"
            android:src="@mipmap/ts1" />

        <TextView
            android:id="@+id/song_name_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/song_album"
            android:text="you belong with me"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/singer_name_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/song_album"
            android:layout_toEndOf="@+id/song_album"
            android:layout_toRightOf="@+id/song_album"
            android:text="Taylar Swift"
            android:textSize="15sp" />

        <View
            android:layout_width="300dp"
            android:layout_height="1dp"
           android:layout_alignParentBottom="true"
            android:layout_alignLeft="@+id/singer_name_tv"

            />
    </RelativeLayout>

4.写MusicAdapter.java的代码,设置适配器:

创建两个全局变量,context和musicList,并且创建有参构造方法public MusicAdapter,给参数传值。用上缓存原理来创建行布局试图,创建行布局控件以及给行布局控件赋值。首先要创建一个ViewHoder类,定义行布局文件的属性。

//自己定义的适配器要继承BaseAdapter
public class MusicAdapter extends BaseAdapter {

    public Context context;//
    public List<Music> musicList;

    public MusicAdapter(Context context, List<Music> musicList) {
        this.context = context;
        this.musicList = musicList;
    }//创建有参构造方法,给参数传值。

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

    @Override
    public Object getItem(int i) {
        return null;
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        View view1 = null;
        ViewHolder viewHolder = null;
        if (view == null) {
            view1 = LayoutInflater.from(context).inflate(R.layout.item_list, null);  
            //创建布局视图
            viewHolder = new ViewHolder();
            viewHolder.titletv = view1.findViewById(R.id.song_name_tv);
            viewHolder.artisttv = view1.findViewById(R.id.singer_name_tv);
            //创建布局控件

            view1.setTag(viewHolder);

        }else {
            view1=view;
            viewHolder= (ViewHolder) view.getTag();
        }
        Music music=musicList.get(i);
        viewHolder.titletv.setText(music.title);
        viewHolder.artisttv.setText(music.artist+" - "+music.album);
        //给行布局控件赋值

        if(music.albumbtm!=null){
            viewHolder.albumimg.setImageBitmap(music.albumbtm);
        }else{
            viewHolder.albumimg.setImageResource(R.mipmap.ts2);
//用if语句判断专辑图片是否不为null,如果不为null就引用它专辑图片,如果为null就给它一个默认的图片
        return view1;
    }

    class ViewHolder {
        TextView titletv;
        TextView artisttv;
        ImageView albumimg;

    }
}

5.配置LocalFragment:

首先,在其XML布局文件里面写好ListView视图,在java代码里除了定义ListView和数组List,还需要定义第三方插件所需要的全局变量。

  private ListView listView;
    private List<Music> musicList = new ArrayList<>();
    private PermissionHelper permissionHelper;//第三方插件所需要的变量
    private String TAG = "HelloActivity";

引入第三方插件compile:在模块对应的build.gradle里的dependencies{}里加上:
compile ‘com.master.android:permissionhelper:1.3’
然后将其下载下来。
在AndroidManifest.xml文件里写上:

   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

在LocalFragment.java文件中要实现动态获取读取手机音乐资源的权限,在前面已经将第三方插件下载好了,在这里直接引用就可以了:

permissionHelper = new PermissionHelper(this, new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
permissionHelper.request(new PermissionHelper.PermissionCallback() {
            @Override
            public void onPermissionGranted() {
                Log.d(TAG, "onPermissionGranted() called");
                initListView();// initListView()是自己定义的内部类,用来读取手机资源
            }            //用户允许获取权限后才执行此方法
            @Override
            public void onIndividualPermissionGranted(String[] grantedPermission) {
                Log.d(TAG, "onIndividualPermissionGranted() called with: 
                grantedPermission = [" + TextUtils.join(",",grantedPermission) + "]");
            }//要获取多条权限,用户允许获取其中的权限后才执行此方法
            @Override
            public void onPermissionDenied() {
                Log.d(TAG, "onPermissionDenied() called");
            }//用户拒绝获取权限后才执行此方法
            @Override
            public void onPermissionDeniedBySystem() {
                Log.d(TAG, "onPermissionDeniedBySystem() called");
            }//用户勾选不在询问此问题,不允许获取权限后才执行此方法
        });

在initListView()这个方法中,先获取游标,再用do\while方法获取自己想要的资源,在获取图片资源时注意要将类型换为int型。

  private void initListView() {
        ContentResolver resolver = getActivity().getContentResolver();
        //获取游标
        Cursor cursor = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
        cursor.moveToFirst();//将游标放至第一位
        do {
            Music M = new Music();

            M.title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
            //读取歌名
            M.artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
            //读取歌手名
            M.album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
            //读取专辑名
           int albumID=cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
            M.albumbtm=getAlbumArt(albumID);
            //读取专辑图片
            musicList.add(M);

        } while (cursor.moveToNext());
//当游标移到最后的时候,结束循环
        cursor.close();
        MusicAdapter musicAdapter = new MusicAdapter(getActivity(), musicList);
        listView.setAdapter(musicAdapter);
    }
/**
     * 根据专辑ID获取专辑封面图
     * @param album_id 专辑ID
     * @return
     */
    private Bitmap getAlbumArt(int albumID) {
        String mUriAlbums = "content://media/external/audio/albums";
        String[] projection = new String[]{"album_art"};
        Cursor cur = getActivity().getContentResolver().query(Uri.parse(mUriAlbums + "/" + Integer.toString(albumID)), projection, null, null, null);
        String album_art = null;
        if (cur.getCount() > 0 && cur.getColumnCount() > 0) {
            cur.moveToNext();
            album_art = cur.getString(0);
        }
        cur.close();
        Bitmap bm = null;
        if (album_art != null) {
//            Log.e("LOCAL",album_art);
            bm = BitmapFactory.decodeFile(album_art);
        }
        return bm;
    }

6.配置MainActivity代码:

在Mian活动里要实现两个Fragment的滑动切换和点击切换。
在MianActivity.java文件中绑定两个Fragment,给两个TextView设置监听事件。
在MianActivity.xml文件里除了设置两个TextView控件,还要写ViewPager控件:

   <android.support.v4.view.ViewPager
        android:id="@+id/mian_vp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
    </android.support.v4.view.ViewPager>

MianActivity.java代码如下:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private TextView localtv;
    private TextView onlinetv;
    private ViewPager viewPager;
    private List<Fragment> fragmentList=new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindID();

        localtv.setOnClickListener(this);
        onlinetv.setOnClickListener(this);

        LocalFragment localFragment=new LocalFragment();
        OnlineFragment onlineFragment=new OnlineFragment();
        fragmentList.add(localFragment);
        fragmentList.add(onlineFragment);
        //绑定两个Fragment

        MusicPagerAdapter pagerAdapter=new MusicPagerAdapter(getSupportFragmentManager(),fragmentList);
        viewPager.setAdapter(pagerAdapter);
        //创建适配器,启动适配器
    }
//绑定ID
    private void bindID() {
        localtv = findViewById(R.id.main_local_tv);
        onlinetv = findViewById(R.id.main_online_tv);
        viewPager = findViewById(R.id.mian_vp);
    }
//给两个控件添加点击事件
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.main_local_tv:
                viewPager.setCurrentItem(0);
                break;
            case R.id.main_online_tv:
                viewPager.setCurrentItem(1);
                break;
            default:
                break;
        }
    }
 }
相关标签: 音乐