java - 我不能在Activity调用fragment的方法,因为fragment的对象是由newInstance方法构造的
问题描述
当按下活动中的按钮时,我想让 MediaPlayer 在片段中停止。我在片段中创建了 stopMediaPlayer() 方法。我尝试在 Activity 的 onClick(View view) 方法中调用 stopMediaPlayer()。
但在我的例子中,片段的对象是使用 newInstance 构造的。并且添加了扩展 FragmentPagerAdapter 类的 FragmentAdater 类。如下所示。这意味着我没有可以直接从 Activity 调用该方法的片段实例。我必须使用 Adapter 实例调用该方法,因为它具有 FragmentManager。
public class FragmentAdapter extends FragmentPagerAdapter {
ArrayList<Fragment> fragmentArrayList = new ArrayList<>();
public FragmentAdapter(FragmentManager fm){
super(fm);
}
public void addFragment(Fragment fragment) {
fragmentArrayList.add(fragment);
}
@Override
public Fragment getItem(int position) {
return fragmentArrayList.get(position);
}
@Override
public int getCount() {
return fragmentArrayList.size();
}
------------------下面的活动-------------- --------
WholeGuideFragment wholeGuideFragment = new WholeGuideFragment();
Part1QuestionFragment part1QuestionFragment = new Part1QuestionFragment();
Part2QuestionFragment part2QuestionFragment = new Part2QuestionFragment();
Part3QuestionFragment part3QuestionFragment = new Part3QuestionFragment();
Part4QuestionFragment part4QuestionFragment = new Part4QuestionFragment();
Part5QuestionImageFragment part5QuestionImageFragment = new Part5QuestionImageFragment();
Part5QuestionStringFragment part5QuestionStringFragment = new Part5QuestionStringFragment();
Part6QuestionFragment part6QuestionFragment = new Part6QuestionFragment();
StopButton stopButton = StopButton.getStopButton();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_part1);
setFragmentAdapter();
initView();
setSession();
checkPermission();
//audio record 묻기
Log.d("aaa", "Acitivity onCreate");
}
private void setFragmentAdapter() {
fragmentAdapter = new FragmentAdapter(getSupportFragmentManager());
fragmentAdapter.addFragment(wholeGuideFragment);
fragmentAdapter.addFragment(PartGuideFragment.newInstance(1, this));
fragmentAdapter.addFragment(part1QuestionFragment);
fragmentAdapter.addFragment(PartGuideFragment.newInstance(2, this));
fragmentAdapter.addFragment(part2QuestionFragment);
fragmentAdapter.addFragment(PartGuideFragment.newInstance(3, this));
fragmentAdapter.addFragment(part3QuestionFragment);
fragmentAdapter.addFragment(PartGuideFragment.newInstance(4, this));
fragmentAdapter.addFragment(part4QuestionFragment);
fragmentAdapter.addFragment(PartGuideFragment.newInstance(5, this));
fragmentAdapter.addFragment(part5QuestionImageFragment);
fragmentAdapter.addFragment(part5QuestionStringFragment);
fragmentAdapter.addFragment(PartGuideFragment.newInstance(6, this));
fragmentAdapter.addFragment(part6QuestionFragment);
}
private void initView() {
isStopped = false;
next_btn = findViewById(R.id.next_btn);
back_btn = findViewById(R.id.back_btn);
play_pause_button = findViewById(R.id.play_pause_button);
viewPager = findViewById(R.id.viewPager);
viewPager.setAdapter(fragmentAdapter);
viewPager.beginFakeDrag();
viewPager.setOffscreenPageLimit(0);
next_btn.setOnClickListener(this);
back_btn.setOnClickListener(this);
play_pause_button.setOnClickListener(this);
play_pause_button.setSelected(true);
}
@Override
public void onClick(View view) {
int button_id = view.getId();
position = viewPager.getCurrentItem();
switch (button_id) {
case R.id.next_btn:
setNext(position);
break;
case R.id.back_btn:
setBefore(position);
break;
case R.id.play_pause_button:
if (play_pause_button.isSelected()) {
fragmentPlayStop(position, play_pause_button.isSelected());
stopButton.setStopButtonClicked(false);
play_pause_button.setSelected(false);
} else {
fragmentPlayStop(position, play_pause_button.isSelected());
stoppedPageNum = position;
savedStoppedQ_num(position);
stopButton.setStopButtonClicked(true);
play_pause_button.setSelected(true);
}
//play_pause_button is selector:true=play_button,false=pause
//stopButton is a Singleton class can share the boolean value to other fragments whether the activity stop button is pressed or not
//stoppedPageNum and savedStoppedQ_num method is to compare the page whether the user pressed the button at the same fragment or not.
//timer 초기화.
break;
}
}
public void fragmentPlayStop(int stop_play_position, boolean b) {
if (b == true) {
stoppedPageNum = checkStopAndCurrentPage(stop_play_position);
fragmentonResume(stoppedPageNum);
} else {
fragmentonPause(stop_play_position);
}
}
private void fragmentonPause(int stop_play_position) {
switch (stop_play_position) {
case 0:
wholeGuideFragment.onPause();
break;
case 1:
//mp stop
break;
case 2:
part1QuestionFragment.stopMediaPlayer();
part1QuestionFragment.stopTimer();
break;
case 3:
//Guide fragment에서 mediaplayer어떻게 스탑할건지 생각하기
//mp stop
break;
case 4: break;
case 5:
//Guide fragment에서 mediaplayer어떻게 스탑할건지 생각하기
//mp stop
break;
case 6:
//mp, timer stop
break;
case 7:
//Guide fragment에서 mediaplayer어떻게 스탑할건지 생각하기
//인터페이스로 mpstop 이나 onPause호출하기
break;
case 8:
//mp, timer stop
break;
case 9:
//Guide fragment에서 mediaplayer어떻게 스탑할건지 생각하기
//mp stop
break;
case 10:
//mp stop
break;
case 11:
//mp, timer stop
break;
case 12:
//Guide fragment에서 mediaplayer어떻게 스탑할건지 생각하기
//mp stop
break;
case 13:
//mp, timer stop
break;
}
}
问题就在这里。由于通过 newInstance 方法的对象,我无法调用如下片段的方法。如果是 1,3,5,7,9,12 我必须调用方法 stopMediaPlayer();
(PartGuideFragment)fragmentAdapter.getItem(9).stopMediaPlayer();
我试过了,但我只能调用像onPause,onStop这样的覆盖方法......
+参考下面的 FragmentClass -> "PartGuideFragment"
public static PartGuideFragment newInstance(int part, GuideCompleteListener guideCompleteListener) {
Bundle args = new Bundle();
args.putInt("part", part);
PartGuideFragment fragment = new PartGuideFragment();
fragment.guideCompleteListener = guideCompleteListener;
fragment.setArguments(args);
return fragment;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_part1_guide, container, false);
textView = view.findViewById(R.id.guide_txt);
part = getArguments().getInt("part");
setGuideString();
return view;
}
private void setGuideString() {
switch (part){
case 1:
str = guidData.getPart1Guide();
break;
case 2:
str = guidData.getPart2Guide();
break;
case 3:
str = guidData.getPart3Guide();
break;
case 4:
str = guidData.getPart4Guide();
break;
case 5:
str = guidData.getPart5Guide();
break;
case 6:
str = guidData.getPart6Guide();
break;
}
Markwon.setMarkdown(textView, str);
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
if(mediaPlayer == null){
setMediaPlayer();
mediaPlayer.start();
}else{
mediaPlayer.start();
}
}else{
if(mediaPlayer == null){
setMediaPlayer();
}else{
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
}
}
private void setMediaPlayer() {
switch (part) {
case 1:
mediaPlayer = MediaPlayer.create(context, R.raw.part1_direction);
break;
case 2:
mediaPlayer = MediaPlayer.create(context, R.raw.part2_direction);
break;
case 3:
mediaPlayer = MediaPlayer.create(context, R.raw.part3_direction);
break;
case 4:
mediaPlayer = MediaPlayer.create(context, R.raw.part4_direction);
break;
case 5:
mediaPlayer = MediaPlayer.create(context, R.raw.part5_direction);
break;
case 6:
mediaPlayer = MediaPlayer.create(context, R.raw.part6_direction);
break;
}
}
public void stopMediaPlayer(){
if(mediaPlayer!= null){
mediaPlayer.stop();
}
}
public void playMediPalyer(){
if(mediaPlayer!= null){
mediaPlayer.reset();
mediaPlayer.start();
}else{
setMediaPlayer();
mediaPlayer.start();
}
}
解决方案
你只是选错了演员。试试这个
((PartGuideFragment)fragmentAdapter.getItem(9)).stopMediaPlayer();
推荐阅读
- python - 循环浏览 2 个列表
- reactjs - 使用 React Hooks 更新状态对象
- pandas - 使用 pandas 在数据帧上执行 groupby,按计数排序并获取 python 中的前 2 个计数
- python - 如何将日志消息写入文件
- latex - 将目录从 R bookdown 删除到 pdf_book 或 pdf_document2
- javascript - 使用 jQuery/javascript 动态添加目录中的所有图像
- python-3.x - 如何通过 VSTS 个人令牌通过 Python 连接 VSTS 查询并获取查询结果
- nextcloud - Onlyoffice集成到nextcloud。下载要转换的文档文件时出错
- java - 我的 Jbutton 没有添加从 Jtextfield 获取的数据并将数据打印到 Jtable
- firebase - 在发送云消息方面,我是否需要关注 firebase 刷新令牌?