Як передавати пакет з ArrayList від Fragment to Activity

У мене є ListFragment, який реалізує слухач кліків, щоб передати клацаний об'єкт до IngredientActivity. Коли я отримую об'єкт у складі інгредієнта, змінні об'єктів є нульовими.

public class ListFragment extends Fragment implements ListRecipeAdapter.ListItemClickListener {
....
@Override
    public void onListItemClick(Recipe selectedRecipe) {
        Bundle bundle = new Bundle();
        ArrayList selectedRecipeArray = new ArrayList<>();
        selectedRecipeArray.add(selectedRecipe);
        bundle.putParcelableArrayList("recipe",selectedRecipeArray);
        Intent intent = new Intent(getActivity(), IngredientActivity.class);
        intent.putExtras(bundle);
        startActivity(intent);
    }
}

Я отримую пакунок і витягую арреїліста об'єкта як:

public class IngredientActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ....
        Bundle bundle = getIntent().getExtras();
        ArrayList recipes = bundle.getParcelableArrayList("recipe");
        recipe = recipes.get(0);

    }
}

Слухач - це інтерфейс:

public interface ListItemClickListener {
        void onListItemClick(Recipe recipeId);
    }

Рецепт визначається як Parcelable:

public class Recipe implements Parcelable {
...
}

Коли я надрукую це у logcat:

Рецепт у фрагменті:

[email protected]

Список фрагментів у фрагменті:

[[email protected]]

Пакет у фрагменті:

Bundle[{selected_recipe=[[email protected]]}]

Отриманий об'єкт виглядає інакше:

Пакет "Діяльність":

Bundle[mParcelledData.dataSize=6784]

Список показів у активності:

[[email protected]]

Рецепт в діяльності:

[email protected]
1
Пакет має обмеження розміру 500 Кб, якщо ви переходите, щоб ваше додаток зірвалося. Є кілька приємних способів отримати локальне сховище, не покладаючись на IPC між екранами програм.
додано Автор EpicPandaForce, джерело
Вам дійсно потрібно надіслати ArrayList ? onListItemClick (Recipe recipeId); надає лише один об'єкт, тому чому б не використовувати putParcelable() замість putParcelableArrayList() .
додано Автор android_hub, джерело
Вам дійсно потрібно надіслати ArrayList ? onListItemClick (Recipe recipeId); надає лише один об'єкт, тому чому б не використовувати putParcelable() замість putParcelableArrayList() .
додано Автор android_hub, джерело

7 Відповіді

Схоже, у вас виникли проблеми з об'єктом, що поширюється. Переконайтеся, що всі поля є серіалізованими.

Інший варіант - ваш об'єм, який можна поширити, занадто великий. Існує обмеження розміру на Parcelable, що додається до намірів - щось близько 1 мб.

1
додано

Чи правильно реалізований об'єкт Parcelable?

Після розподілу посилань ви можете мати інший об'єкт адреси, оскільки об'єкт відтворюється за допомогою цих даних.

Ознайомтеся з реалізацією об'єкта Рецепт, що діє на паркеті.

1
додано
Велике спасибі за натяк! Я неправильно обробляв нульовий випадок у writeToParcel і оновлював виклики dest.write *. Виправлення обох вирішило мою проблему.
додано Автор sbj1811, джерело

Чи правильно реалізований об'єкт Parcelable?

Після розподілу посилань ви можете мати інший об'єкт адреси, оскільки об'єкт відтворюється за допомогою цих даних.

Ознайомтеся з реалізацією об'єкта Рецепт, що діє на паркеті.

1
додано
Велике спасибі за натяк! Я неправильно обробляв нульовий випадок у writeToParcel і оновлював виклики dest.write *. Виправлення обох вирішило мою проблему.
додано Автор sbj1811, джерело

У мене є ListFragment, який реалізує прослуховування натиснутого клавіші   об'єкт до IngredientActivity. Коли я отримую об'єкт в   IngredientActivity, змінні об'єктів є нульовими.

Я хотів би, щоб ви переглянули структуру, що ви робите, передавши об'єкт ArrayList через Bundle з Fragment відповідного Діяльність , що не є правильний шлях.

Рішення: Ви можете використовувати інтерфейс, який буде передавати об'єкт за допомогою методу зворотного виклику до активності (тут я припускаю, що вам потрібно встановити інтерфейс після створення фрагмента).

Зробіть подібні

        public class ListFragment extends Fragment {
        ....

        private ListItemClickListener mListener;

        public void setListClickListner(ListItemClickListener listener){
        this.mListener=listener;
        }

/**Note : you will need to call      
mListener.onListItemClick(selectedRecipe);
in the relavent click event of ListView/RecyclerView with instance of 
receipe. */

}

і в активності:

public class IngredientActivity extends AppCompatActivity  implements ListRecipeAdapter.ListItemClickListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ....
        Bundle bundle = getIntent().getExtras();
        ArrayList recipes = bundle.getParcelableArrayList("recipe");
        recipe = recipes.get(0);

    }

   //Callback method
   @Override
    public void onListItemClick(Recipe selectedRecipe) {
       //Whatever thing you want to do goes here...
        mListener.onListItemClick(selectedRecipe);
    }

}

Сподіваюся, це має сенс.

0
додано

У мене є ListFragment, який реалізує прослуховування натиснутого клавіші   об'єкт до IngredientActivity. Коли я отримую об'єкт в   IngredientActivity, змінні об'єктів є нульовими.

Я хотів би, щоб ви переглянули структуру, що ви робите, передавши об'єкт ArrayList через Bundle з Fragment відповідного Діяльність , що не є правильний шлях.

Рішення: Ви можете використовувати інтерфейс, який буде передавати об'єкт за допомогою методу зворотного виклику до активності (тут я припускаю, що вам потрібно встановити інтерфейс після створення фрагмента).

Зробіть подібні

        public class ListFragment extends Fragment {
        ....

        private ListItemClickListener mListener;

        public void setListClickListner(ListItemClickListener listener){
        this.mListener=listener;
        }

/**Note : you will need to call      
mListener.onListItemClick(selectedRecipe);
in the relavent click event of ListView/RecyclerView with instance of 
receipe. */

}

і в активності:

public class IngredientActivity extends AppCompatActivity  implements ListRecipeAdapter.ListItemClickListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ....
        Bundle bundle = getIntent().getExtras();
        ArrayList recipes = bundle.getParcelableArrayList("recipe");
        recipe = recipes.get(0);

    }

   //Callback method
   @Override
    public void onListItemClick(Recipe selectedRecipe) {
       //Whatever thing you want to do goes here...
        mListener.onListItemClick(selectedRecipe);
    }

}

Сподіваюся, це має сенс.

0
додано

Ви можете використовувати інтерфейс Android Parcelable або Java Serializable. Обидва будуть працювати. З продуктивністю рівень, parcelable швидше, ніж serializable.

0
додано

Ви можете використовувати інтерфейс Android Parcelable або Java Serializable. Обидва будуть працювати. З продуктивністю рівень, parcelable швидше, ніж serializable.

0
додано
ІТ КПІ - Java
ІТ КПІ - Java
436 учасників

android_jobs_ua
android_jobs_ua
120 учасників

Публикуем вакансии и запросы на поиск работы по направлению Android. Здесь всё: full-time, part-time, remote и разовые подработки.

Mobile Dev Jobs UA
Mobile Dev Jobs UA
20 учасників

Публикуем вакансии и запросы на поиск работы по направлению iOS, Android, Xamarin, RN и т.д.