Загрузить тот же фрагмент с разными данными в ViewPager

У меня в окне просмотра 8 фрагментов с одинаковым макетом. Фрагмент содержит представление ресайклера и текстовое представление. Моя проблема в том, что когда я инициирую фрагмент окна просмотра, все данные загружаются в самом первом фрагменте, а в остальных фрагментах ничего не отображается. Вот как я настроил свой адаптер и вьюпейджер во фрагменте.

            adapter = new SelectPlayerAdapter(getActivity(), getChildFragmentManager());

            //Set up the view pager.
            setupViewPager(pager);

 private void setupViewPager(ViewPager viewPager) {
    adapter.addFragment(new PlayersFragment(), "BATSMAN 1", batsman_1);
    adapter.addFragment(new PlayersFragment(), "BATSMAN 2", batsman_2);
    adapter.addFragment(new PlayersFragment(), "BATSMAN 3", batsman_3);
    adapter.addFragment(new PlayersFragment(), "ALL-ROUNDER 1", all_rounder_1);
    adapter.addFragment(new PlayersFragment(), "ALL-ROUNDER 2", all_rounder_2);
    adapter.addFragment(new PlayersFragment(), "WICKET-KEEPER", wicket_keeper);
    adapter.addFragment(new PlayersFragment(), "BOWLER 1", bowler_1);
    adapter.addFragment(new PlayersFragment(), "BOWLER 2", bowler_2);
    viewPager.setAdapter(adapter);
}

Вот мой класс адаптера.

public class SelectPlayerAdapter extends FragmentStatePagerAdapter {

Context context = null;
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
private final ArrayList<String> player_list = new ArrayList<>();
Gson gson;


public SelectPlayerAdapter(Context context, android.support.v4.app.FragmentManager mgr) {
    super(mgr);
    this.context = context;
}

@Override
public int getCount() {
    return mFragmentList.size();
}


@Override
public android.support.v4.app.Fragment getItem(int position) {
    Fragment player_fragment = mFragmentList.get(position);
    Bundle bundle = new Bundle();
    bundle.putString("player_position_string", player_list.get(position));
    player_fragment.setArguments(bundle);
    return player_fragment;
}


public void addFragment(android.support.v4.app.Fragment fragment, String title, ArrayList<Player> players_position_list) {
    mFragmentList.add(fragment);
    mFragmentTitleList.add(title);
    gson = new Gson();
    String players_position_string = gson.toJson(players_position_list);
    player_list.add(players_position_string);
}

@Override
public CharSequence getPageTitle(int position) {
    return mFragmentTitleList.get(position);
}

Я передаю разные массивы массивов при добавлении фрагментов и добавлении их в другой массив массивов в моем адаптере, когда вызывается элемент get, я получаю элемент из массива и передаю его в качестве аргумента этому фрагменту, но когда я запускаю это, я получаю все аргументы только изначально и ничего не происходит, когда я меняю вкладки. Я попробовал отладить и увидел, что getitem сначала вызывается только 8 раз, и ничего не происходит, когда я меняю вкладки вьюпейджера. Я пробовал фрагментировать метод newinstance и addonpagechangelistener, но получил тот же результат. Пожалуйста помоги.

Вот мой класс Players Fragment.

public class PlayersFragment extends Fragment {

private TextView player_position_text;
private TextView player_position_number_text;
private RecyclerView players_list_view;
Bundle extra;
private String players_string;
private ArrayList<Player> player_position_list;
Gson gson;

public PlayersFragment() {
    // Required empty public constructor
}

public static Fragment newInstance(Context context) {
    PlayersFragment playersFragment = new PlayersFragment();
    return playersFragment;
}

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

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.select_player_layout, container, false);

    //Get the bundle from previous fragment.
    extra = this.getArguments();

    //If bundle contains the key players string then retrieve it.
    if(extra.containsKey("player_position_string")){

        players_string = extra.getString("player_position_string", "0");
        System.out.println("players string is " + players_string);
        gson = new Gson();

        Type type = new TypeToken<List<Player>>() {
        }.getType();
        player_position_list = gson.fromJson(players_string, type);
        System.out.println("players list is " + player_position_list);
        System.out.println("players name is " + player_position_list.get(1).getName());

    }

    //If bundle does not contain string it then display a toast.
    else
    {
        // Display toast with exception.
        Toast.makeText(getActivity(), "There was some error with getting the details. Please try again later.",
                Toast.LENGTH_LONG).show();
    }

    player_position_text = view.findViewById(R.id.player_position_text);
    player_position_number_text = view.findViewById(R.id.player_position_number_text);
    players_list_view = view.findViewById(R.id.players_list_view);

    return view;
}

comment
Где ты умеешь это делать? Было бы полезно, если бы вы предоставили решение   -  person Huzaifa Asif    schedule 05.09.2019


Ответы (1)


РЕДАКТИРОВАТЬ:

Я добавил рабочую демонстрацию. Пожалуйста, проверьте это и дайте мне знать, работает ли оно.

Player.java

public class Player implements Parcelable {

    private String name;
    private int age;

    public Player(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    protected Player(Parcel in) {
        name = in.readString();
        age = in.readInt();
    }

    public static final Creator<Player> CREATOR = new Creator<Player>() {
        @Override
        public Player createFromParcel(Parcel in) {
            return new Player(in);
        }

        @Override
        public Player[] newArray(int size) {
            return new Player[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }

    @Override
    public String toString() {
        return "Player{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

PlayerFragment.java

public class PlayerFragment extends Fragment {

    private static final String ARG_PLAYERS = "arg_player";
    private Player player;

    public static PlayerFragment newInstance(Player players) {

        Bundle args = new Bundle();
        args.putParcelable(ARG_PLAYERS, players);
        PlayerFragment fragment = new PlayerFragment();
        fragment.setArguments(args);
        return fragment;
    }

        public PlayerFragment() {
            // Required empty public constructor
        }

        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Bundle args = getArguments();
            if (args != null){
                this.player = args.getParcelable(ARG_PLAYERS);
            }
            if (player == null){
                throw new IllegalArgumentException("Player list can not be null");
            }
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.fragment_player, container, false);
        }

        @Override
        public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            ((TextView)view.findViewById(R.id.txt_player)).setText(player.toString());
        }
    }

StatePagerAdapter.java

public class StatePagerAdapter extends FragmentStatePagerAdapter {

    private ArrayList<Player> players;
    private List<String> titles;

    public StatePagerAdapter(FragmentManager fm, ArrayList<Player> players, List<String> titles) {
        super(fm);
        if (players.size() != titles.size())
            throw new IllegalArgumentException("Sizes must be equal");
        this.players = players;
        this.titles = titles;
    }

    @Override
    public Fragment getItem(int position) {
        return PlayerFragment.newInstance(players.get(position));
    }

    @Override
    public int getCount() {
        return players.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return titles.get(position);
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    ViewPager viewPager;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ArrayList<Player> players = new ArrayList<>();
        players.add(new Player("a", 1));
        players.add(new Player("b", 2));
        players.add(new Player("c", 3));

        List<String> titles = new ArrayList<>(Arrays.asList("Title1", "Title2", "Title3"));

        StatePagerAdapter adapter = new StatePagerAdapter(getSupportFragmentManager(), players, titles);

        viewPager = findViewById(R.id.view_pager);

        viewPager.setAdapter(adapter);
    }
}

ПРЕДЫДУЩИЙ ОТВЕТ:

Не могли бы вы поделиться своим классом PlayersFragment и попробовать код ниже.

@Override
public android.support.v4.app.Fragment getItem(int position) {
    Fragment player_fragment = new PlayerFragment();
    Bundle bundle = new Bundle();
    bundle.putString("player_position_string", player_list.get(position));
    player_fragment.setArguments(bundle);
    return player_fragment;
}
person toffor    schedule 16.03.2018
comment
Я уже пробовал упомянутый вами код. Тот же результат. Также я добавил класс фрагментов игроков. Я просто печатаю данные, которые я получаю во фрагменте на данный момент, для целей отладки. - person mxs2649; 16.03.2018
comment
Это вроде сработало, но когда я запускаю его, я получаю первые два значения в консоли, когда я выбираю title2, я получаю третье значение, которое name = c и age = 3, и когда я выбираю заголовок 3, я ничего не получаю . После первого выбора заголовка 1 я получаю только первое значение. Второе значение отсутствует, а третий фрагмент пуст. - person mxs2649; 16.03.2018
comment
Проверяли ли вы просмотры текста в макетах фрагментов? Потому что я получил правильные результаты для каждой страницы, которую я пролистал. - person toffor; 16.03.2018
comment
Это правильно, для меня это тоже правильно видно. Хм, странно ... в методе oncreate, если я проверю его, он показывает неправильные данные, но в onviewcreated он работает отлично. Сейчас я пытаюсь использовать свой код с таким подходом. - person mxs2649; 16.03.2018
comment
Потому что FragmentPagerAdapter создает два фрагмента одновременно. Поэтому, когда вы проводите пальцем по следующему фрагменту, второй фрагмент не вызывает onCreate, потому что он уже создан, но вызывает onCreateView, потому что он только что стал видимым. Если это вам поможет, примите ответ. И вы можете узнать больше об этом поведении FragmentPagerAdapter. - person toffor; 16.03.2018
comment
Я уже сделал. Может быть, из-за моей репутации он не появляется публично, но я сделал это. Благодаря тонну. - person mxs2649; 16.03.2018