0

I am making a media playing app with lyrics in listview, the listview scrolls as the media progresses, Now I want that the current playing verse be highlighted in the listview with a different color. So I use the following code inside a handler, however I am getting a NPE.

if(mediaPlayer.getCurrentPosition()/1000 > 0 && mediaPlayer.getCurrentPosition()/1000 < 20){
                            listView.smoothScrollToPosition(3);
                            View element = listView.getChildAt(3);
                            element.setBackgroundColor(0xff0000ff);

Complete code

public class MainActivity extends Activity {

    TextView T,S1;
    MediaPlayer mediaPlayer;
    ScrollView sv;
    SeekBar seek_bar;
    boolean lang = true; 
    Typeface tf;
    String [] LyricsE; 
    String [] LyricsH; 
    ListView listView;
    Button b;
    private ArrayAdapter dataAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.stair);
        //mediaPlayer.start();
        LyricsE =  new String [] {"","","",getResources().getString(R.string.V1E),getResources().getString(R.string.V2E),
                getResources().getString(R.string.V3E),
                getResources().getString(R.string.V4E),getResources().getString(R.string.V4E),getResources().getString(R.string.V5E),
                getResources().getString(R.string.V6E),getResources().getString(R.string.V7E),getResources().getString(R.string.V8E),
                getResources().getString(R.string.V9E),getResources().getString(R.string.V10E),getResources().getString(R.string.V11E),
                getResources().getString(R.string.V12E),getResources().getString(R.string.V13E),getResources().getString(R.string.V14E),
                getResources().getString(R.string.V15E),getResources().getString(R.string.V16E),getResources().getString(R.string.V17E),
                getResources().getString(R.string.V18E),getResources().getString(R.string.V19E),getResources().getString(R.string.V20E),
                getResources().getString(R.string.V21E),getResources().getString(R.string.V22E),getResources().getString(R.string.V23E),
                getResources().getString(R.string.V24E),getResources().getString(R.string.V25E),getResources().getString(R.string.V26E),
                getResources().getString(R.string.V27E),getResources().getString(R.string.V28E),getResources().getString(R.string.V29E),
                getResources().getString(R.string.V30E),getResources().getString(R.string.V31E),getResources().getString(R.string.V32E),
                getResources().getString(R.string.V33E),getResources().getString(R.string.V34E),getResources().getString(R.string.V35E),
                getResources().getString(R.string.V36E),getResources().getString(R.string.V37E),getResources().getString(R.string.V38E),
                getResources().getString(R.string.V39E),getResources().getString(R.string.V40E),getResources().getString(R.string.V41E),
                getResources().getString(R.string.V42E)};

        LyricsH = new String[] {"","","",getResources().getString(R.string.V1H),getResources().getString(R.string.V2H),
                getResources().getString(R.string.V3H),
                getResources().getString(R.string.V4H),getResources().getString(R.string.V4H),getResources().getString(R.string.V5H),
                getResources().getString(R.string.V6H),getResources().getString(R.string.V7H),getResources().getString(R.string.V8H),
                getResources().getString(R.string.V9H),getResources().getString(R.string.V10H),getResources().getString(R.string.V11H),
                getResources().getString(R.string.V12H),getResources().getString(R.string.V13H),getResources().getString(R.string.V14H),
                getResources().getString(R.string.V15H),getResources().getString(R.string.V16H),getResources().getString(R.string.V17H),
                getResources().getString(R.string.V18H),getResources().getString(R.string.V19H),getResources().getString(R.string.V20H),
                getResources().getString(R.string.V21H),getResources().getString(R.string.V22H),getResources().getString(R.string.V23H),
                getResources().getString(R.string.V24H),getResources().getString(R.string.V25H),getResources().getString(R.string.V26H),
                getResources().getString(R.string.V27H),getResources().getString(R.string.V28H),getResources().getString(R.string.V29H),
                getResources().getString(R.string.V30H),getResources().getString(R.string.V31H),getResources().getString(R.string.V32H),
                getResources().getString(R.string.V33H),getResources().getString(R.string.V34H),getResources().getString(R.string.V35H),
                getResources().getString(R.string.V36H),getResources().getString(R.string.V37H),getResources().getString(R.string.V38H),
                getResources().getString(R.string.V39H),getResources().getString(R.string.V40H),getResources().getString(R.string.V41H),
                getResources().getString(R.string.V42H)};



        String fontPath = "fonts/DroidSansDevanagari-Regular.ttf";
        tf = Typeface.createFromAsset(getAssets(), fontPath);

        mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.stair);
        b = (Button)findViewById(R.id.button1);
        Button L = (Button)findViewById(R.id.button2); 
        L.setOnClickListener(Lang); 
        b.setOnClickListener(on); 
        T = (TextView)findViewById(R.id.textView1);
        S1 = (TextView)findViewById(R.id.textView2);
        seek_bar =(SeekBar)findViewById(R.id.seekBar1); 
        listView = (ListView) findViewById(R.id.listView1);
        if(lang){
            //ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list,R.id.textView2, LyricsE);
            //listView.setAdapter(adapter);
            dataAdapter = new arrayAdapter(MainActivity.this, LyricsE);

            listView.setAdapter(dataAdapter);
        }
        if(!lang){
            //ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list,R.id.textView2, LyricsH);
            //listView.setAdapter(adapter);

            dataAdapter = new arrayAdapter(MainActivity.this, LyricsH);

            listView.setAdapter(dataAdapter);

        }

    }

    private View.OnClickListener on = new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            boolean flag = true; 
            int B = 0; 
            //  mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.stair);

            if(mediaPlayer.isPlaying()){

                mediaPlayer.pause();
                B = mediaPlayer.getCurrentPosition();
                flag = false; 
                b.setText("Play"); 
                System.out.println("in is.playing"); 
            }else if(!flag && !mediaPlayer.isPlaying()){
                mediaPlayer.seekTo(B); 
                b.setText("Pause"); 
                System.out.println("in flag and !playing"); 
            }




            else{
                b.setText("Pause"); 
                System.out.println("Normal execution"); 

                //listView = (ListView) findViewById(R.id.listView1);
                //  mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.stair);
                mediaPlayer.start();
                seek_bar.setMax(mediaPlayer.getDuration());


                seek_bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

                    @Override
                    public void onStopTrackingTouch(SeekBar seekBar) {

                    }

                    @Override
                    public void onStartTrackingTouch(SeekBar seekBar) {

                    }

                    @Override
                    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {                
                        if(mediaPlayer != null && fromUser){

                            mediaPlayer.seekTo(progress);
                        }
                    }

                });




                final Handler handler = new Handler();
                handler.post(new Runnable(){

                    @Override
                    public void run(){
                        int X = mediaPlayer.getCurrentPosition();
                        S1.setText(""+X);
                        setProgressText();
                        seek_bar.setProgress(mediaPlayer.getCurrentPosition());
                            if(mediaPlayer.getCurrentPosition()/1000 > 0 && mediaPlayer.getCurrentPosition()/1000 < 20){
                            //listView.smoothScrollToPosition(3);
                            //View element = listView.getChildAt(3);
                            //element.setBackgroundColor(Color.YELLOW);
                            System.out.println("FIrst if");


                                int wantedPosition = 3; 
                                int firstPosition = listView.getFirstVisiblePosition() - listView.getHeaderViewsCount(); // This is the same as child #0
                                int wantedChild = wantedPosition - firstPosition;
                                // Say, first visible position is 8, you want position 10, wantedChild will now be 2
                                // So that means your view is child #2 in the ViewGroup:
                                if (wantedChild < 0 || wantedChild >= listView.getChildCount()) {
                                 System.out.println( "Unable to get view for desired position, because it's not being displayed on screen.");
                                  return;
                                }
                                listView.smoothScrollToPosition(wantedChild);
                                View wantedView = listView.getChildAt(wantedChild);
                                wantedView.setBackgroundColor(Color.YELLOW);





                        }else if(mediaPlayer.getCurrentPosition()/1000 > 20 && mediaPlayer.getCurrentPosition()/1000 < 54){
                        //  listView.smoothScrollToPosition(4);
                        //  View element = listView.getChildAt(4);
                        //  element.setBackgroundColor(Color.YELLOW);
                            System.out.println("2 if");


                            int wantedPosition = 4; 
                            int firstPosition = listView.getFirstVisiblePosition() - listView.getHeaderViewsCount(); // This is the same as child #0
                            int wantedChild = wantedPosition - firstPosition;
                            // Say, first visible position is 8, you want position 10, wantedChild will now be 2
                            // So that means your view is child #2 in the ViewGroup:
                            if (wantedChild < 0 || wantedChild >= listView.getChildCount()) {
                             System.out.println( "Unable to get view for desired position, because it's not being displayed on screen.");
                              return;
                            }
                            listView.smoothScrollToPosition(wantedChild);
                            View wantedView = listView.getChildAt(wantedChild);
                            wantedView.setBackgroundColor(Color.YELLOW);








                        }else if(mediaPlayer.getCurrentPosition()/1000 > 54 && mediaPlayer.getCurrentPosition()/1000 < 67){
                            //listView.smoothScrollToPosition(5);
                            //View element = listView.getChildAt(5);
                            //element.setBackgroundColor(Color.YELLOW);
                            System.out.println("3 if");


                            int wantedPosition = 5; 
                            int firstPosition = listView.getFirstVisiblePosition() - listView.getHeaderViewsCount(); // This is the same as child #0
                            int wantedChild = wantedPosition - firstPosition;
                            // Say, first visible position is 8, you want position 10, wantedChild will now be 2
                            // So that means your view is child #2 in the ViewGroup:
                            if (wantedChild < 0 || wantedChild >= listView.getChildCount()) {
                             System.out.println( "Unable to get view for desired position, because it's not being displayed on screen.");
                              return;
                            }
                            listView.smoothScrollToPosition(wantedChild);
                            View wantedView = listView.getChildAt(wantedChild);
                            wantedView.setBackgroundColor(Color.YELLOW);






                        }else if(mediaPlayer.getCurrentPosition()/1000 > 67 && mediaPlayer.getCurrentPosition()/1000 < 75){
                            listView.smoothScrollToPosition(6);
                            System.out.println("4 if");
                        }else if(mediaPlayer.getCurrentPosition()/1000 > 20 && mediaPlayer.getCurrentPosition()/1000 < 54){
                            listView.smoothScrollToPosition(7);
                            System.out.println("5 if");
                        }else if(mediaPlayer.getCurrentPosition()/1000 > 20 && mediaPlayer.getCurrentPosition()/1000 < 54){
                            listView.smoothScrollToPosition(8);
                            System.out.println("6 if");
                        }else if(mediaPlayer.getCurrentPosition()/1000 > 20 && mediaPlayer.getCurrentPosition()/1000 < 54){
                            listView.smoothScrollToPosition(9);
                            System.out.println("7 if");
                        }else if(mediaPlayer.getCurrentPosition()/1000 > 20 && mediaPlayer.getCurrentPosition()/1000 < 54){

                        } 


                        handler.postDelayed(this, 1000L);

                    }
                });
            }
        }
    }; 


    protected void setProgressText() {
        String X ;
        final int HOUR = 60*60*1000;
        final int MINUTE = 60*1000;
        final int SECOND = 1000;

        int durationInMillis = mediaPlayer.getDuration();
        int curVolume = mediaPlayer.getCurrentPosition();

        int durationHour = durationInMillis/HOUR;
        int durationMint = (durationInMillis%HOUR)/MINUTE;
        int durationSec = (durationInMillis%MINUTE)/SECOND;

        int currentHour = curVolume/HOUR;
        int currentMint = (curVolume%HOUR)/MINUTE;
        int currentSec = (curVolume%MINUTE)/SECOND;

        if(durationHour>0){
            X = (""+String.format("%02d:%02d:%02d/%02d:%02d:%02d", 
                    currentHour,currentMint,currentSec, durationHour,durationMint,durationSec));            
        }else{
            X = (""+String.format("%02d:%02d/%02d:%02d", 
                    currentMint,currentSec, durationMint,durationSec));
        }


        // Toast.makeText(getApplicationContext(), ""+X, 10000); 
        T = (TextView)findViewById(R.id.textView1);
        T.setText(""+X);
    }

    private View.OnClickListener Lang = new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            ListView listView = (ListView) findViewById(R.id.listView1);
            String [] Change; 
            int index = listView.getFirstVisiblePosition();
            View v1 = listView.getChildAt(0);
            int top = (v1 == null) ? 0 : v1.getTop();

            if(lang){

                Change = LyricsH; 
                lang = false;
            }
            else{
                Change = LyricsE; 



                lang = true; 
            }
            /*  ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, R.layout.list,R.id.textView2, Change);
            listView.setAdapter(adapter);
            listView.setSelectionFromTop(index, top); */

            dataAdapter = new arrayAdapter(MainActivity.this, Change);

            listView.setAdapter(dataAdapter);
            listView.setSelectionFromTop(index, top);


        }
    };


    public boolean fontMag(){
        return lang; 
    }







    public class arrayAdapter extends ArrayAdapter<String[]> {
        private final Context context;
        private final String[] lyrics;
        public arrayAdapter(Context context, String[]lyrics ) {
            super(context, R.layout.list);
            this.context = context;
            this.lyrics = lyrics; 

        }
        public int getCount() {
            return lyrics.length;

        }

        public String[] getItem(int position) {

            return (lyrics);
        }


        public long getItemId(int arg0) {

            return arg0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);



            if (convertView == null) { 
                convertView = inflater.inflate(R.layout.list, parent, false); 
            }
            TextView textView = ((TextView) convertView.findViewById(R.id.textView2));
            textView.setText(lyrics[position]);






            return convertView;
        }
    } 

}

Any pointers where I might be going wrong?

Heretic Monk
  • 397
  • 1
  • 5
  • 19

1 Answers1

1

Null Pointer Exception must be caused because your view is not inflated properly.. Please post logcat details...

Also a better way to achieve what you want will be do this

    int wantedPosition = 10; // Whatever position you're looking for
    int firstPosition = listView.getFirstVisiblePosition() - listView.getHeaderViewsCount(); // This is the same as child #0
    int wantedChild = wantedPosition - firstPosition;
    // Say, first visible position is 8, you want position 10, wantedChild will now be 2
    // So that means your view is child #2 in the ViewGroup:
    if (wantedChild < 0 || wantedChild >= listView.getChildCount()) {
      Log.w(TAG, "Unable to get view for desired position, because it's not being displayed on screen.");
      return;
    }
    // Could also check if wantedPosition is between listView.getFirstVisiblePosition() and listView.getLastVisiblePosition() instead.
    View wantedView = listView.getChildAt(wantedChild);

See this link

Community
  • 1
  • 1
Augustus Francis
  • 2,694
  • 4
  • 22
  • 32
  • Thanks, I am trying this. – Heretic Monk Sep 21 '13 at 10:48
  • Can you elaborate more on wantedPosition? is it the position I want to scroll to. – Heretic Monk Sep 21 '13 at 10:55
  • Yes..wantedPostion :-Position you want to set the color.. Give it a try..:) – Augustus Francis Sep 21 '13 at 10:58
  • It does work but the list jitters when it processes the other if conditions after the one I have specified. – Heretic Monk Sep 21 '13 at 11:04
  • I have a volley of if else conditions in a handler, which executes every 1000ms. in these if statements I check the progress of the mediaplayer, and based on the progress I have to highlight a certain row in the listview which corresponds to the time in song. When the code above is executed, the first row gets positioned at the top of the listview and is highlighted but when its the turn for the second row, it scrolls to the first but afterwards the previous row scrolls down again and this continues. – Heretic Monk Sep 21 '13 at 11:44
  • "but afterwards the previous row scrolls down again and this continues." ? – Augustus Francis Sep 21 '13 at 11:48
  • PS:Say, first visible position is 8, you want position 10, wantedChild will now be 2.So that means your view is child #2 in the ViewGroup. Does that help.. – Augustus Francis Sep 21 '13 at 11:55
  • By previous row I mean, The row which was first highlighted. – Heretic Monk Sep 21 '13 at 11:55