我正在制作音乐播放器,而我正在制作迷你图层。 miniplayer存在于ViewPager中,还有一个用于随机播放的浮动操作按钮(FAB)。最初,屏幕上只显示FAB。单击FAB时,音乐播放开始,Fab-Miniplayer ViewPager的页面计数从1到2,其页面设置为第二页,即miniplayer所在的页面。第二页中的miniplayer本身是一个垂直的viewpager,因此可以滑动到不同的歌曲。 miniplayer / vertical viewpager由PagerAdapter支持,该PagerAdapter从SongQueue
obejct获取歌曲。
如果我点击FAB一次,那么miniplayer就会打开,一切正常。然后我通过向后滑动到ViewPager中的FAB页面来关闭miniplayer以停止播放。单击FAB开始播放并第二次打开miniplayer后,永远不会创建前两个片段。 miniplayer vertical ViewPager的PagerAdapter的getItem()方法永远不会被调用为项目0和项目1.在更高的层次上,miniplayer中的前两首歌曲没有显示出来。在进一步调查之后,onCreate()方法正在从最后一次打开miniplayer开始调用前两首歌曲,因此我猜测ViewPager正在实现某种缓存或者引用被持续的时间太长,因为miniplayer vertical viewpager认为它第二次实例化时已经有前两首歌。希望这个问题描述有意义。如果有任何问题,我会很乐意尝试进一步详细说明。
/**
* Fragment used to display all of the songs on the device.
*/
public class SongsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
private static final String TAG = "SongsFragment";
private SwipeListView mSwipeListView;
private ViewPager fabMiniPlayerViewPager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
setHasOptionsMenu(true);
// Initialize the loader to load the list of songs
getLoaderManager().initLoader(SongCursorLoader.ALL_SONGS_ID, null, this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.list_view_songs, parent, false);
if (view != null) {
mSwipeListView = (SwipeListView) view.findViewById(R.id.list_view_songs);
}
LinearLayout emptyView = (LinearLayout) inflater.inflate(R.layout.list_view_songs_empty, parent, false);
mSwipeListView.setEmptyView(emptyView);
fabMiniPlayerViewPager = (ViewPager) view.findViewById(R.id.fab_miniplayer_ViewPager);
Integer viewPagerPageCount = new Integer(1);
fabMiniPlayerViewPager.setTag(viewPagerPageCount); // The fabMiniPlayerViewPager gets it's page count from the tag so it can be dynamically modified
fabMiniPlayerViewPager.setAdapter(new FragmentStatePagerAdapter(getChildFragmentManager()) {
@Override
public Fragment getItem(int i) {
if (i == 0) {
// ShuffleFabFragment just houses a single button, the code is below
ShuffleFabFragment fragment = new ShuffleFabFragment();
fragment.setViewPager(fabMiniPlayerViewPager);
return fragment;
}
MiniPlayerFragment fragment = new MiniPlayerFragment();
return fragment;
}
@Override
public int getCount() {
Integer count = (Integer) fabMiniPlayerViewPager.getTag();
return count.intValue();
}
});
fabMiniPlayerViewPager.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// Pass touch events to the list view behind it
mSwipeListView.onTouchEvent(motionEvent);
return false;
}
});
return view;
}
@Override
public void onResume() {
super.onResume();
if (!MusicPlayerService.isStopped()) {
Integer viewPagerPageCount = 2;
fabMiniPlayerViewPager.setTag(viewPagerPageCount);
PagerAdapter adapter = fabMiniPlayerViewPager.getAdapter();
fabMiniPlayerViewPager.setAdapter(adapter);
fabMiniPlayerViewPager.setCurrentItem(1, false);
} else {
Integer viewPagerPageCount = 1;
fabMiniPlayerViewPager.setTag(viewPagerPageCount);
fabMiniPlayerViewPager.getAdapter().notifyDataSetChanged();
}
}
}
/**
* Fragment representing the Shuffle Floating Action Button. On FAB click, it turns on shuffle and
* plays a random song. Depending on the user preference, the mini-player will appear or the
* Now Playing view will appear. The ShuffleFabFragment holds a reference to its containing
* ViewPager so it can do the following:
* <p/>
* 1. Add the MiniPlayer fragment to the ViewPager to enable swiping & animations
* 2. Remove the MiniPlayer fragment when it is swiped away
* <p/>
* Once the MiniPlayer is swiped away (to the right), it stops music playback.
*/
public class ShuffleFabFragment extends Fragment {
private static final String TAG = "ShuffleFabFragment";
private ViewPager fabMiniPlayerViewPager;
public void setViewPager(ViewPager viewPager) {
fabMiniPlayerViewPager = viewPager;
fabMiniPlayerViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i2) {
}
@Override
public void onPageSelected(int i) {
if (i == 0) { // MiniPlayer swiped away
Integer viewPagerPageCount = new Integer(1);
fabMiniPlayerViewPager.setTag(viewPagerPageCount);
PagerAdapter adapter = fabMiniPlayerViewPager.getAdapter();
Intent stopMusicIntent = new Intent(getActivity(), MusicPlayerService.class);
stopMusicIntent.setAction(MusicPlayerService.ACTION_STOP);
getActivity().startService(stopMusicIntent);
fabMiniPlayerViewPager.setAdapter(adapter);
}
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.shuffle_fab, viewGroup, false);
ImageView shuffleFabImageView = (ImageView) view.findViewById(R.id.shuffle_fab_ImageView);
shuffleFabImageView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
// Scale up on touch to make the button appear to come closer
view.setScaleX(8f / 7f);
view.setScaleY(8f / 7f);
break;
case MotionEvent.ACTION_UP:
view.setScaleX(1f);
view.setScaleY(1f);
break;
default:
view.setScaleX(1f);
view.setScaleY(1f);
}
return false;
}
});
shuffleFabImageView.setClickable(true);
shuffleFabImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String shuffleMode = PreferencesHelper.getShuffleMode(getActivity());
if (shuffleMode.equals(PreferencesHelper.SHUFFLE_MODE_OFF)) {
PreferencesHelper.setShuffleMode(getActivity(), PreferencesHelper.SHUFFLE_MODE_SMART);
}
SongQueue.initializeQueue(null, true, Song.COLLECTION_TYPE_ALL_SONGS, getActivity().getApplicationContext(), null);
Song firstSong = SongQueue.getSong(0);
firstSong.play(getActivity(), false);
// On Click, update the page count, then set page to miniplayer
Integer viewPagerPageCount = new Integer(2);
fabMiniPlayerViewPager.setTag(viewPagerPageCount);
fabMiniPlayerViewPager.getAdapter().notifyDataSetChanged();
fabMiniPlayerViewPager.setCurrentItem(1, true);
}
});
return view;
}
}
/**
* Hosts MiniplayerCardFragments and allows for song skipping
*/
public class MiniPlayerFragment extends Fragment implements ViewPager.OnPageChangeListener {
VerticalViewPager miniplayerCardViewPager;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.view_pager_miniplayer, viewGroup, false);
miniplayerCardViewPager = (VerticalViewPager) view.findViewById(R.id.miniplayer_cards_ViewPager);
miniplayerCardViewPager.setAdapter(new FragmentStatePagerAdapter(getChildFragmentManager()) {
@Override
public Fragment getItem(int position) {
Song song = SongQueue.getSong(position);
return MiniPlayerCardFragment.newInstance(song);
}
@Override
public int getCount() {
return SongQueue.getTotalSize();
}
});
miniplayerCardViewPager.setOnPageChangeListener(this);
SongQueue.addOnQueueChangeListener(new SongQueue.OnQueueChangeListener() {
@Override
public void onNextSongChanged() {
onQueueChanged();
}
@Override
public void onQueueChanged() {
// Force re-layout to update fragments
int queuePosition = SongQueue.getQueuePositionCurrentSong();
PagerAdapter adapter = miniplayerCardViewPager.getAdapter();
miniplayerCardViewPager.setAdapter(adapter);
miniplayerCardViewPager.setCurrentItem(queuePosition, true);
}
@Override
public void onCurrentSongChanged() {
onQueueChanged();
}
});
return view;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
int queuePosition = SongQueue.getQueuePositionCurrentSong();
if (queuePosition < position) {
Intent nextIntent = new Intent(getActivity(), MusicPlayerService.class);
nextIntent.setAction(MusicPlayerService.ACTION_NEXT);
getActivity().startService(nextIntent);
} else if (queuePosition > position) {
Intent prevIntent = new Intent(getActivity(), MusicPlayerService.class);
prevIntent.setAction(MusicPlayerService.ACTION_PREV);
getActivity().startService(prevIntent);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
@Override
public void onResume() {
super.onResume();
// Force re-layout to update fragments
int queuePosition = SongQueue.getQueuePositionCurrentSong();
PagerAdapter adapter = miniplayerCardViewPager.getAdapter();
miniplayerCardViewPager.setAdapter(adapter);
miniplayerCardViewPager.setCurrentItem(queuePosition, true);
SongQueue.setPagerAdapter(adapter);
}
}
答案 0 :(得分:0)
单击FAB开始播放并第二次打开miniplayer后,永远不会创建前两个片段。对于项目0和项目1,永远不会调用miniplayer垂直ViewPager的PagerAdapter的getItem()方法。
这是因为标准ViewPager
已经有第0页和第1页。为了澄清Sanket的答案,setOffscreenPageLimit()
表示要创建当前页面任意一侧的页数(通过{ {1}})和缓存,最小值为1.将忽略对getItem()
的调用。
setOffscreenPageLimit(0)
不是一种在用户切换页面时查找的方法。 A PageChangeListener
是您查找用户切换页面的方法。
miniplayer vertical viewpager认为它第二次实例化时已经有前两首歌了
它没有第二次实例化AFAICT。
答案 1 :(得分:-1)
ViewPager默认为offScreenPageLimit值为3 ..所以它可能没有第二次加载你的前2项..
试试这个
mViewPager.setOffscreenPageLimit(0);
更多info