关于音乐播放器的一个小Demo

最近在做一个音乐播放器的小Demo,下面记录一下在做的过程中觉得不错的东西,大家都知道音乐播放器一般都是放到service中做的,

本Demo中牵扯到service和Activity之间的传值问题,以及播放音乐的title光亮问题

首先是布局方面,封装了连个工具类,用到布局中,可以直接实现点击任意按钮,切换对应界面,当然也可用fragment的hide(),show()方法

首先是写了两个自定义控件,分别为ScrollableViewGroup,和ViewGroupHook

ScrollableViewGroup继承ViewGroup

public class ScrollableViewGroup extends ViewGroup {
	private static final int INVALID_SCREEN = -1;
	private static final int TOUCH_STATE_REST = 0;
	private static final int TOUCH_STATE_SCROLLING = 1;
	private static final int SNAP_VELOCITY = 1000;
	private int mDefaultScreen;
	private int mCurrentScreen;
	private int mNextScreen = INVALID_SCREEN;
	private int mMaximumVelocity;
	private Scroller mScroller;
	private int mTouchState;
	private boolean mFirstLayout = true;
	private float mLastMotionX;
	private float mLastMotionY;
	private int mTouchSlop;
	private boolean mAllowLongPress;
	private VelocityTracker mVelocityTracker;
	private int mPaintFlag = 0;
	private OnCurrentViewChangedListener mOnCurrentViewChangedListener;

	public interface OnCurrentViewChangedListener {

		public void onCurrentViewChanged(View view, int currentview);
	}

	/** * @param context */
	public ScrollableViewGroup(Context context) {
		super(context);
		initViewGroup();
	}

	/**
	 * * @param context * @param attrs
	 * */
	public ScrollableViewGroup(Context context, AttributeSet attrs) {
		super(context, attrs);
		initViewGroup();
	}

	/**
	 * * @param context * @param attrs * @param defStyle
	 * */
	public ScrollableViewGroup(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		initViewGroup();
	}

	/*
	 * * (non-Javadoc) * @see android.view.ViewGroup#onLayout(boolean, int, int,
	 * int, int)
	 */
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		int childLeft = 0;
		final int count = getChildCount();
		for (int i = 0; i < count; i++) {
			final View child = getChildAt(i);
			if (child.getVisibility() != View.GONE) {
				final int childWidth = child.getMeasuredWidth();
				child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
				childLeft += childWidth;
			}
		}
	}

	/**
	 * * Initializes various states for this viewgroup.
	 * */
	private void initViewGroup() {
		mScroller = new Scroller(getContext());
		mCurrentScreen = mDefaultScreen;
		final ViewConfiguration configuration = ViewConfiguration.get(getContext());
		mTouchSlop = configuration.getScaledTouchSlop();
		// mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
	}

	public boolean isDefaultViewShowing() {
		return mCurrentScreen == mDefaultScreen;
	}

	public int getCurrentView() {

		return mCurrentScreen;

	}

	public void setCurrentView(int currentView) {
		// snapToScreen(currentView);

		Log.d("qqqq", "here:view " + currentView);
		mCurrentScreen = Math.max(0, Math.min(currentView, getChildCount() - 1));
		scrollTo(mCurrentScreen * getWidth(), 0);
		if (mOnCurrentViewChangedListener != null)
			mOnCurrentViewChangedListener.onCurrentViewChanged(this, mCurrentScreen);
		invalidate();

	}

	/*
	 * * (non-Javadoc)
	 * 
	 * @see android.view.View#computeScroll()
	 */
	@Override
	public void computeScroll() {
		if (mScroller.computeScrollOffset()) {

			final int currx = mScroller.getCurrX(), curry = mScroller.getCurrY(), scrx = getScrollX(), scry = getScrollY();
			if (currx != scrx || curry != scry)
				scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
			else
				invalidate();
		} else if (mNextScreen != INVALID_SCREEN) {
			mCurrentScreen = Math.max(0, Math.min(mNextScreen, getChildCount() - 1));
			mNextScreen = INVALID_SCREEN;
			mPaintFlag = 0;
			clearChildrenCache();
			final int scrx = getScrollX(), scry = getScrollY(), mCurrentScrollX = mCurrentScreen * getWidth();
			if (scrx != mCurrentScrollX)
				scrollTo(mCurrentScrollX, scry);

		}
		if (mOnCurrentViewChangedListener != null)
			mOnCurrentViewChangedListener.onCurrentViewChanged(this, mCurrentScreen);

	}

	/*
	 * * (non-Javadoc) * @see
	 * android.view.ViewGroup#dispatchDraw(android.graphics.Canvas)
	 */
	@Override
	protected void dispatchDraw(Canvas canvas) {
		boolean fastDraw = mTouchState != TOUCH_STATE_SCROLLING && mNextScreen == INVALID_SCREEN;
		// If we are not scrolling or flinging, draw only the current screen
		if (fastDraw) {
			drawChild(canvas, getChildAt(mCurrentScreen), getDrawingTime());

		} else {
			final long drawingTime = getDrawingTime();
			// If we are flinging, draw only the current screen and the target
			// screen
			if (mNextScreen >= 0 && mNextScreen < getChildCount()
					&& (Math.abs(mCurrentScreen - mNextScreen) == 1 || mPaintFlag != 0)) {
				final View viewCurrent = getChildAt(mCurrentScreen), viewNext = getChildAt(mNextScreen);
				drawChild(canvas, viewCurrent, drawingTime);
				if (mPaintFlag == 0) {
					drawChild(canvas, viewNext, drawingTime);

				} else {
					Paint paint = new Paint();
					if (mPaintFlag < 0) {
						canvas.drawBitmap(viewNext.getDrawingCache(), -viewNext.getWidth(), viewNext.getTop(), paint);
					} else {
						canvas.drawBitmap(viewNext.getDrawingCache(), getWidth() * getChildCount(), viewNext.getTop(),
								paint);

					}
				}
			} else {
				// If we are scrolling, draw all of our children
				final int count = getChildCount();
				for (int i = 0; i < count; i++) {
					drawChild(canvas, getChildAt(i), drawingTime);
				}
				if (mPaintFlag != 0) {
					final View viewNext;
					Paint paint = new Paint();
					if (mPaintFlag < 0) {
						viewNext = getChildAt(getChildCount() - 1);
						canvas.drawBitmap(viewNext.getDrawingCache(), -viewNext.getWidth(), viewNext.getTop(), paint);
					} else {
						viewNext = getChildAt(0);
						canvas.drawBitmap(viewNext.getDrawingCache(), getWidth() * getChildCount(), viewNext.getTop(),
								paint);
					}
				}
			}
		}
	}

	/*
	 * * (non-Javadoc) * * @see android.view.View#onMeasure(int, int)
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		final int width = MeasureSpec.getSize(widthMeasureSpec);
		final int count = getChildCount();
		for (int i = 0; i < count; i++) {
			getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
		}
		if (mFirstLayout) {
			scrollTo(mCurrentScreen * width, 0);
			mFirstLayout = false;
		}
	}

	/*
	 * * (non-Javadoc) * * @see
	 * android.view.ViewGroup#requestChildRectangleOnScreen(android.view.View,
	 * android.graphics.Rect, boolean)
	 */
	@Override
	public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
		int screen = indexOfChild(child);
		if (screen != mCurrentScreen || !mScroller.isFinished()) {
			snapToScreen(screen);
			return true;
		}
		return false;

	}

	/*
	 * * (non-Javadoc) * * @see
	 * android.view.ViewGroup#onRequestFocusInDescendants(int,*
	 * android.graphics.Rect)
	 */
	@Override
	protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
		int focusableScreen;
		if (mNextScreen != INVALID_SCREEN) {
			focusableScreen = mNextScreen;

		} else {
			focusableScreen = mCurrentScreen;
		}
		getChildAt(focusableScreen).requestFocus(direction, previouslyFocusedRect);
		return false;

	}

	/*
	 * * (non-Javadoc) * * @see
	 * android.view.ViewGroup#dispatchUnhandledMove(android.view.View, int)
	 */

	@Override
	public boolean dispatchUnhandledMove(View focused, int direction) {

		if (direction == View.FOCUS_LEFT) {
			if (getCurrentView() > 0) {
				snapToScreen(getCurrentView() - 1);
				return true;

			}

		} else if (direction == View.FOCUS_RIGHT) {
			if (getCurrentView() < getChildCount() - 1) {
				snapToScreen(getCurrentView() + 1);
				return true;

			}
		}
		return super.dispatchUnhandledMove(focused, direction);
	}

	/*
	 * * (non-Javadoc) * * @see
	 * android.view.ViewGroup#onInterceptTouchEvent(android.view.MotionEvent)
	 */
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		final int action = ev.getAction();
		if ((action == MotionEvent.ACTION_MOVE) && (mTouchState != TOUCH_STATE_REST)) {
			return true;

		}
		final float x = ev.getX();
		final float y = ev.getY();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			System.out.println("---ScrollableViewGroup----onInterceptTouchEvent---MotionEvent.ACTION_DOWN---");
			// Remember location of down touch
			mLastMotionX = x;
			mLastMotionY = y;
			mAllowLongPress = true;
			/*
			 * * If being flinged and user touches the screen, initiate drag;
			 * otherwise don't. mScroller.isFinished should be false when being
			 * flinged.
			 */
			mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;
			break;
		case MotionEvent.ACTION_MOVE:
			System.out.println("----ScrollableViewGroup---onInterceptTouchEvent---MotionEvent.ACTION_MOVE---");
			final int xDiff = (int) Math.abs(x - mLastMotionX);
			final int yDiff = (int) Math.abs(y - mLastMotionY);
			final int touchSlop = mTouchSlop;
			boolean xMoved = xDiff > touchSlop;
			boolean yMoved = yDiff > touchSlop;
			if (xMoved || yMoved) {
				if (xMoved) {
					// Scroll if the user moved far enough along the X axis
					mTouchState = TOUCH_STATE_SCROLLING;
					enableChildrenCache();
				}
				// Either way, cancel any pending longpress
				if (mAllowLongPress) {
					mAllowLongPress = false;
					// Try canceling the long press. It could also have been
					// scheduled
					// by a distant descendant, so use the mAllowLongPress flag
					// to block
					// everything
					final View currentScreen = getChildAt(mCurrentScreen);
					currentScreen.cancelLongPress();
				}
			}
			break;

		case MotionEvent.ACTION_CANCEL:
			System.out.println("---ScrollableViewGroup----onInterceptTouchEvent---MotionEvent.ACTION_CANCEL---");
		case MotionEvent.ACTION_UP:
			System.out.println("---ScrollableViewGroup----onInterceptTouchEvent---MotionEvent.ACTION_UP---");
			mTouchState = TOUCH_STATE_REST;
			mAllowLongPress = false;
			break;

		}

		/*
		 * * The only time we want to intercept motion events is if we are in
		 * the drag mode.
		 */
		return mTouchState != TOUCH_STATE_REST;//true-->孩子  

	}

	void enableChildrenCache() {
		final int count = getChildCount();
		for (int i = 0; i < count; i++) {
			final View layout = getChildAt(i);
			layout.setDrawingCacheEnabled(true);
			if (layout instanceof ViewGroup) {

				((ViewGroup) layout).setAlwaysDrawnWithCacheEnabled(true);

			}
		}
	}

	void clearChildrenCache() {
		final int count = getChildCount();
		for (int i = 0; i < count; i++) {
			final View layout = getChildAt(i);
			if (layout instanceof ViewGroup) {
				((ViewGroup) layout).setAlwaysDrawnWithCacheEnabled(false);

			}
		}
	}

	/*
	 * * (non-Javadoc) * * @see
	 * android.view.View#onTouchEvent(android.view.MotionEvent)
	 */

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (mVelocityTracker == null) {
			mVelocityTracker = VelocityTracker.obtain();

		}
		mVelocityTracker.addMovement(event);
		final int action = event.getAction();
		final float x = event.getX();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			System.out.println("--ScrollableViewGroup----onTouchEvent-----MotionEvent.ACTION_DOWN-------");
			/*
			 * * If being flinged and user touches, stop the fling. isFinished
			 * will be false if being flinged.
			 */
			if (!mScroller.isFinished()) {
				mScroller.abortAnimation();

			}
			// Remember where the motion event started
			mLastMotionX = x;
			break;
		case MotionEvent.ACTION_MOVE:
			System.out.println("---ScrollableViewGroup---onTouchEvent-----MotionEvent.ACTION_MOVE-------");
			if (mTouchState == TOUCH_STATE_SCROLLING) {
				// Scroll to follow the motion event
				final int deltaX = (int) (mLastMotionX - x);
				mLastMotionX = x;
				if (deltaX < 0) {
					/*
					 * * if (getScrollX() > 0) {
					 * scrollBy(Math.max(-getScrollX(),deltaX), 0);}
					 */
					if (getScrollX() <= 0) {
						mPaintFlag = -1;

					}
					scrollBy(deltaX, 0);
				} else if (deltaX > 0) {
					int availableToScroll = getChildAt(getChildCount() - 1).getRight() - getScrollX() - getWidth();
					/*
					 * if (availableToScroll > 0) {
					 * scrollBy(Math.min(availableToScroll, deltaX), 0); }
					 */
					if (availableToScroll <= 0) {
						mPaintFlag = 1;
						availableToScroll += getWidth() << 1;
					}
					if (availableToScroll > 0)
						scrollBy(Math.min(availableToScroll, deltaX), 0);
				}
			}
			break;
		case MotionEvent.ACTION_UP:
			System.out.println("---ScrollableViewGroup---onTouchEvent-----MotionEvent.ACTION_UP-------");
			if (mTouchState == TOUCH_STATE_SCROLLING) {
				final VelocityTracker velocityTracker = mVelocityTracker;
				// velocityTracker.computeCurrentVelocity(1000,
				// mMaximumVelocity);
				int velocityX = (int) velocityTracker.getXVelocity();
				if (velocityX > SNAP_VELOCITY && mCurrentScreen > 0) {
					// Fling hard enough to move left
					snapToScreen(mCurrentScreen - 1);
				} else if (velocityX < -SNAP_VELOCITY && mCurrentScreen < getChildCount() - 1) {
					// Fling hard enough to move right
					snapToScreen(mCurrentScreen + 1);

				} else {
					snapToDestination();

				}
				if (mVelocityTracker != null) {
					mVelocityTracker.recycle();
					mVelocityTracker = null;

				}

			}
			mTouchState = TOUCH_STATE_REST;
			break;
		case MotionEvent.ACTION_CANCEL:
			mTouchState = TOUCH_STATE_REST;

		}

		return true;

	}

	private void snapToDestination() {
		final int screenWidth = getWidth();
		final int scrollWidth = getScrollX() + (screenWidth >> 1);
		final int viewCount = getChildCount();
		final int whichScreen;
		if (scrollWidth < 0)
			whichScreen = -1;
		else if (scrollWidth > screenWidth * viewCount)
			whichScreen = viewCount;
		else
			whichScreen = (getScrollX() + (screenWidth / 2)) / screenWidth;
		snapToScreen(whichScreen);

	}

	public void snapToScreen(int whichScreen) {
		if (!mScroller.isFinished())
			return;
		enableChildrenCache();
		final int viewCount = getChildCount() - 1;
		final int oldWhichScreen = whichScreen;
		if (whichScreen < 0) {
			whichScreen = viewCount;
			mPaintFlag = -1;
			// next screen should be painted before current
		} else if (whichScreen > viewCount) {
			whichScreen = 0;
			mPaintFlag = 1;

		} else
			mPaintFlag = 0;
		// whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() -//
		// 1));
		boolean changingScreens = whichScreen != mCurrentScreen;
		mNextScreen = whichScreen;
		View focusedChild = getFocusedChild();
		if (focusedChild != null && changingScreens && focusedChild == getChildAt(mCurrentScreen)) {

			focusedChild.clearFocus();

		}
		final int newX = oldWhichScreen * getWidth();
		final int delta = newX - getScrollX();
		mScroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta) * 2);
		invalidate();
	}

	public void scrollLeft() {
		if (mNextScreen == INVALID_SCREEN && mCurrentScreen > 0 && mScroller.isFinished()) {
			snapToScreen(mCurrentScreen - 1);

		}
	}

	public void scrollRight() {
		if (mNextScreen == INVALID_SCREEN && mCurrentScreen < getChildCount() - 1 && mScroller.isFinished()) {
			snapToScreen(mCurrentScreen + 1);

		}

	}

	public void moveToDefaultScreen() {
		snapToScreen(mDefaultScreen);
		getChildAt(mDefaultScreen).requestFocus();

	}

	public boolean isScrollFinish() {
		return mTouchState != TOUCH_STATE_SCROLLING && mNextScreen == INVALID_SCREEN;
		// return mScroller.isFinished();

	}

	public OnCurrentViewChangedListener getOnCurrentViewChangedListener() {
		return mOnCurrentViewChangedListener;

	}

	public void setOnCurrentViewChangedListener(OnCurrentViewChangedListener mOnCurrentViewChangedListener) {

		this.mOnCurrentViewChangedListener = mOnCurrentViewChangedListener;

	}

}
ViewGroupHook extends FrameLayout

public class ViewGroupHook extends FrameLayout {

	public ViewGroupHook(Context paramContext) {
		super(paramContext);
	}

	public ViewGroupHook(Context paramContext, AttributeSet paramAttributeSet) {
		super(paramContext, paramAttributeSet);
	}

	public ViewGroupHook(Context paramContext, AttributeSet paramAttributeSet, int paramInt) {
		super(paramContext, paramAttributeSet, paramInt);
	}

	// 为了保证能够响应触摸事件 返回true
	public boolean onTouchEvent(MotionEvent paramMotionEvent) {
		//return super.onTouchEvent(paramMotionEvent);
		//action_down
		//action_move
		switch (paramMotionEvent.getAction()) {
		case MotionEvent.ACTION_DOWN:
			System.out.println("---viewGroudHook---onTouchEvent---ACTION_DOWN");
			break;
		case MotionEvent.ACTION_MOVE:
			System.out.println("---viewGroudHook---onTouchEvent---ACTION_MOVE");
			break;
		case MotionEvent.ACTION_UP:
			System.out.println("---viewGroudHook---onTouchEvent---ACTION_UP");

			break;
		case MotionEvent.ACTION_CANCEL:
			System.out.println("---viewGroudHook---onTouchEvent---ACTION_CANCEL");
			
			break;

		default:
			break;
		}
		return true;//action_down
	}
}

在布局中引用一下(有三个界面可以来回切换,分别为歌单,歌词详情,小歌词界面带seekbar的界面)

主Activity中引用

<com.example.musicandvideo.utils.ScrollableViewGroup
        android:id="@+id/svg_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/include_bottom"
        android:layout_below="@id/include_top" >

        <include layout="@layout/include_page_play" />

        <include layout="@layout/include_page_list" />

        <include layout="@layout/include_page_lrc" />
    </com.example.musicandvideo.utils.ScrollableViewGroup>

在每个子布局中也需要引用一下ViewGroupHook

<com.example.musicandvideo.utils.ViewGroupHook xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        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/lv_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
        </ListView>
    </LinearLayout>

</com.example.musicandvideo.utils.ViewGroupHook>

以上就可实现类似于微信界面

知识点一:MediaStore这个类是android系统提供的一个多媒体数据库,android中多媒体信息都可以从这里提取。
                    这个MediaStore包括了多媒体数据库的所有信息,包括音频,视频和图像,
   android把所有的多媒体数据库接口进行了封装,所有的数据库不用自己进行创建,
             直接调用利用ContentResolver去调用那些封装好的接口就可以进行数据库的操作了。

代码实现

public class InitMusic {
	//装载从内存卡上读取出来的音乐
    public static List<Music> musicList=new ArrayList<Music>();
    //播放按钮初始状态
    public static int CURRENTSTATE=MyConstant.STATIC_STOP;
    //title
    public static int CURRENTPOSITION=0;
	public static void getSong(Context context){
		Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;//”表“的路径
		String[] projection={MediaStore.Audio.Media.TITLE,MediaStore.Audio.Media.ARTIST,
				MediaStore.Audio.Media.DATA};//歌曲名,歌手,歌曲路径
		Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
		while(cursor.moveToNext()){
			String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
			String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
			String path = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
			Music music=new Music();
			music.setTitle(title);
			music.setArtist(artist);
			music.setPath(path);
			//把音乐封装进集合中
			musicList.add(music);
		}
	}

activity想要调用service中方法
1. bindService启动服务
2. aidl
3. 发送广播
4. 消息机制
5. 利用service多次启动,会重复调用 onStartCommd()方法的特性

这里用的是第五种

public class MusicService extends Service implements OnErrorListener,OnPreparedListener,OnCompletionListener{

	private MediaPlayer player;
	private Timer mTimer;
	private Messenger message;
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	@Override
	public void onCreate() {//多次启动service只会走一次
		player = new MediaPlayer();
		player.setOnErrorListener(this);//资源错误
		player.setOnPreparedListener(this);//准备
		player.setOnCompletionListener(this);//完成
		super.onCreate();
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {//每次启动都会执行
		String position=intent.getStringExtra("position");
		if(message==null){
			message = (Messenger)intent.getExtras().get("handl");
		}
		if(position.equals("播放")){
			String path=intent.getStringExtra("path");
			play(path);
		}else if(position.equals("暂停")){
			pause();
		}else if(position.equals("继续")){
			contnue();
		}else if(position.equals("停止")){
			stop();
		}else if(position.equals("进度")){
			int progress = intent.getIntExtra("progress",-1);
			player.seekTo(progress);
		}
		return super.onStartCommand(intent, flags, startId);
	}
    @Override
    public void onDestroy() {
    	super.onDestroy();
    }
    
    //播放
    public void play(String path){
    	
    	try {
    		player.reset();
			player.setDataSource(path);//设置播放资源路径
			player.prepare();
	    	player.start();
	    	InitMusic.CURRENTSTATE=MyConstant.STATIC_PLAY;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    }
    //暂停
    public void pause(){
    	if(player!=null&&player.isPlaying()){
    		player.pause();
    		InitMusic.CURRENTSTATE=MyConstant.STATIC_PAUSE;
    	}
    }
    //继续
    public void contnue(){
    	if(player!=null){
    		player.start();
    		InitMusic.CURRENTSTATE=MyConstant.STATIC_PLAY;
    	}
    }
    //停止
    public void stop(){
    	if(player!=null){
    		player.stop();
    		InitMusic.CURRENTSTATE=MyConstant.STATIC_STOP;
    	}
    }
    //相关资源回调方法
	@Override
	public void onCompletion(MediaPlayer mp) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void onPrepared(MediaPlayer mp) {
		//资源准备好后把时长发给
		if(mTimer==null){
			mTimer = new Timer();
		}
		
		mTimer.schedule(new TimerTask() {
			
			@Override
			public void run() {
				//获得时长
				int totalDuration = player.getDuration();//总时长
				int currentPosition = player.getCurrentPosition();//进度
				Message msg = Message.obtain();
				msg.what = 1;
				msg.arg1=totalDuration;
				msg.arg2=currentPosition;
				try {
					//发消息
					message.send(msg);
				} catch (RemoteException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}, 0, 1000);
		
		
	}
	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
		//Toast.makeText(getApplicationContext(), "亲,资源有问题哦", 0).show();
		return false;
	}
}
主Activity中

public class MainActivity extends ActionBarActivity implements OnClickListener {

	private ScrollableViewGroup svg_main;
	private TextView mTv_curduration;
	private ImageView mIv_bottom_play;
	private ListView mLv_list;
	private TextView mTv_minilrc;
	private TextView mTv_totalduration;
	private SeekBar mSk_duration;
	private ImageView mIv_bottom_model;
	MainActivity instance;
	// handler处理ui界面
	private Handler handler = new Handler() {
		private LrcUtil lrcUtil;
		
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case 1:
				// 获得时长
				int total = msg.arg1;
				int current = msg.arg2;
				// 把时间格式化
				String totalTime = formatTime(total);
				String curTime = formatTime(current);
				// 设置时长
				mTv_curduration.setText(curTime+"");
				mTv_totalduration.setText(totalTime+"");
				mSk_duration.setMax(total);// seekbar最大值
				mSk_duration.setProgress(current);// 随着歌曲进度改变
				//歌词显示
				if(lrcUtil==null){
					lrcUtil = new LrcUtil(instance);
				}
				//序列化歌词
				File lrcFile = InitMusic.getLrcFile(InitMusic.musicList.get(InitMusic.CURRENTPOSITION).getPath());
				//使用功能
				lrcUtil.ReadLRC(lrcFile);
				break;

			default:
				break;
			}
		}

	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		instance=this;
		initView();
		initData();
		initListener();
	}

	// 时间格式化
	protected String formatTime(int dataTime) {
		SimpleDateFormat format = new SimpleDateFormat("mm:ss");
		Date date = new Date(dataTime);
		String times = format.format(date);
		return times;
	}

	// 获得数据
	private void initData() {
		InitMusic.getSong(this);
		mLv_list.setAdapter(new MyAdapter(this));
	}

	// 监听事件
	private void initListener() {
		findViewById(R.id.ib_top_play).setOnClickListener(this);
		findViewById(R.id.ib_top_list).setOnClickListener(this);
		findViewById(R.id.ib_top_lrc).setOnClickListener(this);
		findViewById(R.id.ib_top_volumn).setOnClickListener(this);
		findViewById(R.id.ib_bottom_model).setOnClickListener(this);
		findViewById(R.id.ib_bottom_last).setOnClickListener(this);
		findViewById(R.id.ib_bottom_play).setOnClickListener(this);
		findViewById(R.id.ib_bottom_next).setOnClickListener(this);
		findViewById(R.id.ib_bottom_update).setOnClickListener(this);

		selectedTop(R.id.ib_top_play);

		// 条目监听
		mLv_list.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				// title颜色
				changeBlack();
				InitMusic.CURRENTPOSITION = position;
				changeGreen();
				// 播放
				startMusic("播放", InitMusic.musicList.get(position).getPath());

			}

		});
		// seekbar的监听
		mSk_duration.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {// 停止拖拽
				mSk_duration.setProgress(seekBar.getProgress());// 设置进度条
				startMusic("进度", seekBar.getProgress());

			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {// 触摸

			}

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {// 进度

			}
		});
	}

	// 初始化控件
	private void initView() {
		mTv_curduration = (TextView) findViewById(R.id.tv_curduration);
		mTv_minilrc = (TextView) findViewById(R.id.tv_minilrc);
		mTv_totalduration = (TextView) findViewById(R.id.tv_totalduration);
		mSk_duration = (SeekBar) findViewById(R.id.sk_duration);
		mIv_bottom_model = (ImageView) findViewById(R.id.iv_bottom_model);
		mIv_bottom_play = (ImageView) findViewById(R.id.iv_bottom_play);
		mLv_list = (ListView) findViewById(R.id.lv_list);
		svg_main = (ScrollableViewGroup) findViewById(R.id.svg_main);
	}

	/*
	 * 顶部按钮选中效果 (non-Javadoc)
	 * 
	 * @see android.view.View.OnClickListener#onClick(android.view.View)
	 */
	public void selectedTop(int selected) {
		// 先把所有控件设置成初始状态,不选中
		findViewById(R.id.ib_top_play).setSelected(false);
		findViewById(R.id.ib_top_list).setSelected(false);
		findViewById(R.id.ib_top_lrc).setSelected(false);
		findViewById(R.id.ib_top_volumn).setSelected(false);
		// 让点击的按钮设置为选中状态
		findViewById(selected).setSelected(true);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.ib_top_play:
			// 点击按钮是被显示的状态,只是写选择器是不行的
			svg_main.setCurrentView(0);
			selectedTop(R.id.ib_top_play);
			break;
		case R.id.ib_top_list:
			svg_main.setCurrentView(1);
			selectedTop(R.id.ib_top_list);
			break;
		case R.id.ib_top_lrc:
			svg_main.setCurrentView(2);
			selectedTop(R.id.ib_top_lrc);
			break;
		case R.id.ib_top_volumn:
			break;
		case R.id.ib_bottom_model:

			break;
		case R.id.ib_bottom_last:// 上一首
			if (InitMusic.CURRENTPOSITION > 0) {
				changeBlack();
				InitMusic.CURRENTPOSITION--;
				changeGreen();
				// 点击播放,开启服务
				startMusic("播放",
						InitMusic.musicList.get(InitMusic.CURRENTPOSITION)
								.getPath());
				// 修改图标
				mIv_bottom_play.setImageResource(R.drawable.appwidget_pause);

			}
			break;
		case R.id.ib_bottom_play:
			if (InitMusic.CURRENTSTATE == MyConstant.STATIC_STOP) {
				// 点击播放,开启服务
				startMusic("播放",
						InitMusic.musicList.get(InitMusic.CURRENTPOSITION)
								.getPath());
				// 修改图标
				mIv_bottom_play.setImageResource(R.drawable.appwidget_pause);
			} else if (InitMusic.CURRENTSTATE == MyConstant.STATIC_PLAY) {
				pauseMusic("暂停");
				// 修改图标
				mIv_bottom_play
						.setImageResource(R.drawable.img_playback_bt_play);
			} else if (InitMusic.CURRENTSTATE == MyConstant.STATIC_PAUSE) {
				continueMusic("继续");
				// 修改图标
				mIv_bottom_play.setImageResource(R.drawable.appwidget_pause);
			}

			break;
		case R.id.ib_bottom_next:// 下一首
			if (InitMusic.CURRENTPOSITION < InitMusic.musicList.size() - 1) {
				changeBlack();
				InitMusic.CURRENTPOSITION++;
				changeGreen();
				startMusic("播放",
						InitMusic.musicList.get(InitMusic.CURRENTPOSITION)
								.getPath());
				// 修改图标
				mIv_bottom_play.setImageResource(R.drawable.appwidget_pause);
			}
			break;
		case R.id.ib_bottom_update:
			break;
		default:
			break;
		}
	}

	// 封装的方法------
	// 播放
	public void startMusic(String position, String path) {
		// 点击播放,开启服务
		Intent service = new Intent(MainActivity.this, MusicService.class);
		service.putExtra("position", position);
		service.putExtra("handl", new Messenger(handler));
		service.putExtra("path", path);
		startService(service);
	}

	// 播放
	public void startMusic(String position, int progress) {
		// 点击播放,开启服务
		Intent service = new Intent(MainActivity.this, MusicService.class);
		service.putExtra("position", position);
		service.putExtra("handl", new Messenger(handler));
		service.putExtra("progress", progress);
		startService(service);
	}

	// 暂停
	public void pauseMusic(String position) {
		// 点击暂停
		Intent service = new Intent(MainActivity.this, MusicService.class);
		service.putExtra("position", position);
		//service.putExtra("handl", new Messenger(handler));
		startService(service);
	}

	// 继续
	public void continueMusic(String position) {
		// 点击暂停
		Intent service = new Intent(MainActivity.this, MusicService.class);
		service.putExtra("position", position);
		//service.putExtra("handl", new Messenger(handler));
		startService(service);
	}

	// 修改颜色,正常色
	public void changeBlack() {
		TextView tv = (TextView) mLv_list
				.findViewWithTag(InitMusic.CURRENTPOSITION);
		if (tv != null) {
			tv.setTextColor(Color.BLACK);
		}
	}

	// 绿色
	public void changeGreen() {
		TextView tv = (TextView) mLv_list
				.findViewWithTag(InitMusic.CURRENTPOSITION);
		if (tv != null) {
			tv.setTextColor(Color.GREEN);
		}
	}
	//设置mimi歌词
	public void setMiniLrc(String lrcString) {
		mTv_minilrc.setText(lrcString);
	}

}

Adapter代码:

public class MyAdapter extends BaseAdapter{
	private Context context;
	
	public MyAdapter(Context context) {
		super();
		this.context = context;
	}

	@Override
	public int getCount() {
		if(InitMusic.musicList!=null){
			return InitMusic.musicList.size();
		}
		return 0;
	}

	@Override
	public Object getItem(int position) {
		if(InitMusic.musicList!=null){
			return InitMusic.musicList.get(position);
		}
		return null;
	}

	@Override
	public long getItemId(int position) {
		if(InitMusic.musicList!=null){
			return position;
		}
		return 0;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder vh;
		if(convertView==null){
			vh=new ViewHolder();
			convertView=View.inflate(context,R.layout.item_music, null);
			vh.title=(TextView)convertView.findViewById(R.id.tv_title);
			vh.artist=(TextView)convertView.findViewById(R.id.tv_artist);
			convertView.setTag(vh);
		}else {
			vh=(ViewHolder) convertView.getTag();
		}
		//设置值
		vh.title.setText(InitMusic.musicList.get(position).getTitle());
		vh.title.setText(InitMusic.musicList.get(position).getArtist());
		//设置标题光亮,因为使用的是复用优化,为了避免下一屏的第一个title也会变颜色,所以一定要使用else 
		if(InitMusic.CURRENTPOSITION==position){
			vh.title.setTextColor(Color.GREEN);
		}else{
			vh.title.setTextColor(Color.BLACK);
		}
		vh.title.setTag(position);
		return convertView;
	}
	
	class ViewHolder{
		TextView title;
		TextView artist;
	}

}


暂时只是写到这里了






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值