加载几页后如何设置setOffscreenPageLimit()?

时间:2018-11-05 10:28:10

标签: android android-fragments android-viewpager fragment

我有一个相对复杂的布局,可在一个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);
    }
}

1 个答案:

答案 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);
    }
});