是否可以在片段类中设置 ViewPager?
Posted
技术标签:
【中文标题】是否可以在片段类中设置 ViewPager?【英文标题】:Is it possible to set ViewPager inside a fragment class? 【发布时间】:2021-09-11 23:25:36 【问题描述】:我有一个Fragment
类和一个与该片段相关的Activity
类,ViewPager 已在MizActivity
的Activity 中初始化
我的问题是可以将 ViewPager
初始化从 Activity 类移动到 Fragment 类以便我更好地控制?
提前致谢
片段
@SuppressLint("InflateParams") public class TvShowEpisodeDetailsFragment extends Fragment
TextClicked mCallback;
public interface TextClicked
void sendText(int position);
private Activity mContext;
private TvShowEpisode mEpisode;
private ImageView mBackdrop, mEpisodePhoto;
private TextView mTitle, mDescription, mFileSource, mAirDate, mRating, mDirector, mWriter, mGuestStars, mSeasonEpisodeNumber;
private View mDetailsArea;
private Picasso mPicasso;
private Typeface mMediumItalic, mMedium, mCondensedRegular;
private DbAdapterTvShowEpisodes mDatabaseHelper;
private long mVideoPlaybackStarted, mVideoPlaybackEnded;
private boolean mShowFileLocation;
private Bus mBus;
private int mToolbarColor = 0;
private FloatingActionButton mFab;
private PaletteLoader mPaletteLoader;
private ObservableScrollView mScrollView;
private RecyclerView mEpisodesList;
private String mShowId;
private ArrayList<TvShowEpisode> mEpisodes = new ArrayList<TvShowEpisode>();
private static final String SHOW_ID = "showId";
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private ViewPager mViewPager;
public PlanetAdapter.OnItemClickListener listener;
/**
* Empty constructor as per the Fragment documentation
*/
public TvShowEpisodeDetailsFragment()
public static TvShowEpisodeDetailsFragment newInstance(String showId, int season, int episode)
TvShowEpisodeDetailsFragment pageFragment = new TvShowEpisodeDetailsFragment();
Bundle bundle = new Bundle();
bundle.putString("showId", showId);
bundle.putInt("season", season);
bundle.putInt("episode", episode);
pageFragment.setArguments(bundle);
return pageFragment;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setRetainInstance(true);
setHasOptionsMenu(true);
mContext = getActivity();
mBus = MizuuApplication.getBus();
mShowFileLocation = PreferenceManager.getDefaultSharedPreferences(getActivity()).getBoolean(SHOW_FILE_LOCATION, true);
mPicasso = MizuuApplication.getPicassoDetailsView(getActivity());
mMediumItalic = TypefaceUtils.getRobotoMediumItalic(mContext);
mMedium = TypefaceUtils.getRobotoMedium(mContext);
mCondensedRegular = TypefaceUtils.getRobotoCondensedRegular(mContext);
mDatabaseHelper = MizuuApplication.getTvEpisodeDbAdapter();
// initializing mEpisodes
mShowId = getActivity().getIntent().getExtras().getString(SHOW_ID);
Cursor cursor = mDatabaseHelper.getEpisodes(mShowId);
try
while (cursor.moveToNext())
mEpisodes.add(new TvShowEpisode(mContext, mShowId,
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_TITLE)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_PLOT)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_SEASON)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_AIRDATE)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_DIRECTOR)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_WRITER)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_GUESTSTARS)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_RATING)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_HAS_WATCHED)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_FAVOURITE))
));
catch (Exception e)
finally
cursor.close();
// mEpisodes initialized
LocalBroadcastManager.getInstance(mContext).registerReceiver(mBroadcastReceiver,
new IntentFilter(LocalBroadcastUtils.UPDATE_TV_SHOW_EPISODE_DETAILS_OVERVIEW));
loadEpisode();
@Override
public void onDestroy()
super.onDestroy();
LocalBroadcastManager.getInstance(mContext).unregisterReceiver(mBroadcastReceiver);
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver()
@Override
public void onReceive(Context context, Intent intent)
loadEpisode();
loadData();
;
private void loadEpisode()
if (!getArguments().getString("showId").isEmpty() && getArguments().getInt("season") >= 0 && getArguments().getInt("episode") >= 0)
Cursor cursor = mDatabaseHelper.getEpisode(getArguments().getString("showId"), getArguments().getInt("season"), getArguments().getInt("episode"));
if (cursor.moveToFirst())
mEpisode = new TvShowEpisode(getActivity(),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_SHOW_ID)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_TITLE)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_PLOT)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_SEASON)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_AIRDATE)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_DIRECTOR)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_WRITER)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_GUESTSTARS)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_RATING)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_HAS_WATCHED)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_FAVOURITE))
);
mEpisode.setFilepaths(MizuuApplication.getTvShowEpisodeMappingsDbAdapter().getFilepathsForEpisode(
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_SHOW_ID)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_SEASON)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE))
));
cursor.close();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
return inflater.inflate(R.layout.episode_details, container, false);
@Override
public void onAttach(Activity activity)
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try
mCallback = (TextClicked) activity;
catch (ClassCastException e)
throw new ClassCastException(activity.toString()
+ " must implement TextClicked");
@Override
public void onViewCreated(final View view, Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
mBackdrop = (ImageView) view.findViewById(R.id.imageBackground);
mEpisodePhoto = (ImageView) view.findViewById(R.id.episodePhoto);
mDetailsArea = view.findViewById(R.id.details_area);
mTitle = (TextView) view.findViewById(R.id.movieTitle);
mSeasonEpisodeNumber = (TextView) view.findViewById(R.id.textView7);
mDescription = (TextView) view.findViewById(R.id.textView2);
mFileSource = (TextView) view.findViewById(R.id.textView3);
mAirDate = (TextView) view.findViewById(R.id.textReleaseDate);
mRating = (TextView) view.findViewById(R.id.textView12);
mDirector = (TextView) view.findViewById(R.id.director);
mWriter = (TextView) view.findViewById(R.id.writer);
mGuestStars = (TextView) view.findViewById(R.id.guest_stars);
mScrollView = (ObservableScrollView) view.findViewById(R.id.observableScrollView);
mFab = (FloatingActionButton) view.findViewById(R.id.fab);
// setting RecyclerView
mEpisodesList = (RecyclerView) view.findViewById(R.id.episodesLIST);
// getting episodeslist
ArrayList<PlanetModel> episodeslist = new ArrayList<>();
for(TvShowEpisode e : mEpisodes)
episodeslist.add(new PlanetModel(e.mEpisode));
// Setting LinearLayoutManager
LinearLayoutManager layoutManager
= new LinearLayoutManager(mContext.getApplicationContext(), LinearLayoutManager.HORIZONTAL, false);
//mEpisodesList.setLayoutManager(new LinearLayoutManager(mContext));
mEpisodesList.setLayoutManager(layoutManager);
// Setting RecyclerView Adapter
mEpisodesList.setAdapter(new PlanetAdapter(episodeslist, new PlanetAdapter.OnItemClickListener()
@Override public void onItemClick(String item)
SharedPreferences getPref = getActivity ().getSharedPreferences("PlanetAdapter", Context.MODE_PRIVATE);
int pos = getPref.getInt("newPosition",0);
mCallback.sendText(pos);
));
mFab.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
ViewUtils.animateFabJump(v, new SimpleAnimatorListener()
@Override
public void onAnimationEnd(Animator animation)
play();
);
);
if (MizLib.isTablet(mContext))
mFab.setType(FloatingActionButton.TYPE_NORMAL);
final int height = MizLib.getActionBarAndStatusBarHeight(getActivity());
mScrollView = (ObservableScrollView) view.findViewById(R.id.observableScrollView);
mScrollView.setOnScrollChangedListener(new OnScrollChangedListener()
@Override
public void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt)
final int headerHeight = mEpisodePhoto.getHeight() - height;
final float ratio = (float) Math.min(Math.max(t, 0), headerHeight) / headerHeight;
final int newAlpha = (int) (ratio * 255);
mBus.post(new BusToolbarColorObject(mToolbarColor, newAlpha));
if (MizLib.isPortrait(mContext))
// Such parallax, much wow
mEpisodePhoto.setPadding(0, (int) (t / 1.5), 0, 0);
);
mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
@Override
public void onGlobalLayout()
ViewUtils.setLayoutParamsForDetailsEmptyView(mContext, view,
mBackdrop, mScrollView, this);
);
loadData();
mPicasso.load(mEpisode.getEpisodePhoto()).placeholder(R.drawable.bg).config(MizuuApplication.getBitmapConfig()).into(mEpisodePhoto, new Callback()
@Override
public void onError()
if (!isAdded())
return;
int width = getActivity().getResources().getDimensionPixelSize(R.dimen.episode_details_background_overlay_width);
int height = getActivity().getResources().getDimensionPixelSize(R.dimen.episode_details_background_overlay_height);
mPicasso.load(mEpisode.getTvShowBackdrop()).placeholder(R.drawable.bg).error(R.drawable.nobackdrop).resize(width, height).config(MizuuApplication.getBitmapConfig()).into(mEpisodePhoto);
@Override
public void onSuccess()
if (mPaletteLoader == null)
mPaletteLoader = new PaletteLoader(mPicasso, Uri.fromFile(mEpisode.getEpisodePhoto()), new PaletteLoader.OnPaletteLoadedCallback()
@Override
public void onPaletteLoaded(int swatchColor)
mToolbarColor = swatchColor;
);
mPaletteLoader.addView(mDetailsArea);
mPaletteLoader.setFab(mFab);
mPaletteLoader.execute();
else
// Clear old views after configuration change
mPaletteLoader.clearViews();
// Add views after configuration change
mPaletteLoader.addView(mDetailsArea);
mPaletteLoader.setFab(mFab);
// Re-color the views
mPaletteLoader.colorViews();
);
if (!MizLib.isPortrait(getActivity()))
mPicasso.load(mEpisode.getEpisodePhoto()).placeholder(R.drawable.bg).error(R.drawable.bg).transform(new BlurTransformation(getActivity().getApplicationContext(), mEpisode.getEpisodePhoto().getAbsolutePath() + "-blur", 4)).into(mBackdrop, new Callback()
@Override public void onError()
if (!isAdded())
return;
mPicasso.load(mEpisode.getTvShowBackdrop()).placeholder(R.drawable.bg).error(R.drawable.nobackdrop).transform(new BlurTransformation(getActivity().getApplicationContext(), mEpisode.getTvShowBackdrop().getAbsolutePath() + "-blur", 4)).into(mBackdrop, new Callback()
@Override
public void onError()
@Override
public void onSuccess()
if (!isAdded())
return;
mBackdrop.setColorFilter(Color.parseColor("#aa181818"), android.graphics.PorterDuff.Mode.SRC_OVER);
);
@Override
public void onSuccess()
if (!isAdded())
return;
mBackdrop.setColorFilter(Color.parseColor("#aa181818"), android.graphics.PorterDuff.Mode.SRC_OVER);
);
@Override
public void onDetach()
mCallback = null; // => avoid leaking, thanks @Deepscorn
super.onDetach();
private void loadData()
// Set the episode title
mTitle.setVisibility(View.VISIBLE);
mTitle.setText(mEpisode.getTitle());
mTitle.setTypeface(mCondensedRegular);
mDescription.setTypeface(mCondensedRegular);
mFileSource.setTypeface(mCondensedRegular);
mDirector.setTypeface(mCondensedRegular);
mWriter.setTypeface(mCondensedRegular);
mGuestStars.setTypeface(mCondensedRegular);
mAirDate.setTypeface(mMedium);
mRating.setTypeface(mMedium);
mSeasonEpisodeNumber.setTypeface(mMediumItalic);
mSeasonEpisodeNumber.setText(getString(R.string.showSeason) + " " + mEpisode.getSeason() + ", " + getString(R.string.showEpisode) + " " + mEpisode.getEpisode());
// Set the movie plot
if (!MizLib.isPortrait(getActivity()))
mDescription.setBackgroundResource(R.drawable.selectable_background);
mDescription.setMaxLines(getActivity().getResources().getInteger(R.integer.episode_details_max_lines));
mDescription.setTag(true); // true = collapsed
mDescription.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
if (((Boolean) mDescription.getTag()))
mDescription.setMaxLines(1000);
mDescription.setTag(false);
else
mDescription.setMaxLines(getActivity().getResources().getInteger(R.integer.episode_details_max_lines));
mDescription.setTag(true);
);
mDescription.setEllipsize(TextUtils.TruncateAt.END);
mDescription.setFocusable(true);
else
if (MizLib.isTablet(getActivity()))
mDescription.setLineSpacing(0, 1.15f);
mDescription.setText(mEpisode.getDescription());
if (mShowFileLocation)
mFileSource.setText(mEpisode.getAllFilepaths());
else
mFileSource.setVisibility(View.GONE);
// Set the episode air date
mAirDate.setText(MizLib.getPrettyDatePrecise(getActivity(), mEpisode.getReleasedate()));
// Set the movie rating
if (!mEpisode.getRating().equals("0.0"))
try
int rating = (int) (Double.parseDouble(mEpisode.getRating()) * 10);
mRating.setText(html.fromHtml(rating + "<small> %</small>"));
catch (NumberFormatException e)
mRating.setText(mEpisode.getRating());
else
mRating.setText(R.string.stringNA);
if (TextUtils.isEmpty(mEpisode.getDirector()) || mEpisode.getDirector().equals(getString(R.string.stringNA)))
mDirector.setVisibility(View.GONE);
else
mDirector.setText(mEpisode.getDirector());
if (TextUtils.isEmpty(mEpisode.getWriter()) || mEpisode.getWriter().equals(getString(R.string.stringNA)))
mWriter.setVisibility(View.GONE);
else
mWriter.setText(mEpisode.getWriter());
if (TextUtils.isEmpty(mEpisode.getGuestStars()) || mEpisode.getGuestStars().equals(getString(R.string.stringNA)))
mGuestStars.setVisibility(View.GONE);
else
mGuestStars.setText(mEpisode.getGuestStars());
Rest of the code
活动
public class TvShowEpisodeDetails extends MizActivity implements TvShowEpisodeDetailsFragment.TextClicked
private static final String SHOW_ID = "showId";
private ArrayList<TvShowEpisode> mEpisodes = new ArrayList<TvShowEpisode>();
private int mSeason, mEpisode;
private String mShowId, mShowTitle;
private ViewPager mViewPager;
private DbAdapterTvShowEpisodes mDatabaseHelper;
private Bus mBus;
@Override
protected int getLayoutResource()
return R.layout.viewpager_with_toolbar_overlay;
@Override
public void onCreate(Bundle savedInstanceState)
mBus = MizuuApplication.getBus();
super.onCreate(savedInstanceState);
// Set theme
setTheme(R.style.Mizuu_Theme_NoBackground);
ViewUtils.setupWindowFlagsForStatusbarOverlay(getWindow(), true);
ViewUtils.setProperToolbarSize(this, mToolbar);
mShowId = getIntent().getExtras().getString(SHOW_ID);
mSeason = getIntent().getExtras().getInt("season");
mEpisode = getIntent().getExtras().getInt("episode");
mDatabaseHelper = MizuuApplication.getTvEpisodeDbAdapter();
Cursor cursor = mDatabaseHelper.getEpisodes(mShowId);
try
while (cursor.moveToNext())
mEpisodes.add(new TvShowEpisode(this, mShowId,
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_TITLE)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_PLOT)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_SEASON)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_AIRDATE)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_DIRECTOR)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_WRITER)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_GUESTSTARS)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_RATING)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_HAS_WATCHED)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_FAVOURITE))
));
catch (Exception e)
finally
cursor.close();
final ArrayList<PlanetModel> episodeslist = new ArrayList<>();
for(TvShowEpisode e : mEpisodes)
episodeslist.add(new PlanetModel(e.mEpisode));
mShowTitle = MizuuApplication.getTvDbAdapter().getShowTitle(mShowId);
setTitle(mShowTitle);
mViewPager = (ViewPager) findViewById(R.id.awesomepager);
mViewPager.setAdapter(new TvShowEpisodeDetailsAdapter(getSupportFragmentManager()));
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener()
@Override
public void onPageSelected(int position)
for (int i=0; i<episodeslist.size(); i++)
episodeslist.get(i).setPlanetSelected(false);
episodeslist.get(position).setPlanetSelected(true);
//notify your recycler views adaper
ViewUtils.updateToolbarBackground(TvShowEpisodeDetails.this, mToolbar, 0, mEpisodes.get(position).getTitle(), Color.TRANSPARENT);
);
if (savedInstanceState != null)
mViewPager.setCurrentItem(savedInstanceState.getInt("tab", 0));
else
for (int i = 0; i < mEpisodes.size(); i++)
if (mEpisodes.get(i).getSeason().equals(MizLib.addIndexZero(mSeason)) && mEpisodes.get(i).getEpisode().equals(MizLib.addIndexZero(mEpisode)))
mViewPager.setCurrentItem(i);
SharedPreferences setPref = this.getSharedPreferences("TvShowEpisodeDetails", Context.MODE_PRIVATE);
setPref.edit().putInt("i", i).apply();
break;
@Subscribe
public void onScrollChanged(TvShowEpisodeDetailsFragment.BusToolbarColorObject object)
ViewUtils.updateToolbarBackground(this, mToolbar, object.getAlpha(),
mEpisodes.get(mViewPager.getCurrentItem()).getTitle(), object.getToolbarColor());
public void onResume()
super.onResume();
mBus.register(this);
ViewUtils.updateToolbarBackground(this, mToolbar, 0, mShowTitle, Color.TRANSPARENT);
@Override
public void onPause()
super.onPause();
mBus.unregister(this);
@Override
public boolean onOptionsItemSelected(MenuItem item)
switch (item.getItemId())
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
@Override
public void onStart()
super.onStart();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
@Override
protected void onSaveInstanceState(Bundle outState)
super.onSaveInstanceState(outState);
outState.putInt("tab", mViewPager.getCurrentItem());
@Override
public void sendText(int position)
mViewPager.setCurrentItem(position,false);
//Toast.makeText(getContext(), "Item Clicked " + text, Toast.LENGTH_SHORT).show();
private class TvShowEpisodeDetailsAdapter extends FragmentPagerAdapter
public TvShowEpisodeDetailsAdapter(FragmentManager fm)
super(fm);
@Override
public Fragment getItem(int index)
return TvShowEpisodeDetailsFragment.newInstance(mShowId, Integer.parseInt(mEpisodes.get(index).getSeason()), Integer.parseInt(mEpisodes.get(index).getEpisode()));
@Override
public int getCount()
return mEpisodes.size();
protected void onActivityResult(int requestCode, int resultCode, Intent data)
if (requestCode == 0)
if (resultCode == Activity.RESULT_OK)
setResult(Activity.RESULT_OK);
finish();
【问题讨论】:
【参考方案1】:是的,可以在 Fragment 中设置 Viewpager
。
你只需要在构造它时得到正确的FragmentManager
,即在mViewPager.setAdapter(new TvShowEpisodeDetailsAdapter(getSupportFragmentManager()));
中使用getChildFragmentManager()
来自https://developer.android.com/guide/fragments/fragmentmanager
访问 FragmentManager
在活动中访问
每个 FragmentActivity 及其子类,例如 AppCompatActivity,通过 getSupportFragmentManager() 方法。
在片段中访问
Fragment 也能够托管一个或多个子 Fragment。 在片段内部,您可以获得对 FragmentManager 的引用 通过 getChildFragmentManager() 管理片段的孩子。
【讨论】:
以上是关于是否可以在片段类中设置 ViewPager?的主要内容,如果未能解决你的问题,请参考以下文章
片段中的Tablayout + viewpager,需要清除viewpager中的edittext数据
如何确定 Fragment 何时在 ViewPager 中可见