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

来源:互联网 发布:战地2win7优化补丁 编辑:程序博客网 时间:2024/06/05 00:09

最近在做一个音乐播放器的小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) */@Overrideprotected 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() */@Overridepublic 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());elseinvalidate();} 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) */@Overrideprotected void dispatchDraw(Canvas canvas) {boolean fastDraw = mTouchState != TOUCH_STATE_SCROLLING && mNextScreen == INVALID_SCREEN;// If we are not scrolling or flinging, draw only the current screenif (fastDraw) {drawChild(canvas, getChildAt(mCurrentScreen), getDrawingTime());} else {final long drawingTime = getDrawingTime();// If we are flinging, draw only the current screen and the target// screenif (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 childrenfinal 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) */@Overrideprotected 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) */@Overridepublic 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) */@Overrideprotected 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) */@Overridepublic 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) */@Overridepublic 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 touchmLastMotionX = 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 axismTouchState = TOUCH_STATE_SCROLLING;enableChildrenCache();}// Either way, cancel any pending longpressif (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// everythingfinal 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) */@Overridepublic 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 startedmLastMotionX = x;break;case MotionEvent.ACTION_MOVE:System.out.println("---ScrollableViewGroup---onTouchEvent-----MotionEvent.ACTION_MOVE-------");if (mTouchState == TOUCH_STATE_SCROLLING) {// Scroll to follow the motion eventfinal 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 leftsnapToScreen(mCurrentScreen - 1);} else if (velocityX < -SNAP_VELOCITY && mCurrentScreen < getChildCount() - 1) {// Fling hard enough to move rightsnapToScreen(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;elsewhichScreen = (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;} elsemPaintFlag = 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);}// 为了保证能够响应触摸事件 返回truepublic boolean onTouchEvent(MotionEvent paramMotionEvent) {//return super.onTouchEvent(paramMotionEvent);//action_down//action_moveswitch (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;@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {//多次启动service只会走一次player = new MediaPlayer();player.setOnErrorListener(this);//资源错误player.setOnPreparedListener(this);//准备player.setOnCompletionListener(this);//完成super.onCreate();}@Overridepublic 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 blocke.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;    }    }    //相关资源回调方法@Overridepublic void onCompletion(MediaPlayer mp) {// TODO Auto-generated method stub}@Overridepublic void onPrepared(MediaPlayer mp) {//资源准备好后把时长发给if(mTimer==null){mTimer = new Timer();}mTimer.schedule(new TimerTask() {@Overridepublic 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 blocke.printStackTrace();}}}, 0, 1000);}@Overridepublic 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;}}};@Overrideprotected 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() {@Overridepublic 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() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {// 停止拖拽mSk_duration.setProgress(seekBar.getProgress());// 设置进度条startMusic("进度", seekBar.getProgress());}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {// 触摸}@Overridepublic 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);}@Overridepublic 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;}@Overridepublic int getCount() {if(InitMusic.musicList!=null){return InitMusic.musicList.size();}return 0;}@Overridepublic Object getItem(int position) {if(InitMusic.musicList!=null){return InitMusic.musicList.get(position);}return null;}@Overridepublic long getItemId(int position) {if(InitMusic.musicList!=null){return position;}return 0;}@Overridepublic 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;}}


暂时只是写到这里了






0 0