如何在列表视图中添加最近播放的歌曲?

Posted

技术标签:

【中文标题】如何在列表视图中添加最近播放的歌曲?【英文标题】:How to add recently played song in listview? 【发布时间】:2017-01-11 05:29:39 【问题描述】:

我是 android 开发的新手,目前我正在 android 中实现简单的音乐播放器应用程序。所以,我的问题是我在这个音乐播放器中使用片段,我想在另一个列表视图片段中添加最近播放的歌曲。

这是我的主要播放器片段类......

private ImageButton btnPlay;
private ImageButton btnForward;
private ImageButton btnBackward;
private ImageButton btnNext;
private ImageButton btnPrevious;
private ImageButton btnPlaylist;
private ImageButton btnRepeat;
private ImageButton btnShuffle;
private SeekBar songProgressBar;
private TextView songTitleLabel;
private TextView songCurrentDurationLabel;
private TextView songTotalDurationLabel;
// Media Player
private MediaPlayer mp;
VisualizerView mVisualizerView;
SliderView sl;
private Visualizer mVisualizer;
// Handler to update UI timer, progress bar etc,.
private Handler mHandler = new Handler();;
private SongsManager songManager;
private Utilities utils;
private int seekForwardTime = 5000; // 5000 milliseconds
private int seekBackwardTime = 5000; // 5000 milliseconds
private int currentSongIndex = 0;
private boolean isShuffle = false;
private boolean isRepeat = false;
private ArrayList<SongModel> songsList = new ArrayList<SongModel>();
int songIndex;
private AudioManager audioManager = null;
SongAdapter songAdapter;

public Player(int position) 
    songIndex = position;



@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) 

                        View android = inflater.inflate(R.layout.player, container, false);

                        super.onCreate(savedInstanceState);

    // variable initialization for button
    btnPlay = (ImageButton) android.findViewById(R.id.btnPlay);
    btnForward = (ImageButton) android.findViewById(R.id.btnForward);
    btnBackward = (ImageButton) android.findViewById(R.id.btnBackward);
    btnNext = (ImageButton) android.findViewById(R.id.btnNext);
    btnPrevious = (ImageButton) android.findViewById(R.id.btnPrevious);
    btnRepeat = (ImageButton) android.findViewById(R.id.btnRepeat);
    btnShuffle = (ImageButton) android.findViewById(R.id.btnShuffle);
    songProgressBar = (SeekBar) android.findViewById(R.id.songProgressBar);
    songTitleLabel = (TextView) android.findViewById(R.id.songTitle);
    songTitleLabel.setEllipsize(TextUtils.TruncateAt.MARQUEE);
    songTitleLabel.setSingleLine(true);
    songCurrentDurationLabel = (TextView)android.findViewById(R.id.songCurrentDurationLabel);
    songTotalDurationLabel = (TextView) android.findViewById(R.id.songTotalDurationLabel);
    mVisualizerView = (VisualizerView) android.findViewById(R.id.myvisualizerview);
    audioManager = (AudioManager)getActivity().getSystemService(Context.AUDIO_SERVICE);


    //get bundle data
    /*Bundle b = getArguments();
    int position = b.getInt("songIndex");
    Log.i("position...","...."+position);*/

    //Log.i("songIndex...","...."+);

    //sliding finger up and increase and decrease volume
    android.setOnTouchListener(new View.OnTouchListener() 
        public boolean onTouch(View v, MotionEvent event) 
            int action = MotionEventCompat.getActionMasked(event);
            if (action == MotionEvent.ACTION_MOVE) 
                // put your volume change logic here, for example compare previously recorded x/y position to new one and change volume
                audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 5, 0);
            
            return true;
        
    );
    //Visualizer method
    mp = new MediaPlayer();
    initAudio();

    // Mediaplayer

    songManager = new SongsManager();
    utils = new Utilities();

    // Listeners
    songProgressBar.setOnSeekBarChangeListener(this); // Important
    mp.setOnCompletionListener(this); // Important

    // Getting all songs list
    songsList = songManager.getPlayList();
    // By default play first song
    if (songIndex==0)
    
        playSong(0);
    
    else
    
        playSong(songIndex);
    
    btnPlay.setOnClickListener(new View.OnClickListener() 

        @Override
        public void onClick(View arg0) 
            // check for already playing
            if (mp.isPlaying()) 
                if (mp != null) 
                    mp.pause();
                    btnPlay.setImageResource(R.drawable.btn_play);
                
             else 
                // Resume song
                if (mp != null) 
                    mp.start();
                    btnPlay.setImageResource(R.drawable.btn_pause);
                
            

        
    );
    btnForward.setOnClickListener(new View.OnClickListener() 

        @Override
        public void onClick(View arg0) 
            int currentPosition = mp.getCurrentPosition();
            if(currentPosition + seekForwardTime <= mp.getDuration())
                mp.seekTo(currentPosition + seekForwardTime);
            else
                mp.seekTo(mp.getDuration());
            
        
    );
    btnBackward.setOnClickListener(new View.OnClickListener() 

        @Override
        public void onClick(View arg0) 
            int currentPosition = mp.getCurrentPosition();
            if(currentPosition - seekBackwardTime >= 0)
                mp.seekTo(currentPosition - seekBackwardTime);
            else
                mp.seekTo(0);
            

        
    );
    btnNext.setOnClickListener(new View.OnClickListener() 

        @Override
        public void onClick(View arg0) 
            if(currentSongIndex < (songsList.size() - 1))
                playSong(currentSongIndex + 1);
                currentSongIndex = currentSongIndex + 1;
            else
                playSong(0);
                currentSongIndex = 0;
            

        
    );
    btnPrevious.setOnClickListener(new View.OnClickListener() 

        @Override
        public void onClick(View arg0) 
            if(currentSongIndex > 0)
                playSong(currentSongIndex - 1);
                currentSongIndex = currentSongIndex - 1;
            else
                playSong(songsList.size() - 1);
                currentSongIndex = songsList.size() - 1;
            

        
    );
    btnRepeat.setOnClickListener(new View.OnClickListener() 

        @Override
        public void onClick(View arg0) 
            if(isRepeat)
                isRepeat = false;
                Toast.makeText(getActivity().getApplicationContext(), "Repeat is OFF", Toast.LENGTH_SHORT).show();
                btnRepeat.setImageResource(R.drawable.btn_repeat);
            else
                isRepeat = true;
                Toast.makeText(getActivity().getApplicationContext(), "Repeat is ON", Toast.LENGTH_SHORT).show();
                isShuffle = false;
                btnRepeat.setImageResource(R.drawable.btn_repeat_focused);
                btnShuffle.setImageResource(R.drawable.btn_shuffle);
            
        
    );
    btnShuffle.setOnClickListener(new View.OnClickListener() 

        @Override
        public void onClick(View arg0) 
            if(isShuffle)
                isShuffle = false;
                Toast.makeText(getActivity().getApplicationContext(), "Shuffle is OFF", Toast.LENGTH_SHORT).show();
                btnShuffle.setImageResource(R.drawable.btn_shuffle);
            else
                isShuffle= true;
                Toast.makeText(getActivity().getApplicationContext(), "Shuffle is ON", Toast.LENGTH_SHORT).show();
                isRepeat = false;
                btnShuffle.setImageResource(R.drawable.btn_shuffle_focused);
                btnRepeat.setImageResource(R.drawable.btn_repeat);
            
        
    );
    return android;



private void initAudio() 
    getActivity().setVolumeControlStream(AudioManager.STREAM_MUSIC);
    mp = MediaPlayer.create(getActivity(),R.raw.test);
    mp.setLooping(true);
    setupVisualizerFxAndUI();
    mVisualizer.setEnabled(true);
    mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() 
        public void onCompletion(MediaPlayer mediaPlayer) 
            mVisualizer.setEnabled(false);
        
    );
    mp.start();


private void setupVisualizerFxAndUI() 
    mVisualizer = new Visualizer(mp.getAudiosessionId());
    mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
    mVisualizer.setDataCaptureListener(
            new Visualizer.OnDataCaptureListener() 
                public void onWaveFormDataCapture(Visualizer visualizer,
                                                  byte[] bytes, int samplingRate) 
                    mVisualizerView.updateVisualizer(bytes);
                

                public void onFftDataCapture(Visualizer visualizer,
                                             byte[] bytes, int samplingRate) 
                
            , Visualizer.getMaxCaptureRate() / 2, true, false);


@Override
public void onActivityResult(int requestCode,
                             int resultCode, Intent data) 
    super.onActivityResult(requestCode, resultCode, data);
    if(resultCode == 100)
        currentSongIndex = data.getExtras().getInt("songIndex");
        // play selected song
        playSong(currentSongIndex);
    


public void playSong(int songIndex)
    try 
        mp.reset();
        mp.setDataSource(songsList.get(songIndex).getSongPath());
        mp.prepare();
        mp.start();
        String songTitle = songsList.get(songIndex).getSongTitle();
        songTitleLabel.setText(songTitle);

        btnPlay.setImageResource(R.drawable.btn_pause);
        songProgressBar.setProgress(0);
        songProgressBar.setMax(100);
        updateProgressBar();
     catch (IllegalArgumentException e) 
        e.printStackTrace();
     catch (IllegalStateException e) 
        e.printStackTrace();
     catch (IOException e) 
        e.printStackTrace();
    

private void updateProgressBar() 
    mHandler.postDelayed(mUpdateTimeTask,100);

private Runnable mUpdateTimeTask = new Runnable() 
    public void run() 
        long totalDuration = mp.getDuration();
        long currentDuration = mp.getCurrentPosition();

        songTotalDurationLabel.setText(""+utils.milliSecondsToTimer(totalDuration));

        songCurrentDurationLabel.setText(""+utils.milliSecondsToTimer(currentDuration));


        int progress = (int)(utils.getProgressPercentage(currentDuration, totalDuration));

        songProgressBar.setProgress(progress);

        mHandler.postDelayed(this,100);
    
;

@Override
public void onCompletion(MediaPlayer mp) 
    if(isRepeat)
        playSong(currentSongIndex);
     else if(isShuffle)
        Random rand = new Random();
        currentSongIndex = rand.nextInt((songsList.size() - 1) - 0 + 1) + 0;
        playSong(currentSongIndex);
     else
        if(currentSongIndex < (songsList.size() - 1))
            playSong(currentSongIndex + 1);
            currentSongIndex = currentSongIndex + 1;
        else
            playSong(0);
            currentSongIndex = 0;
        
    


@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) 



@Override
public void onStartTrackingTouch(SeekBar seekBar) 
    mHandler.removeCallbacks(mUpdateTimeTask);


@Override
public void onStopTrackingTouch(SeekBar seekBar) 
    mHandler.removeCallbacks(mUpdateTimeTask);
    int totalDuration = mp.getDuration();
    int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration);

    mp.seekTo(currentPosition);
    updateProgressBar();

@Override
public void onDestroy() 
    super.onDestroy();
    mHandler.removeCallbacks(mUpdateTimeTask);
    if (mp != null) 
        if (mp.isPlaying()) mp.stop();
        mp.reset();
        mp.release();
    

public void onBackPressed() 

    new AlertDialog.Builder(getActivity())
            .setIcon(R.drawable.musiclogo)
            .setTitle("Closing M-Player")
            .setMessage("Are you sure you want to close this application?")
            .setPositiveButton("Yes", new DialogInterface.OnClickListener()
            

                public void onClick(DialogInterface dialog, int which) 
                    getActivity().finish();
                

            )
            .setNegativeButton("No",null)
            .show();

这是我的播放列表(歌曲列表)片段和扩展列表片段

EditText edtSearch;
ListAdapter adapter;
SongAdapter songAdapter;
ArrayList<SongModel> songList = new ArrayList<SongModel>();
SongsManager songsManager = new SongsManager();

// Songs list
public ArrayList<SongModel> songsList = new ArrayList<>();
 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) 
     View windows = inflater.inflate(R.layout.playlist, container, false);
     return windows;


@Override
public void onViewCreated(View v, Bundle savedInstanceState) 
    super.onViewCreated(v, savedInstanceState);

    edtSearch = (EditText)getView().findViewById(R.id.search);
    final ArrayList<SongModel> songsListData = songsManager.songList;
    Log.i("songsListData...",""+songsListData.size());
    SongsManager plm = new SongsManager();

    // get all songs from sdcard
    this.songsList = plm.getPlayList();

    // looping through playlist
    for (int i = 0; i < songsListData.size(); i++) 
        // creating new HashMap
        SongModel song = songsListData.get(i);

        // adding HashList to ArrayList
        songsListData.add(song);
    
    // Adding menuItems to ListView
   /* adapter = new SimpleAdapter(getActivity(), songsListData, R.layout.playlist_item, new String[]  "songTitle" , new int[] 
            R.id.songTitle );*/

    songAdapter = new SongAdapter(getActivity(),songsList);
    setListAdapter(songAdapter);
    // selecting single ListView item
    final ListView lv = getListView();

    // listening to single listitem click
    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() 

        @Override
        public void onItemClick(AdapterView<?> parent, View arg0,
                                int position, long id) 

            // getting listitem index
            Log.i("Index", "..." + position);
            // Starting new intent
            Intent i = new Intent(getActivity().getApplicationContext(),Main.class);
            SongModel songModel = (SongModel) songAdapter.getItem(position);
            int indexOfSong = songAdapter.songsList.indexOf(songModel);
            // Sending songIndex to PlayerActivity
            i.putExtra("songIndex", indexOfSong);
            getActivity().setResult(100, i);
            startActivityForResult(i, 100);

        
    );
    edtSearch.addTextChangedListener(new TextWatcher() 
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) 

        
        @Override
        public void onTextChanged(CharSequence cs, int start, int before, int count) 

        
        @Override
        public void afterTextChanged(Editable s) 
            String text = edtSearch.getText().toString().toLowerCase(Locale.getDefault());
            songAdapter.filter(text);
        
    );

这是我的歌曲管理器课程。

public ArrayList<SongModel> songList = new ArrayList<SongModel>();
// SDCard Path
final String MEDIA_PATH = new String("/sdcard/");

// Constructor
public SongsManager()




public ArrayList<SongModel> getPlayList()
    File home = new File(MEDIA_PATH);

    if (home.listFiles(new FileExtensionFilter()).length > 0) 
        for (File file : home.listFiles(new FileExtensionFilter())) 
            SongModel setter = new SongModel();
            setter.setSongPath(file.getPath());
            setter.setSongTitle(file.getName().substring(0, (file.getName().length() - 4)));

            songList.add(setter);
        
    
    return songList;

class FileExtensionFilter implements FilenameFilter 
    public boolean accept(File dir, String name) 
        return (name.endsWith(".mp3") || name.endsWith(".MP3"));
    

这是我的歌曲适配器和扩展基本适配器。

Context context;
//private ArrayList<SongModel> songsList = null;
SongAdapter songAdapter;
private ArrayList<SongModel> songsListDat = null;
public ArrayList<SongModel> songsList;
private static LayoutInflater inflater;

public SongAdapter(FragmentActivity activity, ArrayList<SongModel> songsListDat) 

    this.context = activity;
    this.songsListDat = songsListDat;
    this.songsList = new ArrayList<SongModel>();
    this.songsList.addAll(songsListDat);



@Override
public int getViewTypeCount() 

    return getCount();


@Override
public int getCount() 
    return songsListDat.size();


@Override
public Object getItem(int position) 
    return songsListDat.get(position);


@Override
public long getItemId(int position) 
    return position;


@Override
public int getItemViewType(int position) 

    return position;


@Override
public View getView(int position, View convertView, ViewGroup parent) 
    inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View vi = convertView;
    if (convertView == null)
        vi = inflater.inflate(R.layout.playlist_item, null);

    TextView title = (TextView) vi.findViewById(R.id.songTitle); // title
    SongModel song = new SongModel();
    song = songsListDat.get(position);
    // Setting all values in listview
    title.setText(song.getSongTitle());

    return vi;

如果有人知道这其中的逻辑,请帮助我。 提前致谢

【问题讨论】:

【参考方案1】:

我终于做到了。这是我对此逻辑的更改

我创建了一个 Utility 常量类并全局传递这个数组列表。

public static ArrayList<SongModel> recentSongList = new ArrayList<SongModel>();

这是我的播放列表类,用于将点击的列表视图项发送到另一个列表视图

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() 

        @Override
        public void onItemClick(AdapterView<?> parent, View arg0,
                                int position, long id) 

            Log.i("Index", "..." + position);
            songAdapter.setSelectedIndex(position);
            Intent i = new Intent(getActivity().getApplicationContext(),Main.class);
            SongModel songModel = (SongModel) songAdapter.getItem(position);
            int indexOfSong = songAdapter.songsList.indexOf(songModel);

            // Sending songIndex to PlayerActivity
            i.putExtra("songIndex", indexOfSong);
            getActivity().setResult(100, i);
            startActivityForResult(i, 100);

            //putting song in recentSongList arraylist
            SongModel model = (SongModel) songAdapter.getItem(position);
            model.setSongTitle(songModel.getSongTitle());
            model.setSongPath(songModel.getSongPath());
            Constant.recentSongList.add(model);
            Log.i("recentSongList...","..."+Constant.recentSongList.size());
        
    );

这是我最近的播放列表片段,用于在列表视图中获取最近点击播放的歌曲

public class SingleItemView extends ListFragment
SongAdapter songAdapter;
SongsManager songsManager = new SongsManager();
public ArrayList<SongModel> songsList = new ArrayList<>();
public ArrayList<SongModel> recentSongList = Constant.recentSongList;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) 

    View windows = inflater.inflate(R.layout.recent_playlist, container, false);
    Log.i("recent Song List...","..."+recentSongList.size());
    return windows;

@Override
public void onViewCreated(View v, Bundle savedInstanceState) 
    super.onViewCreated(v, savedInstanceState);

    final ArrayList<SongModel> songsListData = songsManager.songList;
    Log.i("songsListData...", "" + songsListData.size());
    songAdapter = new SongAdapter(getActivity(),recentSongList);
    setListAdapter(songAdapter);

    final ListView lv = getListView();
    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() 
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) 

        
    );

【讨论】:

以上是关于如何在列表视图中添加最近播放的歌曲?的主要内容,如果未能解决你的问题,请参考以下文章

从列表视图的顶部到底部拖动项目时如何提高速度?

如何让 avaudioplayer 在点击新闻歌曲时停止播放上一首歌曲?

如何在 Flutter 的 ListView 中添加列?

如何在保留 onClickListener 的同时将菜单按钮添加到列表视图?

当我单击媒体播放器中的列表视图时,正在播放多首歌曲

Xamarin 表单列表视图添加幻灯片功能