2016-06-27 2 views
3

this tutorial에서 음악 응용 프로그램을 구현 중입니다.MediaPlayer 및 BaseAdapter를 다루는 방법

트랙 목록을 표시하는 데 사용되는 BaseAdapter 클래스와 음악을 재생하는 MusicPlayer 클래스가 있습니다. 둘 다 내 주요 활동 클래스의 변수입니다.

public class MainActivity extends Activity implements MediaPlayerControl{ 
     private MediaPlayer musicSrv; 
     private BaseAdapter songAdt; 
     ... 

MusicPlayer는 현재 완료되면 다음 트랙을 재생합니다. BaseAdapter에 메시지를 보내서 (현재 트랙의 색상을 변경하는 것과 같이) 각각의 새로운 재생 트랙에서 표시를 변경하는 가장 좋은 방법은 무엇입니까?

편집

는 의견에 따르면, 인터페이스 재화의 사용은 좋은 옵션이 될 것으로 보인다. 누군가 그것을 할 수있는 방법을 설명하는 세부 답변을 쓸 수 있습니까? 감사.

답변

1

감사 어댑터를 새로 고침 할 필요가 그래서 나는 인터페이스 솔루션을 구현하는 데 성공했습니다.

이 인 BaseAdapater에게 노래가 변경 될 때마다 새로 고침 내 주요 활동 클래스 :

public class MainActivity extends Activity implements MusicService.SongChangedListener { 
     private MediaPlayer musicSrv; 
     private BaseAdapter songAdt; 
     ... 

     @Override 
     public void songChanged(Song currentSong){ 
      songAdt.notifyDataSetChanged(); // refresh view 
     } 

그리고 내 MusicService 클래스 : 나는 songAdt.notifyDataSetChanged있어

public class MusicService extends Service implements MediaPlayer.OnPreparedListener{ 
... 
private MainActivity activity; 
... 

public void setActivity(MainActivity act){ 
    //set the activity 
    activity = act; 
} 

public interface SongChangedListener { 
    void songChanged(Song song); 
} 
... 
public void playSong(){ 
     // this function is called each time a new song is played 
     activity.songChanged(playSong); 
     ... 
} 
0

BaseAdapter의 메소드 getView() 메소드는 뷰를 제공하며 목록에 변수를 설정하고 변수가 설정되지 않은 경우 해당 색상을 기본값으로 재설정하여 현재 트랙의 색상을 변경해야합니다.

if (is this the current playing track) { 
    // Set the color of the view. 
} else { 
    // Set the color to default. 
} 

현재이 논리를 구현 한 경우 당신은 또한 현재 트랙 및 현재 재생중인 미디어를 추적 목록에서 변수, 간단한 songAdt.notifyDataSetChanged()를 변경할 때마다, 다음가에 BaseAdapter를 요청합니다 다시 호출하고 새 데이터에 따라보기를 설정합니다. ListView에 대해 더 깊이 이해하려면 this talk을 참조하십시오. 도움이 될거야.

RecyclerView와 함께 자신을 트레이닝하는 것이 좋습니다. ListView는 무서운 과거였습니다.

public class Activity implements SongChangedListener { 
... 
    @Override 
    onCreate() { 
     .... 
     PlayerManager pManager = new PlayerManager(); 
    } 

    onResume() { 
     pManager.setListener(this); 
    } 

    onPause() { 
     pManager.setListener(null); 
    } 

    @Override 
    void songChanged (MediaId idOfSong) { 
     if (getActivity == null) //If you received a callback after activity was killed. 
      return; 
     // Change the current song as not playing in List. (for your adapter) 
     // Change the idOfSong to currently playing in List (for your adapter). 
     // change currentSong = idOfSong; 
     // notify that the data in List has changed (songAdt.notifyDataSetChanged) 
    } 

} 

그리고 PlayerManager에서 인터페이스를 만들거나 인터페이스의 별도 클래스를 만들 수 있습니다. 인터페이스 인스턴스를 보내는 방법에 관계 없습니다.

public class PlayerManager { 
    ... 
    private SongChangedListener mListener; 
    ... 

    public PlayerManager() { 
    } 

    public void setListener(SongChangedListener listener) { 
     mListener = listener; 
    } 

    public interface SongChangedListener { 
     void songChanged(MediaId idOfSong); 
    } 

    ... 
    public void playSong() { 
     ... 
     if (mListener != null) 
      mListener.songChanged(idOfNextSong); 
     ... 
    } 

귀하의 답변에 여러 가지면에서 잘못된 느낌을주는 활동이 귀하의 서비스에 전달됩니다. 활동과 서비스 간의 통신을 구현하려는 경우이를 수행 할 수있는 여러 가지 방법이 있습니다. 일반적으로 Handler와 함께 Messenger를 사용합니다. 더 자세한 내용을 제공 하겠지만 문서 및 기타 답변에서 탐색하면 더 유용 할 것입니다. 메신저가 어떻게 작동하는지 이해하면 구현하기 쉽습니다.

또한 완전 완성 MediaPlayer 응용 프로그램을 찾고 있다면 구현시 더 많은 보일러 코드가 필요합니다. 또한 MediaButton 클릭 (누군가가 블루투스 헤드폰이나 시계에서 재생/일시 중지를 클릭 한 경우)을 처리해야합니다. 바람직하게는 MediaSessionCompat이 더 나은 구현입니다. android-UniversalMusicPlayer의 최소 필수 기능을 모두 구현 한 다음 소스 미디어 플레이어를 참조 할 수도 있습니다.

+0

() 내 주요 활동 수업에서. 나는 수동으로 노래를 바꿀 때 그것을 사용한다. 이 문제는 완료 후 MediaPlayer가 자동으로 다음 노래로 전환 할 때 발생합니다. songAdt를 알 수 없으므로 MediaPlayer 클래스에서 songAdt.notifyDataSetChanged()를 호출 할 수 없습니다. – PatriceG

+1

콜백을 추가하고, 미디어 플레이어 클래스에서 인터페이스를 만들고, songChanged() 메서드를 사용하십시오. mainActivity에서이 인터페이스를 구현하고 MediaPlayer 클래스에서 노래를 변경하면이 메서드가 호출되어 노래 변경이 ur mainActivity에 반영됩니다. 액티비티를 변경 사항에 알리기 위해 콜백과 함께 사용되는 꽤 일반적인 디자인입니다. – Roadblock

+1

U mainActivity의 인스턴스를 MediaPlayer 클래스에 전달해야합니다 (MediaPlayers 생성자 사용). 이 인스턴스를 사용하여 songChanged 메서드를 호출합니다. – Roadblock

0

음악 트랙 모델 클래스에서이 노래가 재생 모드에 있는지 여부를 나타내는 변수 하나를 유지 관리합니다.

getView()에서 해당 값을 확인하고 그에 따라 코딩하십시오.당신은 수동으로 실시 또는보기 자동 노래를 변경할 때마다

if(model.is_playing) 
    //change your code for playing song 
else 
    //rest songs which are not playing 

지금, 이전 트랙에서 그것을 해제, 그 is_playing 값을 변경하고 현재 트랙을 재생하도록 설정합니다.

+0

예,하지만 BaseAdapter를 새로 고쳐야합니까? 그것을하는 방법? – PatriceG

+0

목록을 업데이트 한 후에'notifyDatasetChanged()'를 사용할 수 있습니다. –

+0

제 문제는 노래가 변경되는 MusicPlayer 클래스에서 BaseAdapter를 모르는 것입니다. – PatriceG

0

고유 한 콜백 인터페이스를 구현할 필요가 없습니다. 재생 사운드가 종료되면 Mediaplayer는 이미 완성 된 리스너를 가지고 있습니다. 방금 oncompletion 방법의 의견에

public class MainActivity extends Activity implements MediaPlayerControl, MediaPlayer.OnCompletionListener{ 
    private MediaPlayer musicSrv; 
    private BaseAdapter songAdt; 


    @Override 
    public void onCreate() { 
     musicSrv.setOnCompletionListener(this); 
    } 

    @Override 
    public void onCompletion(MediaPlayer musicPlayer) { 
     songAdt.notifyDataSetChanged(); 
    } 
} 
+0

설명을 추가해주세요 귀하의 게시물, 무엇을 보여 주려고 왜 등등. – Mfusiki

+0

설명을 추가했습니다. –

관련 문제