ArrayList Удваивайте его размер каждый раз, когда я возвращаюсь к фрагменту - PullRequest
0 голосов
/ 02 октября 2018

Я новый разработчик для Android, и я попытался создать приложение для туристов "

. В моем приложении есть HomeFragment с тремя кнопками:" Достопримечательности "," События "," Гостиницы "

*.1004 *

}

, поскольку все содержимое одинаковое (отличается только название категории). Я решил использовать MasterFragment, чтобы не дублировать код для каждой категории.

Все«Данные» создается в HomeFragment, и каждый раз, когда пользователь нажимает на одну из кнопок, приложение создает новый MasterFragment и отправляет ему данные в Bundle, чтобы сообщить ему, какие данные ему нужно показать.

Вот так выглядит «MasterFragment»:

public class MasterFragment extends Fragment {

private ArrayList<Category> mData;

public MasterFragment() {
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle bundle) {
    // Inflate the layout for this fragment
    View rootView = inflater.inflate(R.layout.item_list, container, false);
    mData = (ArrayList<Category>)getArguments().getSerializable("Data");

    // Create an {@link WordAdapter}, whose data source is a list of {@link Category}s. The
    // adapter knows how to create list items for each item in the list.
    CategoryAdapter adapter = new CategoryAdapter(getActivity(), mData, R.color.colorAccent);

    // Find the {@link ListView} object in the view hierarchy of the {@link Activity}.
    // There should be a {@link ListView} with the view ID called list, which is declared in the
    // word_list.xml layout file.
    ListView listView = (ListView) rootView.findViewById(R.id.list);

    // Make the {@link ListView} use the {@link WordAdapter} we created above, so that the
    // {@link ListView} will display list items for each {@link Word} in the list.
    listView.setAdapter(adapter);


    return rootView;
}

}

Все работает нормально, когда пользователь нажимает, например, AttractionButton, приложение показывает содержимоеотлично (только дизайн плохой LOL) Но !! когда я нажал «кнопку назад» и вернулся в HomeFragment, а затем снова нажал на кнопку Attraction, она дублирует Arraylist (от 6 пунктов до 12и так далее ...)

Я исправил проблему с помощью init переменных ArrayList внутри метода "initCategoriesData"

Но я до сих пор не понимаю, почему приложение действует так, как онаЯ ценю хорошее объяснение этому, это действительно поможет мне лучше понять, как все это работает

Заранее спасибо, Нив :)

Ответы [ 5 ]

0 голосов
/ 02 октября 2018

См. Изображение выше от разработчиков Android , onCreateView() вызывается, когда фрагмент был обнаружен нажатием пользователем кнопки назад.И затем initCategoriesData().

Фрагмент возвращается из заднего стека в макет, а затем вызываются onCreateView() и initCategoriesData().

0 голосов
/ 02 октября 2018

Поскольку вы используете fragmentTransaction.replace(), HomeFragment.onCreate() и HomeFragment.onCreateView() будут вызываться каждый раз, когда вы возвращаетесь к нему.Так что initCategoriesData() также будет называться.Вы можете либо очистить и инициализировать все данные с нуля каждый раз, либо использовать fragmentTransaction.add() вместо fragmentTransaction.replace(), чтобы избежать этой проблемы.

fragmentTransaction.replace() меняет текущий фрагмент.Он больше не связан с действием, но объект Fragment все еще жив, и все данные, хранящиеся в переменных, все еще там.Когда вы возвращаете его к действию, он вызывает onCreate() и onCreateView(), чтобы заново воссоздать его вид.Эти действия происходят, когда вы replace() и возвращаетесь:

  1. HomeFragment уходит
  2. MasterFragment приходит
  3. MasterFragment уходит
  4. HomeFragment возвращается, запускает onCreate() и onCreateView()

fragmentTransaction.add() ведет себя как добавление еще одного Fragment поверх текущего Fragment, не удаляя его.Когда вы возвращаетесь, он просто показывает оригинал Fragment, который сидел там без каких-либо действий.Эти действия происходят, когда вы add() и возвращаетесь

  1. MasterFragment приходит, покрывая HomeFragment
  2. MasterFragment уходит, показывая HomeFragment

HomeFragment на этот раз практически не тронут, поэтому на нем ничего не срабатывает.

0 голосов
/ 02 октября 2018

// Попробуйте это.Пока вы не очищаете свои списки, прежде чем добавлять в него данные.Очистите ваш список, так как я обновил его в вашем коде.

   public class HomeFragment extends Fragment implements View.OnClickListener {

        private ArrayList<Category> mAttractions= new ArrayList<>();
        private ArrayList<Category> mEvents= new ArrayList<>();
        private ArrayList<Category> mHotels= new ArrayList<>();


        private int mAttractionsBtnId = R.id.attractions_btn;
        private int mEventsBtnId = R.id.events_btn;
        private int mHotelsBtnId = R.id.hotels_btn;

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

        public void initCategoriesData() {
            // init attraction array list
       mAttractions.clear();
       mEvents.clear();
       mHotels.clear();
            mAttractions.add(new Category("Jaffa Port",5,R.drawable.attractions_jaffa_port));
            mAttractions.add(new Category("Beit Hatfusot",5,R.drawable.attractions_beit_hatfutsot));

            mAttractions.add(new Category("Independence Hall",5,R.drawable.attractions_independence_hall));

            mAttractions.add(new Category("Jaffa Bazar",5,R.drawable.attractions_jaffa_bazar));

            mAttractions.add(new Category("Neve Tzedek St",5,R.drawable.attractions_neve_tzedek));

            mAttractions.add(new Category("Rothschild Boulevard St",5,R.drawable.attractions_rothschild_boulevard));


            // init Events array list
            mEvents.add(new Category("cacdas",3));
            mEvents.add(new Category("cacdas",3));
            mEvents.add(new Category("cacdas",3));
            mEvents.add(new Category("cacdas",3));
            mEvents.add(new Category("cacdas",3));
            mEvents.add(new Category("cacdas",3));
            mEvents.add(new Category("cacdas",3));
            mEvents.add(new Category("cacdas",3));

            // init Hotels array list
            mHotels.add(new Category("hotels",3));
            mHotels.add(new Category("hotels",3));
            mHotels.add(new Category("hotels",3));
            mHotels.add(new Category("hotels",3));
            mHotels.add(new Category("hotels",3));
            mHotels.add(new Category("hotels",3));




        }


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

            // Initiate data for each category
            initCategoriesData();


            // Find Buttons
            Button attractionsBtn = (Button)view.findViewById(R.id.attractions_btn);
            Button hotelsBtn = (Button)view.findViewById(R.id.hotels_btn);
            Button eventsBtn = (Button)view.findViewById(R.id.events_btn);

            // Set buttons OnClickListener
            attractionsBtn.setOnClickListener(this);
            hotelsBtn.setOnClickListener(this);
            eventsBtn.setOnClickListener(this);


            return view;
        }


        @Override
        public void onClick(View v) {
            // Start new Fragment when Button Clicked
            FragmentManager fragmentManager = getFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction().addToBackStack(null);

            Bundle bundle = new Bundle();


            // Pass the right data in the bundle
            switch (v.getId()){
                case R.id.attractions_btn:
                    bundle.putSerializable("Data",mAttractions);
                    break;

                case R.id.hotels_btn:
                    bundle.putSerializable("Data",mHotels);
                    break;

                case R.id.events_btn:
                    bundle.putSerializable("Data",mEvents);
                    break;

            }

            ArrayList<Category> cat = (ArrayList<Category>)bundle.getSerializable("Data");
            int size = cat.size();

            MasterFragment masterFragment = new MasterFragment();
            masterFragment.setArguments(bundle);

            fragmentTransaction.replace(R.id.fragment_container, masterFragment);
            fragmentTransaction.commit();
        }
0 голосов
/ 02 октября 2018

Поскольку ваш фрагмент не уничтожается, и когда вы возвращаетесь, у вашего массива уже есть 6 элементов (потому что фрагмент не воссоздан).Таким образом, вы добавляете еще 6 предметов, и размер массива становится 12. Вы можете сделать что-то вроде этого, чтобы решить эту проблему.

private ArrayList<Category> mAttractions;
private ArrayList<Category> mEvents;
private ArrayList<Category> mHotels;

public void initCategoriesData() {

//initialize array list here

mAttractions= new ArrayList<>()
mEvents= new ArrayList<>();
mHotels= new ArrayList<>();

// init attraction array list
mAttractions.add(new Category("Jaffa Port",5,R.drawable.attractions_jaffa_port));
mAttractions.add(new Category("Beit Hatfusot",5,R.drawable.attractions_beit_hatfutsot));

mAttractions.add(new Category("Independence Hall",5,R.drawable.attractions_independence_hall));

mAttractions.add(new Category("Jaffa Bazar",5,R.drawable.attractions_jaffa_bazar));

mAttractions.add(new Category("Neve Tzedek St",5,R.drawable.attractions_neve_tzedek));

mAttractions.add(new Category("Rothschild Boulevard St",5,R.drawable.attractions_rothschild_boulevard));


// init Events array list
mEvents.add(new Category("cacdas",3));
mEvents.add(new Category("cacdas",3));
mEvents.add(new Category("cacdas",3));
mEvents.add(new Category("cacdas",3));
mEvents.add(new Category("cacdas",3));
mEvents.add(new Category("cacdas",3));
mEvents.add(new Category("cacdas",3));
mEvents.add(new Category("cacdas",3));

// init Hotels array list
mHotels.add(new Category("hotels",3));
mHotels.add(new Category("hotels",3));
mHotels.add(new Category("hotels",3));
mHotels.add(new Category("hotels",3));
mHotels.add(new Category("hotels",3));
mHotels.add(new Category("hotels",3));

}

Надеюсь, это помогло вам.

0 голосов
/ 02 октября 2018

Каждый раз, когда вы возвращаетесь в HomeFragment, вызывается метод OnCreateView, а также initCategoriesData(), потому что представление воссоздается.Попробуйте поместить функцию в другое место, onCreate() должно быть в порядке

...