SuRaj Creator SuRaj Creator - 4 months ago 23
Android Question

Viewpager sound not synchronised with image

So basically i want to play a short sound when user swipes the images. There are number of images & sound i taken in this. Sound is playing fine But my problem is here my sound is not matches the image. May be i think i have not implemented OnPageChangeListener in my code. Can any one help me in this how do i implement this code..

package com.android.learning_numbers;

import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

public class Numbers extends Activity {

public class serv extends Service{

MediaPlayer mp;
public IBinder onBind1(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public void onCreate()
{
mp = MediaPlayer.create(this, R.raw.jingle);
mp.setLooping(true);
}
public void onDestroy()
{
mp.stop();
}
public void onStart(Intent intent,int startid){

String tag = null;
Log.d(tag, "On start");
mp.start();
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}

public static MediaPlayer mp = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_numbers);
ViewPager viewPager = (ViewPager)findViewById(R.id.view_pager);
ImagePagerAdapter adapter = new ImagePagerAdapter();
viewPager.setAdapter(adapter);
}

private class ImagePagerAdapter extends PagerAdapter {

private int[] mImages = new int[]{R.drawable.no1,R.drawable.no2,R.drawable.no3,R.drawable.no4,R.drawable.no5,R.drawable.no6,R.drawable.no7,R.drawable.no8,R.drawable.no9,};
private int[] mAudio= new int[]{R.raw.one,R.raw.two,R.raw.three,R.raw.four,R.raw.five,R.raw.six,R.raw.seven,R.raw.eight,R.raw.nine};
@Override
public int getCount() {
return mImages.length;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == ((ImageView) object);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Context context = Numbers.this;
ImageView imageView = new ImageView(context);
int padding =context.getResources().
getDimensionPixelSize(R.dimen.activity_vertical_margin);
imageView.setPadding(padding, padding, padding, padding);
imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setImageResource(mImages[position]);
((ViewPager) container).addView(imageView, 0);

//for Sound
if (mp != null) {
mp.reset();
mp.release();
}

//the audio files are running here but not in sync with image
mp = MediaPlayer.create(Numbers.this,mAudio[position]);
mp.start();

return imageView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((ImageView) object);
}
}
}


Here how do i use OnPageChangeListener??

Answer

Your problem is that you're playing the sound whenever you are creating an item, which may not necessarily be the same as when you change to an item. You can use the OnPageChangeListener by defining it in your class like this:

public OnPageChangeListener mOnPageListener = new OnPageChangeListener() {

    @Override public void onPageSelected(int position) {
        //for Sound 
        if (mp != null) {
            mp.reset();
            mp.release();
        }

        //the audio files are running here but not in sync with image
        mp = MediaPlayer.create(Numbers.this, mAudio[position]);
        mp.start();

    }
    @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
    @Override public void onPageScrollStateChanged(int state) {}

};

Then you just need to attach it to your ViewPager:

viewPager.setOnPageChangeListener(mOnPageListener);

I also recommend you not recreate your MediaPlayer every time, and instead cache it for each page.