音乐播放器的实现-Music类的Adapter (2)

本文详细介绍了如何使用Adapter将Music数据展示至ListView,并实现点击音乐触发播放功能。通过MusicAdapter自定义适配器,实现了音乐列表的动态显示与点击事件处理,包括背景色变化与播放音乐的Intent传递。

一。Adapter

前面我们得到了Music类和 MusicList类,我们要想得到Music 数据 ,只用调用 MusicList的 getMusicData(Context)就可以了 ,现在我们要将数据显示至少ListView中。

List<Music> listMusic = MusicList.getMusicData(getApplicationContext());
musicAdapter= new MusicAdapter(this , listMusic);
listView.setAdapter(musicAdapter);

在Adapter 中,我们要显示三个数据 ,  name ,singer ,time .传递进去的变量是 listMusic、

public class MusicAdapter extends BaseAdapter {
	Context context;
	private List<Music> listMusic;
	private LayoutInflater inflater;
	private int selectedItem =-1;
	
	private class ViewHolder{
		ImageView image;
		TextView name;
		TextView singer;
		TextView time ;
	}
	
	public MusicAdapter(Context context,
			List<Music> listMusic) {
		// TODO Auto-generated constructor stub
		this .context=context;
		this.listMusic= listMusic;
		inflater = LayoutInflater.from(context);
	}
	

	public int getSelectedItem() {
		return selectedItem;
	}


	public void setSelectedItem(int selectedItem) {
		this.selectedItem = selectedItem;
	}


	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return listMusic.size();
	}

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return listMusic.get(position);
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(int position, View convertView , ViewGroup parent) {
		// TODO Auto-generated method stub
		ViewHolder holder;
		if (convertView==null){  //第一次展示convertview与内容 的结合 
			convertView = inflater.inflate(R.layout.musicitem, null);
			holder = new ViewHolder();
			holder.image = (ImageView) convertView.findViewById(R.id.music_item_image);
			holder.name = (TextView)convertView.findViewById(R.id.music_item_name);
			holder.singer = (TextView)convertView.findViewById(R.id.music_item_singer);
			holder.time = (TextView)convertView.findViewById(R.id.music_item_time);
			convertView.setTag(holder);
			/*Sets the tag associated with this view. A tag can be used to mark 
			             * a view in its hierarchy and does not have to be unique within the hierarchy.
			             *  Tags can also be used to store data within a view without resorting to
			             *   another data structure.
			             */
		}else {
			holder = (ViewHolder) convertView.getTag();
			//将holder  添加到动态生成的View里面
		}
		Music music = listMusic.get(position);
		
		holder.name.setText(music.getName());
		holder.singer.setText(music.getSinger());
		holder.time.setText(toTime((int) music.getTime()));
		return convertView;
	}

	public String toTime (int time ){
		time/=1000;   //原来 为ms
		int minute =time /60;
		int second = time%60;
		return String.format("%02d:%02d", minute,second);

	}

}

在这里,我们为了区分是否为被点击 的音乐 ,可以修改所对应的 List 的背景,也就是  convertView 的背景。这就是 selectedItem 的作用。

修改代码 如下:

if (getSelectedItem()==position){
			convertView.setBackgroundColor(Color.GRAY);  //是被点击 的音乐 
		}else {                                                                             //没有点击 的音乐 
			convertView.setBackgroundColor(Color.TRANSPARENT);
			convertView.getBackground().setAlpha(120);
		}
		return convertView;

除此外,我们还要在 MusicActivity 中,对adapter 里面 selectedItem 进行牡设置。如下。


二。监听 Adapter 

当我们点击 listView 上的一个音乐 时,就将这个 position 传递给播放音乐 的界面 OnPlayActivity,然后  OnPlayActivity 可以 将 postion 传递给 Service 以进行音乐 的播放。

OnItemClickListener ItemClick=new OnItemClickListener() {
		@Override
		public void onItemClick(AdapterView<?> parent, View v, int position,
				long id ) {
			// TODO Auto-generated method stub
			musicAdapter.setSelectedItem(position);
				musicAdapter.notifyDataSetInvalidated();//让adpater不再变化 
			Intent i = new Intent(getBaseContext(), OnPlayActivity.class);
			i.putExtra("id", position);
			startActivity(i);
		}
	};


这里,我们补充知识 

notifyDataSetChanged方法通过一个外部的方法控制如果适配器的内容改变时需要强制调用getView来刷新每个Item的内容。

 

public void notifyDataSetChanged ()

 

该方法内部实现了在每个观察者上面调用onChanged事件。每当发现数据集有改变的情况,或者读取到数据的新状态时,就会调用此方法。

 

public void notifyDataSetInvalidated ()

 

该方法内部实现了在每个观察者上面调用onInvalidated事件。每当发现数据集监控有改变的情况,比如该数据集不再有效,就会调用此方法。

今天用到Listview刷新功能,之前解决都是给Listview重新负上adapter这样listview就滚动到第一条了,但是这样会有些耗内存,程序写法也不美观。理论上是这样的,需要实验一下,重要的是一下两句话!

notifyDataSetInvalidated(),会重绘控件(还原到初始状态)

notifyDataSetChanged(),重绘当前可见区域


转载于:https://my.oschina.net/chuiyuan/blog/268735

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值