我正在使用$role = Role::where("display_name",'=', $request->route("role"))->first();
$role->delete() //fails
$role->forceDelete() //also fails
单片段实例,其中我正在显示ViewPager
文件,如图片,视频,音频。
我已经实施Media
来处理ExoPlayer
& Video
个文件。并Audio
用于图片。
从this来避免内存泄漏我在Glide
中发布ExoPlayer
这样的对象:
ItemViewerFragment.java
在 private void releasePlayer() {
if (player != null) {
player.release();
player = null;
trackSelector = null;
simpleExoPlayerView.setPlayer(null);
}
}
@Override
public void onStart() {
super.onStart();
if (player == null && currentGalleryModel != null) {
initializePlayer();
}
}
@Override
public void onResume() {
super.onResume();
if (player == null && currentGalleryModel != null) {
initializePlayer();
}
}
@Override
public void onPause() {
super.onPause();
releasePlayer();
}
@Override
public void onStop() {
super.onStop();
releasePlayer();
}
我正在初始化视图:
onViewCreated()
我正在使用 @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (currentGalleryModel.isVideo() || currentGalleryModel.isAudio()) {
simpleExoPlayerView.setVisibility(View.VISIBLE);
imageView.setVisibility(View.GONE);
initializePlayer();
} else if (currentGalleryModel.isImage() || currentGalleryModel.isGif()) {
simpleExoPlayerView.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE);
Glide.with(this)
.load(currentGalleryModel.getFilePath())
.placeholder(android.R.color.black)
.fitCenter()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(imageView);
}
}
。这是FragmentStatePagerAdapeter
方法:
getItem
我无法在@Override
public Fragment getItem(int position) {
return ItemViewerFragment.newInstance(mItems.get(position));
}
的第一次扫描中检测到片段的onPause
。在第二次滑动Viewpager
文件停止播放时。
在活动中,我尝试添加video/audio
:
.addOnPageChangeListener
在@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
try {
((ItemViewerFragment)mAdapter.getItem(mPreviousPos)).imHiddenNow();
} catch (Exception e) {
e.printStackTrace();
}
mPreviousPos = position;
}
:
ItemViewerFragment.java
仍然public void imHiddenNow(){
releasePlayer();
}
继续比赛。
这是Screencast的Video Link。
请注意,下方发布的解决方案不起作用。
答案 0 :(得分:3)
以下是寻呼机适配器的代码:
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
这是滚动侦听器:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//Stop media here.
}
@Override
public void onPageSelected(int position) {
//Save your previous position here.
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
对于媒体,您可以使用for循环并立即将所有片段添加到列表中,然后使用它来提高效率:
viewPager.setOffscreenPageLimit(3);
这将确保只有3个片段实例可用,这足够了。
对于使用单个片段,我建议你这样做:
public MyFragment() {
}
//This is to send a file to the fragment if you need it.
public static MyFragment newInstance(File file) {
MyFragment fragment = new MyFragment();
Bundle bundle = new Bundle();
bundle.putSerializable("file", file);
fragment.setArguments(bundle);
return fragment;
}
然后在onCreate of Fragment中你可以像这样检索你的文件:
File file;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
file = getArguments().getSerializable("file");
}
现在将您的片段添加到寻呼机中,如下所示:
for (int i = 0; i < totalFiles; i++) {
viewPagerAdapter.addFragment(MyFragment.newInstance(fileList.get(i));
}
希望这有帮助。
答案 1 :(得分:2)
我遵循了一种在HashMap
内维护PagerAdapter
片段对象的方法
interface FragmentLifecycle {
void onPauseFragment()
}
public void onPauseFragment() {
if (simpleExoPlayer != null){
simpleExoPlayer.setPlayWhenReady(false);
}
}
将所有片段对象存储在HashMap<Integer,Fragment>
中,并以相应的位置作为键。在PagerAdapter
中声明哈希图。还声明一种getter方法,用于从hashmap访问片段对象。例如
@Override
public Fragment getItem(int position) {
ItemViewerFragment fragment = ItemViewerFragment.newInstance(mItems.get(position));
mFragments.put(position,fragment);
return fragment;
}
public ItemViewerFragment getMapItem(int position){ 返回mFragments.get(position); }
在声明了viewPager
的活动中,保留一个变量currentPosition
并实现ViewPager.OnPageChangeListener
。
内部onPageSelected
方法中,
@Override
public void onPageSelected(int position) {
if(mAdapter.getMapItem(currentPosition) != null) (mAdapter.getMapItem(currentPosition)).onPauseFragment();
currentPosition = position;
}
答案 2 :(得分:1)
自从我使用Exoplayer&amp; amp;我有点解决了类似的问题。请注意,API已经发生了一些变化,因此请使用以下代码来了解如何实现潜在的解决方案。如果它不起作用,请告诉我,我会进一步研究API并回复您。
来到解决方案:
private int mPlayerCurrentPosition;
private int getCurrentPlayerPosition() {
return mExoPlayer.getCurrentPosition();
}
// call this from onPause
private void releaseExoplayer() {
mPlayerCurrentPosition = getPlayerCurrentPosition();
mExoPlayer.setPlayWhenReady(false);
mExoPlayer.release(); // this will make the player object eligible for GC
}
private void resumePlaybackFromPreviousPosition(int prevPosition) {
mExoPlayer.seekTo(mPlayerCurrentPosition );
}
答案 3 :(得分:1)
问题在于,在ViewPager中更改片段可见性时,不会调用onPause
和onResume
。
解决方案是添加2个可见性事件:losingVisibility
和gainVisibility
。
因为您保持框架管理Fragment缓存和生命周期。 我们只需要在片段中添加暂停和恢复媒体所需的回调。
以下代码仅是我的代码的解释。检查Step*.java类以查看完整的实现。
在YourFragment.java中创建losingVisibility
和gainVisibility
方法:
public class YourFragment extends Fragment {
/**
* This method is only used by viewpager because the viewpager doesn't call onPause after
* changing the fragment
*/
public void losingVisibility() {
// IMPLEMENT YOUR PAUSE CODE HERE
savePlayerState();
releasePlayer();
}
/**
* This method is only used by viewpager because the viewpager doesn't call onPause after
* changing the fragment
*/
public void gainVisibility() {
// IMPLEMENT YOUR RESUME CODE HERE
loadVideo();
}
}
每次在YourActivity.java中选择一个新页面(losingVisibility
)时,调用gainVisibility
和onPageSelected
:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
YourFragment cachedFragmentLeaving = mYourPagerAdapter.getCachedItem(mCurrentItem);
if (cachedFragmentLeaving != null) {
cachedFragmentLeaving.losingVisibility();
}
mCurrentItem = position;
YourFragment cachedFragmentEntering = mYourPagerAdapter.getCachedItem(mCurrentItem);
if (cachedFragmentEntering != null) {
cachedFragmentEntering.gainVisibility();
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
将getCachedItem
添加到YourPagerAdapter.java:
第三步是添加一种方法来检索缓存的片段。为此,我们必须缓存对创建的片段的引用(覆盖
instantiateItem
)并释放相同的引用(覆盖destroyItem
)。
public class YourPagerAdapter extends FragmentStatePagerAdapter {
private SparseArray<YourFragment> mFragmentsHolded = new SparseArray<>();
@NonNull
@Override
public Object instantiateItem(ViewGroup container, int position) {
Object fragment = super.instantiateItem(container, position);
if(fragment instanceof StepFragment) {
mFragmentsHolded.append(position, (StepFragment) fragment);
}
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
mFragmentsHolded.delete(position);
super.destroyItem(container, position, object);
}
public YourFragment getCachedItem(int position) {
return mFragmentsHolded.get(position, null);
}
}
答案 4 :(得分:0)
我知道这么晚但我希望它可以帮助任何人...
viewPager保持屏幕外片段开始..
所以你有:
prev屏外片段(开始) - &gt;可见片段(工作) - &gt;下一个屏幕外片段(开始)
解决方案是你可以覆盖Fragment.setUserVisibleHint()
并处理播放/暂停视频..