Mediaplayer响应第二次点击暂停
Posted
技术标签:
【中文标题】Mediaplayer响应第二次点击暂停【英文标题】:Mediaplayer respond to second click to pause 【发布时间】:2017-12-13 08:16:44 【问题描述】:使用ViewPager进行图片滑动,每张图片点击流不同的MP3。
应用程序包括 50 个页面(图像)和 50 种不同的 mp3,所有 mp3 都存储在应用程序本身上。
例如。第一页流 MP3(一),第二页流 MP3(二),依此类推,直到第 50 页。
第一:
它工作正常只有一个问题是:
In any page --> clicking the image -->
PLAY MP3(one) --> click again--> PAUSE MP3 -->
in paused state of MP3(one) SWIPE to next page -->
--> in next page --> clicking the image -->
PLAY MP3(two) --> click to pause the MP3(two)
--> it doesn't respond to first click,it respond to second click to pause MP3(two).
第二次:
该应用程序包含 50 个页面和 50 个不同的 MP3,我是否需要重复媒体播放器代码 50 次,我已经这样做了,或者有更好的方法可以在应用于所有 50 个媒体播放器 MP3 的单个代码中做到这一点,因为所有人都有相同的功能循环。
请提供任何建议以及如何在编码中应用它。
主要活动:
public class MainActivity extends Activity
private ViewPager mViewPager;
MediaPlayer mp;
private boolean isPaused;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager= (ViewPager) findViewById(R.id.view_pager);
ImageAdapter adapter = new ImageAdapter(this);
mViewPager.setAdapter(adapter);
final GestureDetector tapGestureDetector = new GestureDetector(this, new TapGestureListener());
mViewPager.setOnTouchListener(new View.OnTouchListener()
public boolean onTouch(View v, MotionEvent event)
tapGestureDetector.onTouchEvent(event);
return false;
);
private class TapGestureListener extends GestureDetector.SimpleOnGestureListener
@Override
public boolean onSingleTapConfirmed(MotionEvent e)
if (mViewPager.getCurrentItem() == 0)
if (mp != null)
if (isPaused)
mp.start();
isPaused = false;
else
mp.pause();
isPaused = true;
else
mp = MediaPlayer.create(MainActivity.this, R.raw.aa);
mp.start();
if (mViewPager.getCurrentItem() == 1)
if (mp != null)
if (isPaused)
mp.start();
isPaused = false;
else
mp.pause();
isPaused = true;
else
mp = MediaPlayer.create(MainActivity.this, R.raw.bb);
mp.start();
if (mViewPager.getCurrentItem() == 2)
if (mp != null)
if (isPaused)
mp.start();
isPaused = false;
else
mp.pause();
isPaused = true;
else
mp = MediaPlayer.create(MainActivity.this, R.raw.cc);
mp.start();
if (mViewPager.getCurrentItem() == 3)
if (mp != null)
if (isPaused)
mp.start();
isPaused = false;
else
mp.pause();
isPaused = true;
else
mp = MediaPlayer.create(MainActivity.this, R.raw.dd);
mp.start();
//AND SO ON FOR 50 PAGES//
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener()
@Override
public void onPageSelected(int position)
if (mp == null)
return;
mp.release();
mp = null;
@Override
public void onPageScrollStateChanged(int arg0)
// TODO Auto-generated method stub
@Override
public void onPageScrolled(int arg0, float arg1, int arg2)
// TODO Auto-generated method stub
);
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
public void onCompletion(MediaPlayer m)
Toast.makeText(MainActivity.this,
"COMPLETED", Toast.LENGTH_LONG).show();
// Set the MainActivity member to null
MainActivity.this.mp = null;
);
return super.onSingleTapConfirmed(e);
图像适配器:
public class ImageAdapter extends PagerAdapter
Context context;
private int[] GalImages = new int[]
R.drawable.a,
R.drawable.b,
R.drawable.c,
R.drawable.d,
;
ImageAdapter(Context context)
this.context=context;
@Override
public int getCount()
return GalImages.length;
@Override
public boolean isViewFromObject(View view, Object object)
return view == ((ImageView) object);
@Override
public Object instantiateItem(ViewGroup container, int position)
ImageView imageView = new ImageView(context);
int padding = context.getResources().getDimensionPixelSize(R.dimen.activity_horizontal_margin);
imageView.setPadding(padding, padding, padding, padding);
imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setImageResource(GalImages[position]);
((ViewPager) container).addView(imageView, 0);
return imageView;
@Override
public void destroyItem(ViewGroup container, int position, Object object)
((ViewPager) container).removeView((ImageView) object);
我是 android 新手,我试图修复它但没有成功,它的简单应用程序只包含 MainActivity 和 ImageAdapter。
我试过下面的代码还是没有解决问题:
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener()
@Override
public void onPageSelected(int position)
if (mp != null)
if (mp.isPlaying())
mp.stop();
mp.release();
mp = null;
@Override
public void onPageScrollStateChanged(int arg0)
// TODO Auto-generated method stub
@Override
public void onPageScrolled(int arg0, float arg1, int arg2)
// TODO Auto-generated method stub
);
更新:
在任何页面中:
假设页面(一)--->点击播放MP3--->(播放)--->点击暂停MP3--->(暂停)--->滑动到任意页面Rt或Lf --->(以页面(二)为例)--->点击播放页面(二)的MP3 --->(正在播放)--->点击暂停页面(二)的MP3 --- >(暂停)--->(所有之前的onclick动作都正常工作)--->点击恢复播放已经处于暂停状态的页面(二)中的MP3 ====>但错误地当您点击页面(二)中的图像继续播放 MP3 ,手指不直,略微倾斜,因此手指点击导致(点击页面(二)并同时滑动到页面(三) ====>这里是页面(三)MP3从头自己开始播放的问题。
如果这种情况偶尔或错误地发生,我希望不要开始播放第 (3) 页中的 MP3,直到我单击第 (3) 页中的图像然后开始播放 MP3。
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:第一个问题的答案:-
只需复制粘贴此代码,让我知道我尚未对其进行测试,但强烈感觉它会起作用。
import java.lang.reflect.Field;
public class MainActivity extends Activity
private ViewPager mViewPager;
MediaPlayer mp;
private boolean isPaused;
private ArrayList<Integer> mMp3s;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager = (ViewPager) findViewById(R.id.view_pager);
ImageAdapter adapter = new ImageAdapter(this);
mMp3s=getAllMp3FilesFromRaw();
mViewPager.setAdapter(adapter);
final GestureDetector tapGestureDetector = new GestureDetector(this, new TapGestureListener());
mViewPager.setOnTouchListener(new View.OnTouchListener()
public boolean onTouch(View v, MotionEvent event)
tapGestureDetector.onTouchEvent(event);
return false;
);
private class TapGestureListener extends GestureDetector.SimpleOnGestureListener
@Override
public boolean onSingleTapConfirmed(MotionEvent e)
if (mp != null)
if (isPaused)
mp.start();
isPaused = false;
else
mp.pause();
isPaused = true;
else
mp = MediaPlayer.create(MainActivity.this, mMp3s.get(mViewPager.getCurrentItem()));
mp.start();
isPaused = false;
//AND SO ON FOR 50 PAGES//
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener()
@Override
public void onPageSelected(int position)
if (mp == null)
return;
mp.release();
mp = null;
isPaused = true;
@Override
public void onPageScrollStateChanged(int arg0)
// TODO Auto-generated method stub
@Override
public void onPageScrolled(int arg0, float arg1, int arg2)
// TODO Auto-generated method stub
);
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
public void onCompletion(MediaPlayer m)
Toast.makeText(MainActivity.this, "COMPLETED", Toast.LENGTH_LONG).show();
// Set the MainActivity member to null
finish();
MainActivity.this.mp = null;
);
return super.onSingleTapConfirmed(e);
/**
*Do it on background thread if it blocks the UI.
*/
private ArrayList<Integer> getAllMp3FilesFromRaw()
ArrayList<Integer> mp3s = new ArrayList<>();
try
Field fields[] = R.raw.class.getDeclaredFields();
for (int i = 0; i < fields.length; i++)
Field f = fields[i];
int resIdentifier = getResources().getIdentifier(f.getName(), "raw", getPackageName());
mp3s.add(resIdentifier);
return mp3s;
catch (Exception e)
e.printStackTrace();
return null;
如果这个过程在后台线程上花费太多时间,逻辑是在启动应用程序时获取所有 mp3 文件资源 ID。
现在使用这些资源 ID 播放您的歌曲,您获取的列表存在很多问题,例如它们可能与您的图像或浏览器编号不匹配,因为如果您遇到任何错误,您将不得不应用一些其他逻辑让我知道。
秒问题答案:- 现在我假设当你想点击图像同时播放音乐时,页面会被刷卡,当它到达其他页面时,它会立即开始播放该页面的音乐。如果我理解您的问题,因为我仍然不知道您使用的是哪个代码,我将指导您完成基于您可以应用逻辑的方法。
当页面切换到下一个时
onPageChanged(int position)
方法将被称为https://***.com/a/11294494/5492047 在这里你可以应用逻辑。 现在如何,如果正在播放音乐,并且您在第一页上并且您滑动到第二页,那么您必须在
中做什么onPageChanged(int position)
mp.release();
mp=null;
//Now initialiase it again with page two's music.
mp = MediaPlayer.create(MainActivity.this, R.raw.aa);
并且不要调用 mp.start(); 现在当用户点击
中的图片时 OnClickListener(View view)
//use the same instance of mediaplayer and call mp.start();
if(isPlaying)
mp.pause();
else
mp.start();
我假设您只使用了一个 MediaPlayer 实例,不像您在代码中显示的那样。
【讨论】:
请给我一个小问题,如果你有任何建议,在任何页面--->点击播放--->点击暂停--->滑动到任何页面Rt或Lf -- ->点击播放--->点击暂停--->(正常工作)--->点击恢复但错误地滑动到下一页--->立即开始下一页MP3而不点击它,我想要即使我的手指点击导致错误地滑动到另一个页面以开始点击而不是自己点击。 好的,如果此答案对您有所帮助,请接受并奖励赏金,您的第二个问题不清楚。就像当您滑动到下一页或上一页时,是应该立即播放 mp3 还是应该在滑动页面并点击后播放? @ReyanshMishra 请不要将您的答案强加给 OP 并强制向您发送赏金,如果他有疑问请清除它们。如果问题解决了,他一定会接受并提供赏金。 我不是很抱歉你觉得我只是问它是否解决了你的问题,我想帮助这就是为什么最后我要求他澄清他的问题,因为我不知道他在暗示什么,这可能是一个全新的问题,他无法在 cmets 中解释。 @ReyanshMishra Mishra 请你检查一下这个问题的更新,谢谢【参考方案2】:第一
我相信您的isPaused
在暂停第一首歌曲后保持真实,您可能需要在用户换页时将其设置为 false :
public void onPageSelected(int position)
if (mp == null)
return;
mp.release();
mp = null;
isPaused = false;
第二次
您可以使用List<Integer>
,您可以在应用程序开始时对其进行初始化,这样您就可以有一个结构来存储您的歌曲,因为它是您代码中唯一改变的东西,例如:
List<Integer> songs;
@Override
public void onCreate(Bundle savedInstanceState)
...
songs = new ArrayList<>();
songs.add(R.raw.aa);
songs.add(R.raw.bb);
//...etc
然后在您的 onSingleTapConfirmed
方法上,您可以通过索引访问它们一次:
if (mp != null)
if (isPaused)
mp.start();
isPaused = false;
else
mp.pause();
isPaused = true;
else
mp = MediaPlayer.create(MainActivity.this,
songs.get(mViewPager.getCurrentItem()));
mp.start();
isPaused = false;
【讨论】:
请给我一个小问题,如果你有任何建议,在任何页面--->点击播放--->点击暂停--->滑动到任何页面Rt或Lf -- -> 点击播放--->点击暂停--->(正常工作)--->点击恢复但误滑到下一页--->下一页MP3将立即播放而不点击它,我想要即使我的手指点击导致错误地滑动到另一个页面 mp 也必须响应点击而不是自己播放。 请你检查一下这个问题的更新,谢谢【参考方案3】:根据你的描述和我的理解,我列出你希望程序做的要求。
点击图片或切换页面后,MediaPlayer 会按照以下规则进行响应。
规则:
如果之前没有播放过歌曲,点击,播放器将开始播放当前页面的歌曲。
如果之前播放过一首歌曲而播放器仍在播放,则单击,播放器将暂停。
如果之前播放过一首歌曲,而播放器还在播放,你切换,播放器将在之前释放并开始播放当前页面的歌曲。
如果之前播放过一首歌曲并且播放器被暂停,你点击,如果当前页面不是之前暂停的歌曲的页面,播放器将释放之前的歌曲并开始播放当前页面的歌曲。
如果之前播放过一首歌曲并且播放器暂停播放,你点击,如果当前页面是之前暂停的歌曲的页面,播放器将继续播放。
如果之前播放过一首歌曲并且播放器被暂停,你切换,什么都不会发生。
看字看不懂,请看下图: (规则 1 实际上与规则 4 相同。)
如果没有误解,我将开始回答问题。或者请告诉我。
现在,我们明确了玩家在不同情况下点击或切换页面时的反应(当前页面是否为之前暂停的歌曲页面)。
让我们谈谈如何避免重复代码。正如其他答案所说,使用歌曲列表并使用 index(num of page) 来区分它们。
所以它们是这样声明的:
List<Integer> mMP3s = new ArrayList<Integer>()
add(R.raw.mp3_0);
add(R.raw.mp3_1);
add(R.raw.mp3_2);
add(R.raw.mp3_3);
add(R.raw.mp3_4);
//...
//AND SO ON FOR 50 PAGES//
;
当你点击图片时(在图片上设置 OnClickListener):
@Override
public void onClick(View view)
int position = mViewPager.getCurrentItem();
if (mp != null)
if (isPaused)
if (pausedPage == position)
mp.start();
else
mp = MediaPlayer.create(MainActivity.this, mMP3s.get(position));
mp.start();
isPaused = false;
else
mp.pause();
isPaused = true;
pausedPage = position;
else
mp = MediaPlayer.create(MainActivity.this, mMP3s.get(position));
mp.start();
isPaused = false;
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
public void onCompletion(MediaPlayer m)
Toast.makeText(MainActivity.this,
"COMPLETED", Toast.LENGTH_LONG).show();
// Set the MainActivity member to null
MainActivity.this.mp = null;
);
当你切换页面时:
@Override
public void onPageSelected(int position)
if (!isPaused)
mp.release();
mp = MediaPlayer.create(MainActivity.this, mMP3s.get(position));
mp.start();
tv.append("START page" + position + "\n");
else
//do nothing.
如果您仍然对代码感到困惑,请参阅here。我在 github 上上传了我的代码。
【讨论】:
请你检查一下这个问题的更新,谢谢 我可能会误解你的问题。但我认为您的逻辑不适合用户使用。试想一下这样的场景,《我的心继续》正在播放,我暂停一下,滑动页面看看有没有其他我感兴趣的歌曲,经过一段时间的搜索,我决定返回我的心继续的页面,并单击它继续播放。这样更好吗? 按照您的逻辑,My Heart Will Go On 将从这首歌的开头开始播放,而不是继续播放。而且在我搜索的过程中,MediaPlayer 会被实例化很多次(和我刷的页数一样多)。不觉得这是对内存的不必要消耗吗? 关于您的更新:OnClickListener 将表现更好并避免您的问题。以上是关于Mediaplayer响应第二次点击暂停的主要内容,如果未能解决你的问题,请参考以下文章
JavaFX 媒体 - 暂停();方法使 MediaPlayer 快进?