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

时间:2021-02-12 10:15:21

最近在做一个音乐播放器的小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;
}

}


暂时只是写到这里了