ListFragment не отображает данные повторно при вызове из FragmentStatePagerAdapter.

Вот моя иерархия пользовательского интерфейса:

Основной фрагмент -> Фрагмент с ActionBar.TabListener -> Фрагмент с FragmentStatePagerAdapter -> ListFragment

Проблема в том, что ListFragment отображается при первом переходе на вкладку ListFragment, но не отображается во второй раз (поэтому при переходе на вкладку 2 он отображается, но затем при переходе на вкладку 1, а затем на вкладку 2 это не так) t отображать себя. ListFragment находится на вкладке 2).

Этот макет отлично работает, если я удалю FragmentStatePagerAdapter, но теперь моему проекту требуются страницы, поэтому мне нужно было добавить FragmentStatePagerAdapter, чтобы заставить работать разбиение по страницам.

Однако на данный момент я действительно не знаю, в чем проблема. Я не знаю, связана ли проблема с FragmentStatePagerAdapter, ListFragment или телефон просто по какой-то причине теряет данные ListFragment. Я знаю, что getItem в FragmentStatePagerAdapter не вызывается снова при переключении вкладок.

Вот мой код для TrendsPagerHolder и FragmentStatePagerAdapter (как внутренний класс):

import java.util.ArrayList;
import java.util.Collections;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Fragment;
import android.os.Bundle;
import android.app.FragmentManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.support.v13.app.FragmentPagerAdapter;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class TrendsPagerHolder extends Fragment
{
private ArrayList<String>testArray = new ArrayList<String>();
private Context context;
private SharedPreferences preferences;
private Bundle applicationStatus;

// The number of pages to display
private static final int NUM_PAGES = 3;

private ViewPager pager;

//The pager adapter, which provides the pages to the view pager widget
private PagerAdapter pagerAdapter;

@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    context = getActivity().getApplicationContext();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
{       
    context = inflater.getContext();
    applicationStatus = savedInstanceState;
    View rootView = (View) inflater.inflate(R.layout.trends_screen_slider, container, false);

    System.out.println("in TrendsPagerHolder onCreateView");

    pager = (ViewPager) rootView.findViewById(R.id.trends_pager);   
    pagerAdapter = new ScreenSlidePagerAdapter(getFragmentManager());   
    pager.setAdapter(pagerAdapter);
    pager.setCurrentItem(0);

    return rootView;
}

public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter
{       
    TrendsLV[] arrayOfTrendsFragments;

    public ScreenSlidePagerAdapter(FragmentManager fragmentManager)
    {

        super(fragmentManager);

        testArray.add("One");
        testArray.add("Two");
        testArray.add("Three");

        arrayOfTrendsFragments = new TrendsLV[NUM_PAGES];
        arrayOfTrendsFragments[0] = new TrendsLV(testArray, 0);
        arrayOfTrendsFragments[1] = new TrendsLV(testArray, 1);
        arrayOfTrendsFragments[2] = new TrendsLV(testArray, 2);
    }

    @Override
    public Fragment getItem(int position) 
    {                       
        System.out.println("in getItem. Position = " + position);
        return arrayOfTrendsFragments[position];
    }

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

Вот код моего ListFragment:

import java.util.ArrayList;
import java.util.Collections;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ListFragment;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.os.AsyncTask.Status;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class TrendsLV extends ListFragment
{
private Context context;
private ArrayList<String>testArray;
private Bundle applicationStatus;
private int pageIndex;

public TrendsLV(ArrayList<String> test, int index)
{
    testArray = test;
    pageIndex = index;
}

public TrendsLV()
{
    // required
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{       
    context = inflater.getContext();
    applicationStatus = savedInstanceState;

    System.out.println("in TrendsLV onCreateView");

    if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
    {                               
            if (testArray != null)
            {
                TrendsListAdapter adapter = new TrendsListAdapter(context, testArray, pageIndex);
                setListAdapter(adapter);
            }

    }
    return super.onCreateView(inflater, container, savedInstanceState);
}
}//end class TrendsLV

А вот код адаптера, который вызывается из ListFragment:

    import java.util.ArrayList;
    import android.content.Context;
    import android.graphics.Color;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;
    import android.widget.ImageView;
    import android.widget.TextView;

    public class TrendsListAdapter extends ArrayAdapter<String>
    {
    private Context context;
    private ArrayList<String>testArray;
    private int pageIndex;

    public TrendsListAdapter (Context c, ArrayList<String> test, int index)
    {
        super(c, R.layout.trends_row, test);
        context = c;
        testArray = test;

        pageIndex = index;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
    {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View rowView = inflater.inflate(R.layout.trends_row, parent, false);
        TextView label_totalArea = (TextView) rowView.findViewById(R.id.trends_labelTotalArea);
        label_totalArea.setText(context.getResources().getString(R.string.stringTotalArea));

        return rowView;
    }
}

Дайте мне знать, если вам нужна дополнительная информация для решения этой проблемы. Я тестирую его на устройстве с Android 4.4.4.

Спасибо.


comment
Никто через день?? :(   -  person TooManyEduardos    schedule 20.11.2014


Ответы (2)


Если вы накачиваете Fragment внутри Fragment, вы должны использовать getChildFragmentManager() вместо getFragmentManager().

Вот документ: http://developer.android.com/reference/android/app/Fragment.html#getChildFragmentManager()

 public class TrendsPagerHolder extends Fragment
{
private ArrayList<String>testArray = new ArrayList<String>();
private Context context;
private SharedPreferences preferences;
private Bundle applicationStatus;

// The number of pages to display
private static final int NUM_PAGES = 3;

private ViewPager pager;

//The pager adapter, which provides the pages to the view pager widget
private PagerAdapter pagerAdapter;

@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    context = getActivity().getApplicationContext();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
{       
    context = inflater.getContext();
    applicationStatus = savedInstanceState;
    View rootView = (View) inflater.inflate(R.layout.trends_screen_slider, container, false);

    System.out.println("in TrendsPagerHolder onCreateView");

    pager = (ViewPager) rootView.findViewById(R.id.trends_pager);   
    pagerAdapter = new ScreenSlidePagerAdapter(getChildFragmentManager());   
    pager.setAdapter(pagerAdapter);
    pager.setCurrentItem(0);

    return rootView;
}
person Abhishek V    schedule 23.11.2014
comment
В каком классе должны быть сделаны эти изменения? - person TooManyEduardos; 23.11.2014
comment
@TooManyEduardos TrendsPagerHolder. Отредактировал ответ. - person Abhishek V; 23.11.2014
comment
Я получаю эту ошибку: Для вызова требуется уровень API 17 (текущий минимум 15): android.app.Fragment#getChildFragmentManager Есть ли способ использовать это с существующим уровнем 15, в котором я уже развернул свое приложение? - person TooManyEduardos; 24.11.2014
comment
Кроме того, даже при переходе на getChildFragmentManager() проблема сохраняется после поворота телефона. - person TooManyEduardos; 24.11.2014
comment
Используйте класс Fragment из библиотеки поддержки v4 для поддержки более ранних версий Android. - person Abhishek V; 24.11.2014
comment
А что касается проблемы с вращением, вы загружаете данные только в том случае, если ориентация портретная? Проверить условие внутри TrendsLV класса - if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) - person Abhishek V; 24.11.2014
comment
Да, у меня есть данные, сохраненные при вращении. Данные отображаются в альбомной ориентации, но когда вы возвращаетесь к портретной ориентации, в таблице не отображаются страницы 1 и 2 средства просмотра. Появится страница 3, и если вы прокрутите назад к страницам 1 и 2, появится страница 1. Страница 2 никогда не появляется после ротации. Это очень странно и очень раздражает - person TooManyEduardos; 24.11.2014

Я думаю, вам следует создать экземпляр ListFragment и использовать этот экземпляр в FragmentStatePagerAdapter.. что-то вроде этого..

В своем классе TrendsLV удалите конструктор и добавьте метод ниже, чтобы создать экземпляр фрагмента.

public static TrendsLV newInstance(ArrayList<String> test, int index) {
    TrendsLV fragment = new TrendsLV();
     testArray = test;
     pageIndex = index;
    return fragment;
}

Затем обновите свой ScreenSlidePagerAdapter следующим образом.

    public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter
{       
    TrendsLV[] arrayOfTrendsFragments;

    public ScreenSlidePagerAdapter(FragmentManager fragmentManager)
    {

        super(fragmentManager);

        testArray.add("One");
        testArray.add("Two");
        testArray.add("Three");

        arrayOfTrendsFragments = new TrendsLV[NUM_PAGES];
        arrayOfTrendsFragments[0] = TrendsLV.newInstance(testArray, 0);
        arrayOfTrendsFragments[1] = TrendsLV.newInstance(testArray, 1)
        arrayOfTrendsFragments[2] = TrendsLV.newInstance(testArray, 2)
    }

    @Override
    public Fragment getItem(int position) 
    {                       
        System.out.println("in getItem. Position = " + position);
        return arrayOfTrendsFragments[position];
    }

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

или вместо создания массива фрагментов.. вы можете заменить метод getItem() следующим образом..

   public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter
{       


    public ScreenSlidePagerAdapter(FragmentManager fragmentManager)
    {

        super(fragmentManager);

        testArray.add("One");
        testArray.add("Two");
        testArray.add("Three");

    }

    @Override
    public Fragment getItem(int position) 
    {                       
        System.out.println("in getItem. Position = " + position);

        Fragment instanceFragment = null;

        switch (position) {
        case 0:
            instanceFragment =TrendsLV.newInstance(testArray, 0);;

            break;
        case 1:
            instanceFragment =TrendsLV.newInstance(testArray, 1);;

            break;
        case 2:
            instanceFragment =TrendsLV.newInstance(testArray, 2);;

            break;
        default:
            break;
        }
        return instanceFragment;
    }

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

Я не знаю, для чего нужен testArray, поэтому я не вносил в него никаких изменений.

Надеюсь, поможет..!! :)

person iMDroid    schedule 26.11.2014
comment
так что ваше предложение состоит в том, чтобы удалить методы onCreate и все, что с этим связано, это правильно? - person TooManyEduardos; 26.11.2014
comment
Если я удалю адаптер из TrendsLV, как я буду вызывать содержимое представления списка? - person TooManyEduardos; 26.11.2014
comment
Нет, я предлагаю удалить конструктор TrendLV и добавить метод newInstance(). по ошибке я написал адаптер вместо конструктора. - person iMDroid; 27.11.2014
comment
Извините, это тоже не сработало. После поворота устройства TrendsLV не отображается - person TooManyEduardos; 29.11.2014