2014-09-20 65 views
0

我正在爲我們的音樂學校開發一個Android應用程序。我設計了一個帶有列表視圖的佈局,每個列表視圖顯示了歌曲的細節,例如電影海報,電影名稱,歌曲名稱,發行年份,歌曲價格,播放/停止,查看示例,添加到/從購物車圖像視圖。列表視圖行的單獨控件在另一個列表視圖中受其他單獨控件的影響

佈局的屏幕截圖顯示在下面

![佈局屏幕顯示的歌曲列表] [1]

現在我想用戶聽到的點擊播放按鈕的歌曲的MP3版本。當歌曲正在播放時,我想將播放圖像更改爲停止圖像,併爲用戶提供停止歌曲的功能。

下面是一個包含列表視圖

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#F8AE9F" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@+id/textView1" 
     style="@style/aboutComposer" 
     android:layout_width="wrap_content" 
     android:layout_height="45sp" 
     android:layout_alignParentTop="true" 
     android:layout_centerHorizontal="true" 
     android:gravity="center_vertical|center_horizontal" 
     android:text="@string/msv_songs" 
     android:textAppearance="?android:attr/textAppearanceSmall" /> 

    <TextView 
     android:id="@+id/tvCartTotal" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/textView1" 
     android:layout_centerHorizontal="true" 
     android:text="@string/cart_total" 
     android:textAppearance="?android:attr/textAppearanceMedium" /> 

    <ImageView 
     android:id="@+id/imageView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/tvCartTotal" 
     android:layout_centerHorizontal="true" 
     android:layout_marginTop="14dp" 
     android:src="@drawable/icon_pay_now" /> 

    <ListView 
     android:id="@+id/lstMSVSongs" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/imageView1" 
     android:layout_centerHorizontal="true" 
     android:layout_marginTop="16dp" 
     android:focusable="false" > 

    </ListView> 

</RelativeLayout> 

下面是佈局代碼指定了如何將每首歌曲的細節都顯示

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/tvViewSample" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <ImageView 
     android:id="@+id/imgFilmPoster" 
     android:layout_width="75sp" 
     android:layout_height="75sp" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true" 
     android:src="@drawable/abc_ab_bottom_solid_dark_holo" /> 

    <TextView 
     android:id="@+id/tvSongName" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignLeft="@+id/tvFilmName" 
     android:layout_below="@+id/tvFilmName" 
     android:text="@string/dummy" 
     android:textAppearance="?android:attr/textAppearanceSmall" /> 

    <TextView 
     android:id="@+id/tvYearReleased" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignLeft="@+id/tvSongName" 
     android:layout_below="@+id/tvSongName" 
     android:text="@string/dummy" 
     android:textAppearance="?android:attr/textAppearanceSmall" /> 

    <TextView 
     android:id="@+id/tvPrice" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignLeft="@+id/tvYearReleased" 
     android:layout_below="@+id/tvYearReleased" 
     android:text="@string/dummy" 
     android:textAppearance="?android:attr/textAppearanceSmall" /> 

    <TextView 
     android:id="@+id/tvFilmName" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentTop="true" 
     android:layout_marginLeft="14dp" 
     android:layout_toRightOf="@+id/imgFilmPoster" 
     android:focusable="true" 
     android:text="@string/dummy" 
     android:textAppearance="?android:attr/textAppearanceSmall" /> 

    <ImageView 
     android:id="@+id/imgAddCart" 
     android:layout_width="35sp" 
     android:layout_height="35sp" 
     android:contentDescription="@string/add_to_cart" 
     android:layout_alignTop="@+id/imgView" 
     android:layout_toRightOf="@+id/imgView" 
     android:src="@drawable/add_to_cart" 
     android:tag = "@string/add_to_cart" /> 

    <ImageView 
     android:id="@+id/imgView" 
     android:layout_width="35sp" 
     android:layout_height="35sp" 
     android:layout_below="@+id/imgFilmPoster" 
     android:layout_marginTop="14dp" 
     android:layout_toRightOf="@+id/imgPlay" 
     android:src="@drawable/view_icon" /> 

    <ImageView 
     android:id="@+id/imgPlay" 
     android:layout_width="35sp" 
     android:layout_height="35sp" 
     android:layout_alignLeft="@+id/tvPrice" 
     android:layout_alignTop="@+id/imgView" 
     android:contentDescription="@string/play_mp3" 
     android:src="@drawable/play" /> 

</RelativeLayout> 

我儲存的每首歌曲的細節佈局文件代碼作爲類對象。下面是Song.class

package com.srindroid.indianmusicsheets; 
import java.io.File; 

public class Song { 

    private int filmImageID;  
    private String movieName; 
    private String songName; 
    private String yearReleased; 
    private int songPrice; 
    private int mp3File; 

    public Song(int filmImageID, String movieName, String songName, 
      String yearReleased, int songPrice, int mp3File) { 
     super(); 
     this.filmImageID = filmImageID; 
     this.movieName = movieName; 
     this.songName = songName; 
     this.yearReleased = yearReleased; 
     this.songPrice = songPrice; 
     this.mp3File = mp3File; 

    } 
    public int getFilmImageID() { 
     return filmImageID; 
    } 
    public String getMovieName() { 
     return movieName; 
    } 
    public String getSongName() { 
     return songName; 
    } 
    public String getYearReleased() { 
     return yearReleased; 
    } 
    public int getSongPrice() { 
     return songPrice; 
    } 
    public int getmp3File() { 
     return mp3File; 
    } 
    public void setFilmImageID(int filmImageID) { 
     this.filmImageID = filmImageID; 
    } 
    public void setMovieName(String movieName) { 
     this.movieName = movieName; 
    } 
    public void setSongName(String songName) { 
     this.songName = songName; 
    } 
    public void setYearReleased(String yearReleased) { 
     this.yearReleased = yearReleased; 
    } 
    public void setSongPrice(int songPrice) { 
     this.songPrice = songPrice; 
    }  
} 

下面的代碼是Java代碼來創建每行列表視圖

public class MsvSongs extends Activity { 

    int cart_total; 
    public MediaPlayer mp3Player=null; 
    private ArrayList<Song> msvSongs = new ArrayList<Song>(); 
    ListView songs; 

    @Override 
    protected void onStop(){ 
     if(mp3Player!=null && mp3Player.isPlaying()){ 
      mp3Player.stop(); 
      mp3Player.release(); 
      mp3Player=null; 
     }  
     super.onStop(); 
    } 

    @Override 
    protected void onPause(){ 
     if(mp3Player!=null && mp3Player.isPlaying()){ 
      mp3Player.pause(); 
     } 
     super.onPause(); 
    } 

    @Override 
    protected void onResume(){ 
     if(mp3Player!=null){ 
      mp3Player.start(); 
     } 
     super.onResume(); 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) {   
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.msv_music_sheets); 
     populateSongsList(); 
     populateSongsListView(); 
    } 



    private void populateSongsList() { 
     msvSongs.add(new Song(R.drawable.msv_ayirathil_oruvan,"Ayirathil Oruvan","Adho Andha Paravai Pola","1965",150,R.raw.msv_adho_andha_paravai_pola_ao)); 
     msvSongs.add(new Song(R.drawable.msv_karuppu_panam,"Karuppu Panam","Aadavaralaam","1964",150,R.raw.msv_aadavaralaam_kp)); 
     msvSongs.add(new Song(R.drawable.msv_paalum_pazhamum,"Paalum Paazhamum","Aalayamaniyin Oosai","1961",150,R.raw.msv_aalayamaniyin_oosai_pp)); 
     msvSongs.add(new Song(R.drawable.msv_paava_mannippu,"Paava Mannipu","Athaan Ennathan","1961",150,R.raw.msv_athaan_ennathaan_pm)); 
     msvSongs.add(new Song(R.drawable.msv_periya_idhuthu_pen,"Periya Idhuthu Pen","Andru Vandhadhadhum Adhey Nila","1963",175,R.raw.msv_andru_vandhadhum_adhey_nila_pip)); 
     msvSongs.add(new Song(R.drawable.msv_puthiya_paravai,"Pudhiya Paravai","Enge Nimmadhi","1964",250,R.raw.msv_enge_nimmadhi_pparavai)); 
     msvSongs.add(new Song(R.drawable.msv_server_sundaram,"Server Sundaram","Avalukku Enna Azhagiya Mugam","1964",150,R.raw.msv_avalukkenna_azhagiamugham_ss)); 
     msvSongs.add(new Song(R.drawable.msv_panam_padaithavan,"Panam Padaithavan","Kan Pona Pookiley","1965",175,R.raw.msv_kan_pona_pokkile_pp)); 
     msvSongs.add(new Song(R.drawable.msv_vasantha_maligai,"Vasantha Maligai","Mayakkam Enna","1972",120,R.raw.msv_mayakkam_yenna_vm)); 
    } 

    private void populateSongsListView() { 
     songs=(ListView) findViewById(R.id.lstMSVSongs); 
     BaseAdapter msvAdapter = new MsvSongsAdapter(MsvSongs.this, msvSongs); 
     songs.setAdapter(msvAdapter);  
    } 

    public class MsvSongsAdapter extends BaseAdapter{ 
     private LayoutInflater mInflater; 
     private List<Song> songs; 

     public MsvSongsAdapter(Context context, ArrayList<Song> msvSongs){ 
      mInflater = LayoutInflater.from(context); 
      songs = msvSongs; 
     } 

     @Override 
     public int getCount() { 
      // TODO Auto-generated method stub 
      return songs.size(); 
     } 

     @Override 
     public Object getItem(int position) { 
      // TODO Auto-generated method stub 
      return songs.get(position); 
     } 

     @Override 
     public long getItemId(int position) { 
      // TODO Auto-generated method stub 
      return position; 
     } 

     @Override 
     public View getView(final int position, View convertView, ViewGroup parent) { 
      View view; 
      final ViewHolder holder; 
      if(convertView == null) { 
       view = mInflater.inflate(R.layout.songs_view, parent, false); 
       holder = new ViewHolder(); 
       holder.filmPoster = (ImageView)view.findViewById(R.id.imgFilmPoster); 
       holder.filmName = (TextView)view.findViewById(R.id.tvFilmName); 
       holder.songName = (TextView)view.findViewById(R.id.tvSongName); 
       holder.yearReleased = (TextView)view.findViewById(R.id.tvYearReleased); 
       holder.songPrice = (TextView)view.findViewById(R.id.tvPrice); 
       holder.mp3 = (ImageView)view.findViewById(R.id.imgPlay); 
       view.setTag(holder); 
      } else { 
       view = convertView; 
       holder = (ViewHolder)view.getTag(); 
      } 

      Song currentSong = songs.get(position); 
      holder.filmPoster.setImageResource(currentSong.getFilmImageID()); 
      holder.filmName.setText(currentSong.getMovieName()); 
      holder.songName.setText(currentSong.getSongName()); 
      holder.yearReleased.setText(currentSong.getYearReleased()); 
      holder.songPrice.setText("Rs. "+currentSong.getSongPrice()); 

      holder.mp3.setOnClickListener(new View.OnClickListener() { 


       @Override 
       public void onClick(View v) { 
        String contentDesc = (String) holder.mp3.getContentDescription(); 
        if (contentDesc.contains("Play")) { 
         if (mp3Player != null && mp3Player.isPlaying()) { 
          Toast.makeText(MsvSongs.this, "Stop the previous song", Toast.LENGTH_SHORT).show(); 
         } else { 
          mp3Player = MediaPlayer.create(MsvSongs.this, songs.get(position).getmp3File()); 
          mp3Player.start(); 
          ((ImageView)v).setImageResource(R.drawable.stop); 
          ((ImageView)v).setContentDescription("Stop MP3"); 
         } 
        } else { 
         mp3Player.pause(); 
         mp3Player.stop(); 
         mp3Player.release(); 
         mp3Player = null; 
         ((ImageView)v).setImageResource(R.drawable.play); 
         ((ImageView)v).setContentDescription("Play MP3"); 
        } 

       } 
      });   

      return view; 
     } 

     private class ViewHolder { 
      public ImageView filmPoster, mp3; 
      public TextView filmName, songName, yearReleased, songPrice; 
     } 
    } 
} 

現在的問題我在這裏面對的是,當我點擊第一的播放按鈕歌曲在列表視圖中播放,它會播放相應的mp3文件,並按預期方式將「播放」圖標更改爲「停止」圖標。見下面

截圖![在這裏輸入的形象描述] [2]

但它也改變了播放圖標,停止其他歌曲的圖標列表中也是如此。見下面

截圖![在這裏輸入的形象描述] [3]

可否請你讓我知道是什麼原因造成這個問題?

感謝, 作者Srini

回答

1

你的問題是與OnClickListenerViewHoldergetView()方法將回收/重用視圖。意思是View在位置2以後可能最終會被重複使用6位。這意味着你的點擊偵聽2位被現在突然在6位

改變View拼接你OnClickListener,因爲它是在不同的嵌套類和唐不要讓ViewHolder最終。然後當你實例化OnClickListener傳遞沿ViewHolderSong。它更容易在代碼中顯示,所以這裏是一個簡單的例子:

private class OnSongClickListener implements OnClickListener { 
    private WeakReference<ViewHolder> mViewHolder; 
    private Song mSong; 

    public OnSongClickListener(ViewHolder vh, Song song) { 
     mViewHolder = new WeakReference<ViewHolder>(vh); 
     mSong = song; 
    } 

    @Override 
    public void onClick(View v) { 
     ViewHolder vh = mViewHolder.get(); 
     if (vh == null) { 
      return; 
     } 
     //Do your click logic here 
    } 
} 

您還需要你的getView()方法,以確保查看的根據自己當前的播放狀態被重置。例如:

Song currentSong = songs.get(position); 
holder.filmPoster.setImageResource(currentSong.getFilmImageID()); 
holder.filmName.setText(currentSong.getMovieName()); 
holder.songName.setText(currentSong.getSongName()); 
holder.yearReleased.setText(currentSong.getYearReleased()); 
holder.songPrice.setText("Rs. "+currentSong.getSongPrice()); 
holder.mp3.setOnClickListener(new OnSongClickListener(holder,currentSong)); 

if (currentSong is playing) { //You'll need a way to determine this 
    holder.mp3.setImageResource(R.drawable.play); 
    holder.mp3.setContentDescription("Play MP3"); 
} else { 
    holder.mp3.setImageResource(R.drawable.stop); 
    holder.mp3.setContentDescription("Stop MP3"); 
} 

return view; 
+0

嗨Jay Sover,謝謝你的迴應。我改變了代碼如下 – Srini 2014-09-20 11:56:58

+0

非常感謝。現在它適用於我。我在歌曲類中添加了一個布爾變量,並在播放歌曲時將其設置爲true。 – Srini 2014-09-23 02:06:59

+0

很高興我能幫到你。那麼你能接受這個答案嗎? – 2014-09-23 12:40:00