Android音乐播放器 -- UI 代码构现

Fragment是 android3.0之后出现的概念, 目前广泛使用与各种App中,比如大家非常熟悉的微信,QQ等的切换,我使用了Fragment实现 我的 / 歌手 / 专辑 列表切换,下面是利用Fragment搭建UI的过程

MySongFragment.java

package com.saberhao.fragment;

import java.util.List;
import android.app.Activity;
import android.app.ListFragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.annotation.SuppressLint;

import com.saberhao.Adapter.MusicListAdapter;
import com.saberhao.support.MusicInfo;
import com.saberhao.mediaplayer.R;
import com.saberhao.musichandle.CursorHandle;

@SuppressLint("NewApi")
public class MySongFragment extends ListFragment{
	
	private static String TAG = "MySongFragment";
	MusicListAdapter listAdapter;
	private List<MusicInfo> musicInfolist = null;
	OnArticleSelectedListener mListener;
	
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		
		musicInfolist = CursorHandle.getMusicInfos(getActivity());
		listAdapter = new MusicListAdapter(getActivity(),musicInfolist);
		setListAdapter(listAdapter);
	}
		
	public View onCreateView(LayoutInflater inflater, ViewGroup container,  
            Bundle savedInstanceState) {  
        View mysonglayout = inflater.inflate(R.layout.mysong_listview, container, false); 
        return mysonglayout; 
    }  
	
	@Override  
    public void onListItemClick(ListView l, View v, int position, long id) {  
        System.out.println("Click On List Item!!!"); 
        Log.e(TAG, "Click the music list!!!!!");
        super.onListItemClick(l, v, position, id); 
	}
		
}


关键有两点,一是需要在 onCreateView中,在通过inflate 获取view ,进行listview的装载, 对应的mysong_listview.xml 如下

<?xml version="1.0" encoding="utf-8"?>  
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical"
     >  
  
    <ListView  
        android:id="@+id/android:list"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
         />  

</RelativeLayout> 

二是,通过MusicListAdapt将数据和视图联系起来

listAdapter = new MusicListAdapter(getActivity(),musicInfolist);


MusicListAdapt.java

@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder viewHolder = null;
		if(convertView == null)
		{
			viewHolder = new ViewHolder();
			convertView = LayoutInflater.from(context).inflate(R.layout.mysong_layout, null);
			viewHolder.musicTitle = (TextView) convertView.findViewById(R.id.music_title_show);
			viewHolder.musicArtist = (TextView) convertView.findViewById(R.id.music_singer_show);
			viewHolder.musicDuration = (TextView) convertView.findViewById(R.id.music_time_show);
			convertView.setTag(viewHolder);			//表示给View添加一个格外的数据,
		} else {
			viewHolder = (ViewHolder)convertView.getTag();//通过getTag的方法将数据取出来
		}
		mp3Info = mp3Infos.get(position);
		viewHolder.musicTitle.setText(mp3Info.getTitle());			//显示标题
		viewHolder.musicArtist.setText(mp3Info.getArtist());		//显示艺术家
		viewHolder.musicDuration.setText(CursorHandle.formatTime(mp3Info.getDuration()));//显示时长
		
		return convertView;
	}
	
	
	public class ViewHolder {
		//所有控件对象引用
		//public ImageView albumImage;	//专辑图片
		public TextView musicTitle;		//音乐标题
		public TextView musicDuration;	//音乐时长
		public TextView musicArtist;	//音乐艺术家
	}
}

通过 LayoutInflater获取布局mysong_layout.xml,对于每个ListView, 我们使用了下面的mysong_layout.xml进行定义

mysong_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="70dp" 
    android:background="#3f000000">
    
    <RelativeLayout
	      android:id="@+id/music_about_layout"
	      android:layout_width="250dp"
	      android:layout_height="55dp"
	      android:layout_alignParentBottom="true" >
          
		  <TextView
               android:id="@+id/music_title_show"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_alignParentLeft="true"
               android:layout_marginLeft="7.0dp"
               android:layout_marginTop="7.0dp"
               android:textSize="15sp"
               android:singleLine="true"
               android:text="@string/song"
               android:textColor="@android:color/white" />

           <TextView
               android:id="@+id/music_singer_show"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_alignParentLeft="true"
               android:layout_below="@id/music_title_show"
               android:layout_marginBottom="1.0dp"
               android:layout_marginLeft="7.0dp"
               android:textSize="13sp"
               android:text="@string/singer"
               android:textColor="@android:color/white" />	      
	   </RelativeLayout>
	   
       <TextView
               android:id="@+id/music_time_show"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_marginLeft="5.0dp"
               android:layout_marginRight="12.0dp"
               android:layout_marginTop="5.0dp"
               android:layout_alignTop="@id/music_about_layout"
               android:layout_toRightOf="@id/music_about_layout"
               android:layout_alignParentRight="true"
               android:gravity="right"
               android:textSize="13sp"
               android:ellipsize="marquee"
               android:marqueeRepeatLimit="marquee_forever"
               android:singleLine="true"
               android:text="@string/time"
               android:textColor="@android:color/white" />

</RelativeLayout>


到这里  ”我的“ 列表 相关的fragment 配置就完成了, ”歌手“ 还有 ”专辑“ 列表 也是类似,这里就不详叙了

接下来 要做的就是在 主界面中装载对应的 fragment,   对应的主界面布局文件如下 

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
	android:orientation="vertical"
	android:background="@drawable/wood_bg2"
    tools:context=".MainActivity" >
    
    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="#3f000000"
        >
        
        <Button
            android:id="@+id/mysong_btn"
            style ="?android:attr/buttonBarButtonStyle" 
            android:layout_width="0dp"
            android:layout_height="match_parent" 
            android:gravity="center"
            android:layout_weight="1"
            android:text="@string/mysong"
            android:textColor="#ceefff" />
       
       <Button
            android:id="@+id/singer_btn"
            style ="?android:attr/buttonBarButtonStyle" 
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="@string/singer"
            android:textColor="#ceefff"
            />
       
       <Button
            android:id="@+id/album_btn"
            style ="?android:attr/buttonBarButtonStyle" 
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="@string/album"
            android:textColor="#ceefff"
            />     
    </LinearLayout>
    
    <FrameLayout
        android:id="@+id/musiclist"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >
    </FrameLayout>
    

    <RelativeLayout 
	    android:layout_width="fill_parent"
	    android:layout_height="52dp"
	    android:background="#5f000000">
	
	     <ImageView
	         android:id="@+id/default_pic_bar"
	         android:layout_width="0dp"
	         android:layout_height="match_parent"
	         android:layout_alignParentLeft="true"
	         android:layout_alignParentBottom="true"
	         android:background="#0000"
	         android:src="@drawable/defaul_pic_2" 
	         />
	         
		  <RelativeLayout
		      android:id="@+id/music_about_layout"
		      android:layout_width="180dp"
		      android:layout_height="match_parent"
		      android:layout_alignParentBottom="true"
		      android:layout_alignTop="@id/default_pic_bar"
		      android:layout_toRightOf="@id/default_pic_bar" >
	          
			  <TextView
	               android:id="@+id/music_title"
	               android:layout_width="wrap_content"
	               android:layout_height="wrap_content"
	               android:layout_alignParentLeft="true"
	               android:layout_marginLeft="7.0dp"
	               android:layout_marginTop="5.0dp"
	               android:textSize="17sp"
	               android:ellipsize="marquee"
	               android:focusable="true"
	               android:focusableInTouchMode="true"
	               android:marqueeRepeatLimit="marquee_forever"
	               android:singleLine="true"
	               android:text="@string/song"
	               android:textColor="@android:color/white" />
	
	           <TextView
	               android:id="@+id/music_singer"
	               android:layout_width="wrap_content"
	               android:layout_height="wrap_content"
	               android:layout_alignParentLeft="true"
	               android:layout_below="@id/music_title"
	               android:layout_marginBottom="4.0dp"
	               android:layout_marginLeft="7.0dp"
	               android:textSize="12sp"
	               android:text="@string/singer"
	               android:textColor="@android:color/white" />	      
		   </RelativeLayout>
	      
	       <ImageButton
	          android:id="@+id/play_bar"
	          android:layout_width="50dp"
	          android:layout_height="fill_parent"
	          android:layout_marginRight="5dp"
	          android:background="#0000"
	          android:layout_toRightOf="@id/music_about_layout"
	          android:layout_alignTop="@id/music_about_layout"
	          android:src="@drawable/play" />
	      
	       <ImageButton
	             android:id="@+id/next_bar"
	             android:layout_width="50dp"
	             android:layout_height="fill_parent"
	             android:layout_alignParentRight="true"
	             android:background="#0000"
	             android:layout_marginRight="5dp"
	             android:layout_alignTop="@id/play_bar"
	             android:layout_toRightOf="@id/play_bar"
	             android:src="@drawable/next" />
	</RelativeLayout>
    
</LinearLayout>

activity 动态转载 fragment

MainActivity.java

package com.saberhao.mediaplayer;

import java.util.List;
import com.saberhao.fragment.MyLoveFragment;
import com.saberhao.fragment.MySongFragment;
import com.saberhao.fragment.ArtistFragment;
import com.saberhao.fragment.AlbumFragment;
import com.saberhao.musichandle.CursorHandle;


public class MainActivity extends Activity implements MySongFragment.OnArticleSelectedListener{
	
	private static String TAG = "MainActivity";
	private static int INVALID = -1;
	
	private MySongFragment mysongFragment;
	private MyLoveFragment myloveFragment;
	private ArtistFragment singerFragment;
	private AlbumFragment albumFragment;
	private FragmentManager fragmentManager; 
	
	private Button mysongBtn;
	//private Button myloveBtn;
	private Button singerBtn;
	private Button albumBtn;
	
	private ImageButton playBtn;
	private ImageButton nextBtn;
	private View musicAboutLayout;
	private TextView musicSinger;
	private TextView musicTitle;
	private String url;         // 歌曲路径
	private String titleName;
	private int type = Common.PlayerType.TYPE_ALL;
	private int type0;

	private List<MusicInfo> MusicInfos = null;
	private boolean isPlaying = false; // 正在播放
	private int listposition = 0;


	
	private MainBroadcastReceiver MainBroadcastReceiver;
	public static final String ACTION_UPDATE_INFO = "android.intent.action.ACTION_UPDATE_INFO";
	
	

	@SuppressLint("NewApi")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE); 
		setContentView(R.layout.activity_main);
		MusicInfos = CursorHandle.getMusicInfos(MainActivity.this);
		//注册广播接收器
		registerReceiver();
		//初始化布局
		initView();
		//获取FragmentManager 以便对Fragment进行管理
		fragmentManager = getFragmentManager();
		setTabSeletion(0);
		//发送intent更新音乐播放进度	
		
	}

	/** 
     * 将所有的Fragment都置为隐藏状态。 
     *  
     * @param transaction 
     * 用于对Fragment执行操作的事务 ,
     * Fragment只是被隐藏起来,这样可以节省不断new fragment的内存消耗
     */  
	private void hideFragments(FragmentTransaction transaction) {
		// TODO Auto-generated method stub
		if(null != mysongFragment)
			transaction.hide(mysongFragment);
		
		if(null != myloveFragment)
			transaction.hide(myloveFragment);
		
		if(null != singerFragment)
			transaction.hide(singerFragment);
		
		if(null != albumFragment)
			transaction.hide(albumFragment);
	}

	/** 
     * 清除掉所有的选中状态。 
     */  
	private void initView() {
		// TODO Auto-generated method stub
		mysongBtn =  (Button)findViewById(R.id.mysong_btn);
		//myloveBtn =  (Button)findViewById(R.id.mylove_btn);
		singerBtn =  (Button)findViewById(R.id.singer_btn);
		albumBtn =  (Button)findViewById(R.id.album_btn);
		playBtn = (ImageButton)findViewById(R.id.play_bar);
		nextBtn = (ImageButton)findViewById(R.id.next_bar);
		musicAboutLayout = findViewById(R.id.music_about_layout);
		musicSinger = (TextView)findViewById(R.id.music_singer);
		musicTitle = (TextView)findViewById(R.id.music_title);
		//设置播放bar显示
		MusicInfo musicInfo = MusicInfos.get(listposition);
		musicTitle.setText(musicInfo.getTitle()); // 显示歌曲标题
		musicSinger.setText(musicInfo.getArtist()); //显示歌手名字
		//设置监听
		ViewOnClickListener viewOnClickListener = new ViewOnClickListener();
		mysongBtn.setOnClickListener(viewOnClickListener);
		//myloveBtn.setOnClickListener(viewOnClickListener);
		singerBtn.setOnClickListener(viewOnClickListener);
		albumBtn.setOnClickListener(viewOnClickListener);
		PlayBarOnClickListener playBarOnClickListener = new PlayBarOnClickListener();
		playBtn.setOnClickListener(playBarOnClickListener);
		nextBtn.setOnClickListener(playBarOnClickListener);
		musicAboutLayout.setOnClickListener(playBarOnClickListener);
		
			
	}
	
	private void clearSelection() {
		// TODO Auto-generated method stub
		//淡化字体颜色 选中时设置为  颜色加深 #ceefff
		mysongBtn.setTextColor(Color.parseColor("#a6bff2"));
		//myloveBtn.setTextColor(Color.parseColor("#a6bff2"));
		singerBtn.setTextColor(Color.parseColor("#a6bff2"));
		albumBtn.setTextColor(Color.parseColor("#a6bff2"));
		//提高透明度     前两位为透明度 00代表全透明, ff代表不透明   选中时用   #3f000000
		mysongBtn.setBackgroundColor(Color.parseColor("#3f000000"));
		//myloveBtn.setBackgroundColor(Color.parseColor("#3f000000"));
		singerBtn.setBackgroundColor(Color.parseColor("#3f000000"));
		albumBtn.setBackgroundColor(Color.parseColor("#3f000000"));
	}
	
	 /** 
     * 根据传入的index参数来设置选中的tab页。 
     *  
     * @param index 
     * 每个tab页对应的下标。0表示 "我的",1表示"最爱",2表示"歌手",3表示"专辑"。 
     */  
	private void setTabSeletion(int index) {
		// TODO Auto-generated method stub
		// 1. 清除当前状态
		clearSelection();
		// 2. 开启Fragment事务
		FragmentTransaction transaction = fragmentManager.beginTransaction();
		// 3. 隐藏所有Fragment,以防止多个fragment显示
		hideFragments(transaction); 
		switch(index){
		case 0:
			// 点击"我的"按钮, UI变化
			mysongBtn.setTextColor(Color.parseColor("#ceefff"));
			mysongBtn.setBackgroundColor(Color.parseColor("#5f000000"));
			if(null == mysongFragment){
				mysongFragment = new MySongFragment();
				transaction.add(R.id.musiclist, mysongFragment);
			}else {
				transaction.show(mysongFragment);
			}
			break;
			
		case 2:	
			// 点击"歌手"按钮, UI变化
			singerBtn.setTextColor(Color.parseColor("#ceefff"));
			singerBtn.setBackgroundColor(Color.parseColor("#5f000000"));
			if(null == singerFragment){
				singerFragment = new ArtistFragment();
				transaction.add(R.id.musiclist, singerFragment);
			}else {
				transaction.show(singerFragment);
			}
			break;
			
		case 3:
			// 点击"专辑"按钮, UI变化
			albumBtn.setTextColor(Color.parseColor("#ceefff"));
			albumBtn.setBackgroundColor(Color.parseColor("#5f000000"));
			if(null == albumFragment){
				albumFragment = new AlbumFragment();
				transaction.add(R.id.musiclist, albumFragment);
			}else {
				transaction.show(albumFragment);
			}
			break;
			
		default: 
			break;
		}
		//事务提交
		transaction.commit();
	}

	//监听tab点击动作,选择对应的fragment动态加载
	private class ViewOnClickListener implements OnClickListener {
		@Override
		public void onClick(View arg0) {
			// TODO Auto-generated method stub
			switch(arg0.getId()) {
			case R.id.mysong_btn:
				setTabSeletion(0);
				break;
			case R.id.singer_btn:
				setTabSeletion(2);
				break;
			case R.id.album_btn:
				setTabSeletion(3);
				break;
			default:  
	            break;
			}
		}
		
		
	}
}

最后的效果 如下图

    

过程中遇到了个问题 和大家分享下, 就是旋转屏幕之后,会有重影, 度娘了下, 大概有3中解决办法

1. 讲背景颜色设置为不透明 

android:background="#ffffffff"
这个方法虽好,但是没有根本上解决问题,这是让上图层完全遮住了下面图层,同时存在两个图层,只是下面的图层被挡住了,没有采用

2. 使用 transaction.replace 代替  transaction.add

transaction.replace(R.id.musiclist, mysongFragment);
这种方法就是将原有图层销毁,然后在新建一个图层,可以解决问题,但是,fragment的优势就是可以隐藏而不重绘,可以节省系统资源,显然这个方法和fragment的原意有点不搭,所以我还是坚持使用add 方法

3. 旋转屏幕为什么会出现重影? 其实旋转屏幕会重现调用onCreat方法进行重绘,由于原来fragment没有销毁,所以产生了重影的现象,解决的办法,旋转不onCreate!

在Androidmanifest.xml  的 MainActivity声明中添加 

android:configChanges="orientation|screenSize"
即可解决

重要的事情,源码请猛戳 这里 下载


下篇文章 Android音乐播放器 -- 实现框架 将介绍MediaPlayer的基本框架,敬请期待~








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值