【问题标题】:Android ViewPager with FragmentPageAdapter - only last fragment page is visible带有 FragmentPageAdapter 的 Android ViewPager - 只有最后一个片段页面可见
【发布时间】:2016-09-10 07:03:48
【问题描述】:

我正在使用带有 FragmentPagerAdapter 的 ViewPager。每个页面都是同一个 Fragment 类的一个实例,我总是使用固定数量的 7 个页面(从今天开始的星期几)。调试显示所有片段都被创建并且在创建时具有正确的数据。一件有趣的事情是,虽然适配器按照 0、1、2...6 的顺序创建片段,但片段的 onCreateView 是按 6、0、1、2...5 的顺序调用的。

当运行应用程序并打开这个活动时,第一个片段页面是空白的,然后我可以滑动选项卡,看到除了最后一个页面之外所有页面都是空白的。但是,最后一页没有显示最后一天的数据,它显示的是比它应该早一天的数据,即倒数第二组数据。

我复制了另一个我拥有的 ViewPager / FragmentPagerAdapter,虽然它只有 3 页并且每个页面使用不同的 Fragment。

我没有看到我做错了什么,我已经搜索了一整天,还没有找到答案。这里很多类似的问题都是通过使用 FragmentStatePagerAdapter 而不是 FragmentPagerAdapter 来解决的。我已经尝试过了,它的行为与当前完全相同。

这是托管 ViewPager 的活动:

public class ForecastFaveRowClickedActivity extends AppCompatActivity {

    String distName = "";
    public List<ForecastEntry> forecastEntries = new ArrayList<>();
    ForecastPagerAdapter adapterViewPager;


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_forecast_detail);                

        // get the districts from the main activity
        Bundle bundle = getIntent().getExtras();            
        distName = bundle.getString("districtName");
        if (bundle.containsKey("forecastData")) {
            forecastEntries = bundle.getParcelableArrayList("forecastData");
        }                                

        Collections.sort(forecastEntries);


        // set up viewpager and display the first tab

        // ViewPager for tabs
        ViewPager viewPager = (ViewPager) findViewById(R.id.forecast_pager);
        adapterViewPager = new ForecastPagerAdapter(getSupportFragmentManager(), ForecastFaveRowClickedActivity.this);
        viewPager.setOffscreenPageLimit(7);

        // set the tab titles based on the forecast list for this district            
        String[] days = new String[7];
        int count = 0;
        for (ForecastEntry forecastEntry : forecastEntries) {
            days[count] = forecastEntry.forecastDay.substring(0,3);
            count++;
        }
        adapterViewPager.setTabTitles(days);

        viewPager.setAdapter(adapterViewPager);
        //viewPager.setCurrentItem(0);  // set to today's tab to start with            

        // give the tab layout to the viewpager
        TabLayout tabLayout = (TabLayout) findViewById(R.id.forecast_sliding_date_tabs);
        tabLayout.setupWithViewPager(viewPager);

    }

    // class for view pager adapter

    public class ForecastPagerAdapter extends FragmentPagerAdapter {
        private int NUM_ITEMS = 7;
        private String tabTitles[] = new String[7];
        private Context context;            

        public ForecastPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        public ForecastPagerAdapter(FragmentManager fragmentManager, Context context) {
            super(fragmentManager);
            this.context = context;
        }

        // returns total # of pages
        @Override
        public int getCount() {
            return NUM_ITEMS;
        }

        // returns the fragment to display for that page
        @Override
        public Fragment getItem(int position) {
            Fragment frag = new Fragment();
            ForecastEntry forecastEntry;
            Log.v("Fragment.getItem", Integer.toString(position));
            forecastEntry = ((ForecastFaveRowClickedActivity)context).forecastEntries.get(position);

            frag = FragmentForecastDay.newInstance(position, forecastEntry);                    
            return frag;                    
        }

        // returns the page title for the top indicator
        @Override
        public CharSequence getPageTitle(int position) {
            return tabTitles[position];
        }

        public void setTabTitles(String[] days) {
            tabTitles = Arrays.copyOf(days, days.length);
        }    
    }        
}

这是该活动的布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
                                                 xmlns:app="http://schemas.android.com/apk/res-auto"
                                                 xmlns:tools="http://schemas.android.com/tools"
                                                 android:layout_width="match_parent"
                                                 android:layout_height="match_parent"
                                                 android:fitsSystemWindows="true"
                                                 tools:context="com.districtoverview.ForecastFaveRowClickedActivity">


    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:titleTextColor="@color/colorWhite"
            android:elevation="4dp"
            android:theme="@style/AppTheme.AppBarOverlay"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
    </android.support.design.widget.AppBarLayout>            

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="6dp"
        android:paddingTop="6dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:context="com.districtoverview.ForecastFaveRowClickedActivity"
        tools:showIn="@layout/activity_forecast_detail"
        android:orientation="vertical">

        <android.support.design.widget.TabLayout
            android:id="@+id/forecast_sliding_date_tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:paddingBottom="2dp"
            android:paddingTop="2dp"
            app:tabMode="scrollable"
            app:tabGravity="fill"
            style="@style/customForecastTabLayout" />

        <android.support.v4.view.ViewPager
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/forecast_pager"
            android:layout_width="match_parent"
            android:layout_height="0px"
            android:layout_weight="1"
            android:background="@android:color/white"
            tools:context="com.districtoverview.ForecastFaveRowClickedActivity">
        </android.support.v4.view.ViewPager>                
    </LinearLayout>

</android.support.design.widget.CoordinatorLayout>

这是 Fragment 类的代码。

public class FragmentForecastDay extends Fragment {

    String label;
    int page;
    ForecastEntry forecastEntry;

    public static FragmentForecastDay newInstance(int page, ForecastEntry forecastEntry) {            
        FragmentForecastDay fragment = new FragmentForecastDay();
        Bundle args = new Bundle();
        args.putParcelable("forecastEntry", forecastEntry);
        args.putInt("page", page);
        fragment.setArguments(args);    
        return fragment;
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_forecast_day, container, false);                    

        page = getArguments().getInt("page", 0);
        forecastEntry = getArguments().getParcelable("forecastEntry");

        return view;            
    }


    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {

        super.onViewCreated(view, savedInstanceState);

        TextView headerDistNameTV = (TextView) getActivity().findViewById(R.id.dist_name_header_text);
        headerDistNameTV.setText(parentActivity.distName);

        TextView headerForecastDateTV = (TextView) getActivity().findViewById(R.id.forecast_date_header_text);            
        headerForecastDateTV.setText(forecastEntry.forecastDate);

        TextView headerTotalTechsTV = (TextView) getActivity().findViewById(R.id.total_techs_header_text);                        headerTotalTechsTV.setText(Double.toString(forecastEntry.totalTechs));

        TextView headerDayShiftTV = (TextView) getActivity().findViewById(R.id.day_shift_header_text);
        headerDayShiftTV.setText("Day Shift");

        TextView dayExpectedTechsTV = (TextView) getActivity().findViewById(R.id.day_shift_expected_text);            
        String dayExpectedTechs = "Expected " + Double.toString(forecastEntry.expectedTechs);
        dayExpectedTechsTV.setText(dayExpectedTechs);                

        TextView headerAfterHoursTV = (TextView) getActivity().findViewById(R.id.after_hours_header_text);
        headerAfterHoursTV.setText("After Hours");

        TextView afterHoursExpectedTechsTV = (TextView) getActivity().findViewById(R.id.day_shift_expected_text);    
        String afterHoursExpectedTechs = "Expected " + Double.toString(forecastEntry.afterHoursExpected);
        afterHoursExpectedTechsTV.setText(afterHoursExpectedTechs);                    
    }        
}

这是片段布局:

<?xml version="1.0" encoding="utf-8"?>

    <TableLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/forecast_day_table_layout"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.90"
        android:paddingTop="4dp"
        android:paddingBottom="4dp"
        android:paddingLeft="4dp"
        android:paddingRight="4dp"
        android:weightSum="1">
      <TableRow
            android:id="@+id/row_dist_name_header"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0.50">
            <TextView
                android:id="@+id/dist_name_header_text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="#000"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:paddingBottom="5dp" />
      </TableRow>
      <TableRow
            android:id="@+id/row_date_header"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0.50">
            <TextView
                android:id="@+id/forecast_date_header_text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="#000"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:paddingBottom="5dp" />
      </TableRow>
      <TableRow
          android:id="@+id/row_total_techs_header"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_weight="0.50">
          <TextView
              android:id="@+id/total_techs_header_text"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:textColor="#000"
              android:textAppearance="?android:attr/textAppearanceLarge"
              android:paddingBottom="5dp" />
      </TableRow>
      <TableRow
          android:id="@+id/row_total_techs"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_weight="0.50">
          <TextView
              android:id="@+id/total_techs_text"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:textColor="#000"
              android:textAppearance="?android:attr/textAppearanceLarge"
              android:paddingBottom="5dp" />
      </TableRow>
      <TableRow
          android:id="@+id/row_day_shift_header"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_weight="0.50">
          <TextView
              android:id="@+id/day_shift_header_text"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:textColor="#000"
              android:textAppearance="?android:attr/textAppearanceLarge"
              android:paddingBottom="5dp" />
      </TableRow>
      <TableRow
          android:id="@+id/row_day_shift_expected"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_weight="0.50">
          <TextView
              android:id="@+id/day_shift_expected_text"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:textColor="#000"
              android:textAppearance="?android:attr/textAppearanceLarge"
              android:paddingBottom="5dp" />
      </TableRow>          
      <TableRow
          android:id="@+id/row_after_hours_header"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_weight="0.50">
          <TextView
              android:id="@+id/after_hours_header_text"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:textColor="#000"
              android:textAppearance="?android:attr/textAppearanceLarge"
              android:paddingBottom="5dp" />
      </TableRow>
      <TableRow
          android:id="@+id/row_after_hours_expected"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_weight="0.50">
          <TextView
              android:id="@+id/after_hours_expected_text"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:textColor="#000"
              android:textAppearance="?android:attr/textAppearanceLarge"
              android:paddingBottom="5dp" />
      </TableRow>
  </TableLayout>

【问题讨论】:

    标签: android android-viewpager android-tablayout fragmentpageradapter


    【解决方案1】:

    这是由于我不正确地使用 getActivity() 而不是视图造成的。我已经从位于主要活动上的另一组滑动选项卡中复制了代码,但该组位于片段内部。我需要参考父片段的视图。

    例如:

    (TextView) getActivity().findViewById(R.id.dist_name_header_text);
    

    应该是这样的:

    (TextView) view.findViewById(R.id.dist_name_header_text);
    

    一旦我进行了这个更改,所有在视图分页器中使用的子片段都会正确显示。

    【讨论】:

    • 脱帽致敬,浪费我的 8-10 小时进行搜索误导,
    【解决方案2】:

    一个潜在的问题可能是在创建viewpager时没有正确创建所有七个片段。因此您的活动代码如下所示

    //设置viewpager并显示第一个标签

        // ViewPager for tabs
        ViewPager viewPager = (ViewPager) findViewById(R.id.forecast_pager);
        adapterViewPager = new ForecastPagerAdapter(getSupportFragmentManager(), ForecastFaveRowClickedActivity.this);
    
        viewPager.setOffscreenPageLimit(7);
    

    【讨论】:

    • 我移动了该行,正如您在此处显示的那样,但不幸的是它对应用程序的行为没有影响。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-12
    • 2012-11-17
    相关资源
    最近更新 更多