仿写网易云音乐列表界面设计过程

初学Android,请大神勿喷,总结自己这两天学习Android Studio来仿写网易云音乐列表界面的设计与实现读取本地音乐的功能。

1、功能简介

    实现在MainActivity中实现列表和左右滑动功能
    点击实现左右滑动功能
    能在列表中读取本地音乐和音乐专辑图片
    实现从当前页面点击跳转到另一个界面

实现的列表效果图如下所示:
仿写网易云音乐列表界面设计过程_第1张图片仿写网易云音乐列表界面设计过程_第2张图片

2、实现功能过程

建立一个新的项目来编写音乐播放器,要设计一个音乐界面首先要先操作以下几个步骤:

1. 建立一个实体类entity包

2. 建立一个适配器adapter包

3. 建立一个fragment包

4. 编写一个行布局music_item来编写列表中每一个音乐所代表的行布局

在Activity的layout写入主界面的布局和ViewPage控件,如下代码所示:

.support.v4.view.ViewPager
    android:id="@+id/main_local_viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/main_title_music"
    >
.support.v4.view.ViewPager>

1、建立一个Music实体类,Music类中定义几个方法在适配器中实现

    在这里我比较喜欢使用public来修饰,因为用public不需要再写set与get方法

2、建立一个music_item行布局xml文件

在layout中新建一个xml文件,来定义在列表中的每一个音乐的布局,在这里我们用到了LinearLayout与RelativeLayout两种布局方法,每一首歌曲在列表中显示的都是音乐的专辑图片、歌名、歌手和专辑名在这里就要建立一个ImageView图片类型与两个TextView文本类型,在这些类型里给图片和文本定义好大小与布局,首先我们在LinearLayout用orientation给一个水平分布的布局,使所有布局水平放置,具体位置再经过代码进行调整,但每一个类型的文件我们要给一个id,方便在接下来的适配器中绑定id

开始布局代码如下所示:
    `
     `

3、 创建列表界面ListviewAdapter与ViewPageAdapter适配器

    两个适配器都要要继承父类BaseAdapter适配器
    要在适配器内添加两个方法以及构造方法用context连接上下文,用数组获得数据

在适配器中

private Context context;
    private List musicList;

    public MusicListAdapter(Context context,List musicList){
        this.context=context;
        this.musicList=musicList;
  }

在里面最为重要的就是运用缓存原理ViewHolder

public View getView(int i, View view, ViewGroup viewGroup) {
         //缓存原理
        View v = null;
        ViewHolder viewHolder;

        if (view==null){
        //创建布局构造器
        //创建布局视图
            v= LayoutInflater.from(context).inflate(R.layout.music_item,null);
            viewHolder=new ViewHolder();
        //创建布局控件,绑定id
            viewHolder.titleTV=v.findViewById(R.id.music_item_title);
            viewHolder.autherTV=v.findViewById(R.id.music_item_auther);
            viewHolder.ablumimagview=v.findViewById(R.id.music_item_img);

            v.setTag(viewHolder);
        }else {
            v=view;
            viewHolder= (ViewHolder) v.getTag();
        }
        //给布局控件赋值
        Music music=musicList.get(i);
        viewHolder.titleTV.setText(music.title);
        viewHolder.autherTV.setText(music.auther+" - "+music.album);
        //判断音乐的专辑图片是否不为空
        if (music.albumbtm!=null){
            viewHolder.ablumimagview.setImageBitmap(music.albumbtm);
        }else {
            viewHolder.ablumimagview.setImageResource(R.mipmap.ic_launcher);
        }

        return v;
    }
//创建ViewHolder类
    class ViewHolder{
        TextView titleTV;
        TextView autherTV;
        ImageView ablumimagview;
    }

4、在fragment包中建立两个Fragment,两个Fragment分别是点击时所需要滑动的界面,在两个Fragment的layout中都插入ListView控件

代码所示如下:

    <ListView
        android:id="@+id/local_listview"   //定义listview控件的id
        android:layout_width="match_parent"
        android:layout_height="match_parent">
     ListView>

如图所示:
仿写网易云音乐列表界面设计过程_第3张图片

public class LocalFragment extends Fragment {
private ListView localListview;  //定义我的音乐中的listview控件
private List musicList;

    public LocalFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment

        View view=inflater.inflate(R.layout.fragment_local, container, false);
        localListview=view.findViewById(R.id.local_listview);
        indiListView();//引用一个类,在里面传值,传当地音乐的音乐专辑图片、歌名、歌手和专辑名
        //跳转界面的传值,从当前界面传值到另一个界面
        localListview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView adapterView, View view, int i, long l) {
                Intent intent=new Intent(getActivity(), MusicActivity.class);

                intent.putExtra("title",musicList.get(i).title);
                intent.putExtra("auther",musicList.get(i).auther);
                intent.putExtra("album",musicList.get(i).album);
                getActivity().startActivity(intent);
            }
        });
         return view;//返回view值
         }
    private void indiListView() {
        musicList=new ArrayList<>();//数组初始化
        //用ContentResolver 获取游标
        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.auther=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
            m.album=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
            m.lengrh = Integer.parseInt(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)));
           //定义专辑图片id
            int albumId = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
            m.albumbtm = getAlbumArt(albumId);


            musicList.add(m);
        }while (cursor.moveToNext());
        cursor.close();//关闭游标

        //绑定适配器
        MusicListAdapter adapter=new MusicListAdapter(getActivity(),musicList);
        localListview.setAdapter(adapter);
    }
//根据专辑ID获取专辑封面图
    private Bitmap getAlbumArt(int album_id) {
        String mUriAlbums = "content://media/external/audio/albums";
        String[] projection = new String[]{"album_art"};
        Cursor cur =getContext().getContentResolver().query(Uri.parse(mUriAlbums + "/" + Integer.toString(album_id)), 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) {
            bm = BitmapFactory.decodeFile(album_art);
        }
        return bm;
    }

}
  }

所要跳转到的界面Activity代码:

public class MusicActivity extends AppCompatActivity {
//定义layout中的控件
private TextView titleTV;
private TextView autherTV;

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

        bindID();//绑定id
//获得从另一个界面的传值
        Intent intent=getIntent();
        String titile=intent.getStringExtra("title");
        String auther=intent.getStringExtra("auther");
        String album=intent.getStringExtra("album");

        titleTV.setText(titile);
        autherTV.setText(auther+"-"+album);
    }
//给控件绑定的id
    private void bindID() {
        titleTV=findViewById(R.id.music_title);
        autherTV=findViewById(R.id.music_auther);
    }
}

获取如图所示:
仿写网易云音乐列表界面设计过程_第4张图片仿写网易云音乐列表界面设计过程_第5张图片

下面博客里有专业的的Android获取音乐专辑封面图讲解

http://blog.csdn.net/jasper_success/article/details/78832286

MainActivity代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//定义控件和数组
    private TextView localtv;
    private TextView onlinetv;
    private ViewPager viewPager;
    private List fragmentList=new ArrayList<>();

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

        bindID();//绑定id的类
//设置监听
        localtv.setOnClickListener(this);
        onlinetv.setOnClickListener(this);
//实现滑动的fragment
        LocalFragment localFragment=new LocalFragment();
        OnlineFragment onlineFragment=new OnlineFragment();

        fragmentList.add(localFragment);
        fragmentList.add(onlineFragment);
//绑定适配器
        MusicPagerAdapter pagerAdapter=new MusicPagerAdapter(getSupportFragmentManager(),fragmentList);
        viewPager.setAdapter(pagerAdapter);
    }
//绑定id而定义的单独类
    private void bindID() {
        localtv=findViewById(R.id.main_local_music);
        onlinetv=findViewById(R.id.main_online_music);
        viewPager=findViewById(R.id.main_local_viewpager);
    }
//点击事件所要滑动的界面
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.main_local_music:
                viewPager.setCurrentItem(0);
                break;
            case R.id.main_online_music:
                viewPager.setCurrentItem(1);
                break;
            default:
                break;
        }
    }
}

但代码在Android 5.0设备运行时,可以得到正确结果,但在Android 6.0以上设备运行时,提示没有读写权限。但AndroidManifest文件中已经设置过权限了。
下面有对权限问题的详细讲解:

http://blog.csdn.net/jasper_success/article/details/78836899

你可能感兴趣的:(小白的编程)