【问题标题】:First Fragment View not loading when navigate from third fragment从第三个片段导航时未加载第一个片段视图
【发布时间】:2019-07-05 10:03:54
【问题描述】:

在这里,当我到达第一个片段时,所有视图都已加载并滚动,但是当我来自第三个片段时,即来自其他一些活动时,我需要进入第三个片段,并且当导航到第一个片段时,视图未加载,这使得不可滚动. Firstfragment xml 包含 recyclerview 和 Group 元素。

MyActivity 类:

    MyAdapter adapter = new MyAdapter(this, getSupportFragmentManager(), fragments);

        viewPager.setOffscreenPageLimit(3);

        viewPager.setAdapter(adapter);

        tabLayout.setupWithViewPager(viewPager);

//MyAdapter

    public class MyAdapter extends FragmentPagerAdapter {

    private Context mContext;
    private List<Fragment> fragmentList ;

    public MyAdapter(Context context, FragmentManager fm,List<Fragment> fragmentList) {
        super(fm);
        mContext = context;
        this.fragmentList = fragmentList;
    }

    @Override
    public Fragment getItem(int position) {
        return  fragmentList.get(position);
    }

    @Override
    public int getCount() {
        return 3;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return mContext.getString(R.string.firstfragmentname);
            case 1:
                return mContext.getString(R.string.seconsfrag);
            case 2:
                return mContext.getString(R.string.thirdfrag);

            default:
                return null;
        }
      }
    }

//XML has custom viewpager
<ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="@dimen/headerHeight"
            android:layout_marginBottom="@dimen/footerHeight"
            android:fadingEdgeLength="0dp">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/dp_30_60"
                android:layout_marginTop="10dp"
                android:layout_marginEnd="@dimen/dp_30_60"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/sp_header"
                    style="@style/pageTitle"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="10dp"
                    android:text="@string/my_bill" />

                <com.view.Tab
                    android:id="@+id/tab_custom"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/tab_height" />

                <com.custom.CustomViewPager
                    android:id="@+id/sp_viewpager"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginStart="@dimen/dp_10_53"
                    android:layout_marginTop="4dp"
                    android:layout_marginEnd="@dimen/dp_10_53"
                    android:layout_marginBottom="4dp" />
            </LinearLayout>
        </ScrollView>

//CustomViepager

    public class CustomViepager extends ViewPager {

    public CustomViepager(Context context) {
        super(context);
        initPageChangeListener();
    }

    public CustomViepager(Context context, AttributeSet attrs) {
        super(context, attrs);
        initPageChangeListener();
    }

    private void initPageChangeListener() {
        addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                requestLayout();
            }
        });
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        View child = getChildAt(getCurrentItem());
        if (child != null) {
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
        }
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }

    @Override
    public void setCurrentItem(int item) {
        super.setCurrentItem(item, false);
    }

    @Override
    public void setCurrentItem(int item, boolean smoothScroll) {
        super.setCurrentItem(item, false);
     }
    }

【问题讨论】:

  • 使用 FragmentStatePagerAdapter 代替 FragmentStateAdapter
  • 您需要自定义视图寻呼机
  • @LakhwinderSingh 如果我不使用带有 onMeasure 覆盖的 CustomViewpager,则无法看到布局,它完全是空白屏幕。
  • 如果您不使用自定义视图寻呼机,您认为会发生什么,因为我不明白 onMesuare 的使用,请您指定

标签: android android-fragments android-viewpager fragmentpageradapter


【解决方案1】:

使用简单的视图寻呼机并尝试像这样使用它

自定义页面适配器

import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter

class MyPagerAdapter(fm: FragmentManager, behaviour: Int) : FragmentStatePagerAdapter(fm, behaviour) {

    private val mFragmentList = ArrayList<Fragment>()

    override fun getItem(position: Int): Fragment {
        return mFragmentList[position]
    }

    override fun getCount(): Int {
        return mFragmentList.size
    }

    fun addFragment(fragment: Fragment) {
        mFragmentList.add(fragment)
    }


}

在活动/片段中

private var mAdapter: MyPagerAdapter? = null

onCreate

mAdapter = MyPagerAdapter(getChildFragmentManager(), FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
mAdapter?.addFragment(YOUR_FIRST_FRAGMENT)
mAdapter?.addFragment(YOUR_SECOND_FRAGMENT)
mAdapter?.addFragment(YOUR_THIRD_FRAGMENT)

sp_viewpager.offscreenPageLimit = 3
sp_viewPAger.adapter = mAdapter

当你想降落在想要的位置,上面的代码写完

sp_viewpager.setCurrentItem(1/2/3,true/false)

【讨论】:

    【解决方案2】:

    @LakwinderSingh answer这个问题很完美。

    只想强调一件事,主要的技巧或真正的问题是offscreen page limit 是寻呼机在当前片段的左侧或右侧创建的片段数,默认情况下此值为一。

    这就是为什么当我们滚动到第三个 Fragment 时它不会加载任何内容,因为加载第三个 Fragment 需要同时向左侧加载 2 个 Fragment,通过更改 offscreen page limit 值我们可以确定 Fragment 的数量在这种情况下,它会在特定时间加载,即 2。

    如果我们在上面做了,那么我们还必须将 PagerAdapter 的默认函数 destroyItem() 覆盖为一个没有 super 的空函数,这样就不会同时销毁和创建太多片段,因为这会导致滑动不稳定或将片段留空。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-07
      • 2021-11-30
      • 1970-01-01
      • 1970-01-01
      • 2022-12-10
      相关资源
      最近更新 更多