您的位置:首页 > 移动开发 > Android开发

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

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

1、功能简介

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


实现的列表效果图如下所示:





2、实现功能过程

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

1. 建立一个实体类entity包

2. 建立一个适配器adapter包

3. 建立一个fragment包

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

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

<android.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"
>
</android.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

开始布局代码如下所示:
`<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
//运用orientation进行布局
android:orientation="horizontal">
</LinearLayout>`


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

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


在适配器中

private Context context;
private List<Music> musicList;

public MusicListAdapter(Context context,List<Music> 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>


如图所示:



public class LocalFragment extends Fragment {
private ListView localListview;  //定义我的音乐中的listview控件
private List<Music> 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);
}
}


获取如图所示:





下面博客里有专业的的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<Fragment> 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐