我有一个相对复杂的布局,可在一个5页的viewpager内部重用。 viewpager位于父片段中。
我的问题是,如果我不使用setOffscreenPageLimit(4)
,则在浏览页面时,viewpager会变得非常混乱,因为片段无法及时加载。缺点是,如果我使用setOffscreenPageLimit(4)
,则我的父片段需要很长的时间才能加载(大约3秒)。加载时间为空。
我想知道是否有一种方法可以在装入一些片段后使用setOffscreenPageLimit(4)
,以便可以立即查看初始页面,而其他页面则在后台加载并保存在内存中?
活动
public class MainActivity extends BaseActivity {
public static int layout;
public static ArrayList<ArrayList<Period>> bigList;
private static final int TASKS = 0;
private static final int TIMETABLE = 1;
@BindView(R.id.navigation_view)
NavigationView navigationView;
@BindView(R.id.main_content)
DrawerLayout drawerLayout;
Runnable runnable;
String themeName;
int currentFragment;
@Override
@SuppressLint("InflateParams")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
ViewGroup drawerContent = findViewById(R.id.drawer_content_container);
drawerContent.addView(getLayoutInflater().inflate(R.layout.activity_main_content, null));
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
TypedValue outValue = new TypedValue();
getTheme().resolveAttribute(R.attr.themeName, outValue, true);
themeName = (String) outValue.string;
setUpNavigationView();
layout = R.layout.fragment_timetable_page;
String layoutString = this.getSharedPreferences("prefs", Context.MODE_PRIVATE).getString("layout", "flat");
switch (layoutString) {
case "card":
layout = R.layout.fragment_timetable__page_cardview;
break;
case "flat":
layout = R.layout.fragment_timetable_page;
}
bigList = new ArrayList<>();
ArrayList<Period> periods = Util.getPeriods(this);
ArrayList<Period> monPeriods = new ArrayList<>();
ArrayList<Period> tuePeriods = new ArrayList<>();
ArrayList<Period> wedPeriods = new ArrayList<>();
ArrayList<Period> thuPeriods = new ArrayList<>();
ArrayList<Period> friPeriods = new ArrayList<>();
int[] mon = {0, 1, 2, 3, 4, 5};
int[] tue = {6, 7, 8, 9, 10, 11};
int[] wed = {12, 13, 14, 15, 16, 17};
int[] thu = {18, 19, 20, 21, 22, 23};
int[] fri = {24, 25, 26, 27, 28, 29};
for (int count = 0; count < 6; count++) {
if (periods != null && periods.size() == 30) {
monPeriods.add(periods.get(mon[count]));
tuePeriods.add(periods.get(tue[count]));
wedPeriods.add(periods.get(wed[count]));
thuPeriods.add(periods.get(thu[count]));
friPeriods.add(periods.get(fri[count]));
} else if (periods != null) {
getSharedPreferences("periods", Context.MODE_PRIVATE).edit().clear().apply();
startActivity(new Intent(this, MainActivity.class));
}
}
bigList.add(monPeriods);
bigList.add(tuePeriods);
bigList.add(wedPeriods);
bigList.add(thuPeriods);
bigList.add(friPeriods);
if (savedInstanceState == null) {
switch (Util.getInstance(this).getLastFragment()) {
case TIMETABLE:
setCurrentFragment(TIMETABLE, false);
break;
case TASKS:
setCurrentFragment(TASKS, false);
break;
}
}
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, null, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
if (runnable != null) {
runnable.run();
}
}
};
drawerLayout.addDrawerListener(mDrawerToggle);
updateNavigationDrawerHeader();
}
private void setUpNavigationView() {
int accentColor = ThemeStore.accentColor(this);
NavigationViewUtil.setItemIconColors(navigationView, ATHUtil.resolveColor(this, R.attr.icon_color, ThemeStore.textColorSecondary(this)), accentColor);
NavigationViewUtil.setItemTextColors(navigationView, ThemeStore.textColorPrimary(this), accentColor);
navigationView.setCheckedItem(R.id.nav_timetable);
navigationView.setNavigationItemSelectedListener(item -> {
drawerLayout.closeDrawers();
switchView(item.getItemId());
return true;
});
for (int i = 0; i < navigationView.getChildCount(); i++) {
navigationView.getChildAt(i).setOverScrollMode(View.OVER_SCROLL_NEVER);
}
}
private void switchView(int id) {
runnable = null;
switch (id) {
case R.id.nav_tasks:
runnable = () -> setCurrentFragment(TASKS, true);
break;
case R.id.nav_timetable:
runnable = () -> setCurrentFragment(TIMETABLE, true);
break;
case R.id.nav_settings:
new Handler().postDelayed(() -> startActivity(new Intent(getBaseContext(), SettingsActivity.class)), 200);
break;
case R.id.nav_about:
new Handler().postDelayed(() -> startActivity(new Intent(getBaseContext(), AboutActivity.class)), 200);
}
}
private void updateNavigationDrawerHeader() {
View navigationDrawerHeader = navigationView.getHeaderView(0);
StatusBarView statusBarView = navigationDrawerHeader.findViewById(R.id.status_bar);
TypedValue a = new TypedValue();
getTheme().resolveAttribute(android.R.attr.windowBackground, a, true);
int toolbarColor = ThemeStore.primaryColor(this);
if (getSharedPreferences("prefs", MODE_PRIVATE).getBoolean("flat_ui", false)) {
toolbarColor = a.data;
}
if (themeName.equals("light") && !ColorUtil.isColorLight(toolbarColor)){
statusBarView.setBackgroundColor(Color.parseColor("#26000000"));
}
TextView title = navigationDrawerHeader.findViewById(R.id.title);
title.setText(R.string.app_name);
if (!themeName.equals("light")) {
title.setTextColor(Color.WHITE);
}
}
private void setCurrentFragment(int key, boolean navDrawer) {
if ((key != currentFragment && navDrawer) || !navDrawer) {
Util.getInstance(this).setLastFragment(key);
Fragment fragmentToInflate;
switch (key) {
case TASKS:
navigationView.setCheckedItem(R.id.nav_tasks);
fragmentToInflate = TasksFragment.newInstance(navDrawer);
break;
case TIMETABLE:
navigationView.setCheckedItem(R.id.nav_timetable);
if (Util.getPeriods(this) != null) {
fragmentToInflate = TimetableFragment.newInstance(navDrawer);
} else {
fragmentToInflate = TimetableNotCompletedFragment.newInstance(navDrawer);
}
break;
default:
fragmentToInflate = TimetableFragment.newInstance(navDrawer);
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragmentToInflate, null).commit();
currentFragment = key;
}
}
@Override
public void onBackPressed() {
if (drawerLayout.isDrawerOpen(navigationView)) {
drawerLayout.closeDrawer(navigationView);
} else {
super.onBackPressed();
}
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
if (drawerLayout.isDrawerOpen(navigationView)) {
drawerLayout.closeDrawer(navigationView);
} else {
drawerLayout.openDrawer(navigationView);
}
return true;
}
return super.onOptionsItemSelected(item);
}
}
父片段
public class TimetableFragment extends BaseFragment {
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.tabs)
TabLayout tabs;
@BindView(R.id.appBarLayout)
AppBarLayout appBarLayout;
@BindView(R.id.pager)
ViewPager pager;
private Unbinder unbinder;
public TimetableFragment() {
}
public static TimetableFragment newInstance(boolean navDrawer) {
TimetableFragment fragment = new TimetableFragment();
Bundle args = new Bundle();
args.putBoolean("navDrawer", navDrawer);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_timetable, container, false);
unbinder = ButterKnife.bind(this, view);
setRetainInstance(true);
SectionsPagerAdapter adapter = new SectionsPagerAdapter(getChildFragmentManager());
pager.setAdapter(adapter);
pager.setOffscreenPageLimit(4);
tabs.setupWithViewPager(pager);
getMainActivity().setToolbars(toolbar, appBarLayout);
toolbar.setNavigationIcon(R.drawable.ic_menu_white);
tabs.setBackgroundColor(toolbarColor);
int normalColor = ToolbarContentTintHelper.toolbarSubtitleColor(getContext(), toolbarColor);
int selectedColor = ToolbarContentTintHelper.toolbarTitleColor(getContext(), toolbarColor);
toolbar.setTitleTextColor(selectedColor);
tabs.setTabTextColors(normalColor, selectedColor);
tabs.setSelectedTabIndicatorColor(ThemeStore.accentColor(getContext()));
if (getContext().getSharedPreferences("prefs", Context.MODE_PRIVATE).getBoolean("smart_opening", true)) {
pager.setCurrentItem(getTab());
}
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
@Override
public void onResume() {
super.onResume();
toolbar.setTitle("Timetable");
}
private int getTab() {
int tab = 0;
switch (Calendar.getInstance().get(DAY_OF_WEEK)) {
case TUESDAY:
tab = 1;
break;
case WEDNESDAY:
tab = 2;
break;
case THURSDAY:
tab = 3;
break;
case FRIDAY:
tab = 4;
}
Calendar currentTime = Calendar.getInstance();
if (currentTime.after(Util.periodEndTime(8)) && Calendar.getInstance().get(DAY_OF_WEEK) != SATURDAY && Calendar.getInstance().get(DAY_OF_WEEK) != SUNDAY) {
tab++;
}
return tab;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_timetable, menu);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == R.id.action_configure) {
startActivity(new Intent(getContext(), DefineSubjectsActivity.class));
}
return super.onOptionsItemSelected(item);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
if (Util.isRTL()) {
position = position - getCount();
}
return TimetableFragmentPage.newInstance(position, MainActivity.layout);
}
public int getCount() {
return 5;
}
@Override
public CharSequence getPageTitle(int position) {
return getResources().getStringArray(R.array.short_days)[position];
}
}
}
子片段(页面)
public class TimetableFragmentPage extends Fragment implements View.OnClickListener {
private View[] periods = new View[6];
private TextView[] idents = new TextView[6];
private TextView[] subjects = new TextView[6];
private TextView[] details = new TextView[6];
private IconImageView[] icons = new IconImageView[6];
private IconImageButton[] infoIcons = new IconImageButton[6];
private int dayOfWeek;
public TimetableFragmentPage() {
}
static TimetableFragmentPage newInstance(int day, int layout) {
TimetableFragmentPage fragment = new TimetableFragmentPage();
Bundle args = new Bundle();
args.putInt("dayOfWeek", day);
args.putInt("layout", layout);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
int layout = getArguments().getInt("layout");
View view = inflater.inflate(layout, container, false);
ButterKnife.bind(this, view);
setRetainInstance(true);
periods[0] = view.findViewById(R.id.P1);
periods[1] = view.findViewById(R.id.P2);
periods[2] = view.findViewById(R.id.P3);
periods[3] = view.findViewById(R.id.P4);
periods[4] = view.findViewById(R.id.P5);
periods[5] = view.findViewById(R.id.P6);
return view;
}
@Override
public void onStart() {
super.onStart();
setUpLayout();
}
private void setUpLayout(){
dayOfWeek = getArguments().getInt("dayOfWeek");
ArrayList<Period> periodData = MainActivity.bigList.get(dayOfWeek);
for (int count = 0; count < 6; count++) {
idents[count] = periods[count].findViewById(R.id.periodIdent);
subjects[count] = periods[count].findViewById(R.id.periodSub);
details[count] = periods[count].findViewById(R.id.periodDetails);
icons[count] = periods[count].findViewById(R.id.icon);
infoIcons[count] = periods[count].findViewById(R.id.periodInfo);
idents[count].setTextColor(ThemeStore.accentColor(getContext()));
icons[count].setImageResource(periodData.get(count).getSubject(getContext()).getSubjectIcon());
subjects[count].setText(periodData.get(count).getSubject(getContext()).getSubjectName());
Teacher teacher = new Teacher("teacherFirstName", "teacherLastName", "teacherTitle", getContext());
Room room = new Room("roomPrefix", "room", getContext());
for (Subject subject : Util.getSubjects(getContext())) {
for (int index = 0; index < subject.getTeachers().size(); index++) {
if (subject.getTeachers().get(index).getTeacherKey() == periodData.get(count).getTeacherKey()) {
teacher = subject.getTeachers().get(index);
break;
}
}
for (int index = 0; index < subject.getRooms().size(); index++) {
if (subject.getRooms().get(index).getRoomKey() == periodData.get(count).getRoomKey()) {
room = subject.getRooms().get(index);
break;
}
}
}
details[count].setText(room.getRoomPrefix() + room.getRoom() + ", " + teacher.getTeacherTitle() + " " + teacher.getTeacherLastName());
if (infoIcons[0] != null) {
idents[count].setText(getResources().getStringArray(R.array.periods)[count]);
infoIcons[count].setOnClickListener(this);
} else {
idents[count].setText(String.valueOf(count + 1));
periods[count].setOnClickListener(this);
}
}
}
@Override
public void onClick(View v) {
Intent view = new Intent(getContext(), SubjectViewActivity.class);
int[] basePeriod = {
0,
6,
12,
18,
24
};
int period = 0;
for (int count = 0; count < 6; count++) {
if (v == infoIcons[count] || v == periods[count]) {
period = count;
}
}
view.putExtra("period", basePeriod[dayOfWeek] + period);
startActivity(view);
}
}
答案 0 :(得分:0)
我建议的第一件事是尽力优化代码。从用户的角度来看,花3秒来加载页面是非常糟糕的。
但是,您可以使用ViewTreeObserver.OnGlobalLayoutListener
来了解视图何时完成加载。在看到您实际上拥有托管ViewPager的片段之前,我写了一个简单的示例,但是概念仍然相同。
基本上,这将在初始页面完全加载后设置屏幕外页面限制。
//YourActivity
private ViewPager _viewPager;
public ViewPager getViewPager()
{
return this._viewPager;
}
//First fragment
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
rootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
((YourActivity)_context).getViewPager().setOffscreenPageLimit(4);
}
});