简体   繁体   中英

Parcelable with arraylist<CustomClass> passing value from activity to fragment android

I'm trying to pass a custom ArrayList from an activity to a fragment but don't understand what's wrong with the code. There's no error but even them I'm unable to get the expected output. And I'm completely lost after trying hard to fix it for almost 3 days(Yes, but I'm just a beginner). Please help me fix it out. The purpose is that I want to use the fragment for another activity.

Here's my Activity Class:

 public class CityDetailsActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Create a list of City Details
        ArrayList<CityDetails> cityDetail = new ArrayList<CityDetails>();
        cityDetail.add(new CityDetails("information", "near", "local food", R.drawable.img1, R.drawable.img1, R.drawable.img6));
        Bundle args = new Bundle();
        args.putParcelableArrayList("key", cityDetail);
        CityInformationFragment myFragment = new CityInformationFragment();
        myFragment.setArguments(args);

        // Set the content of the activity to use the activity_main.xml layout file
        setContentView(R.layout.fragment_main);
        ViewPager vpPager = (ViewPager) findViewById(R.id.vpPager);
        FragmentPagerAdapter adapterViewPager;
        adapterViewPager = new CityDetailsPagerAdapter(getSupportFragmentManager());
        vpPager.setAdapter(adapterViewPager);
        // Give the TabLayout the ViewPager
        TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
        tabLayout.setupWithViewPager(vpPager);
    }
}

And my Custom Parcelable Class is as under:

    public class CityDetails implements Parcelable {
    private String mInformation;
    private String mNearPlace;
    private String mLocalFood;
    private int mItemImageResourceId;
    private int mNear_place_image_ResourceId;
    private int mLocal_food_image_ResourceId;

    public CityDetails(String information, String nearPlace, String localFood, int itemImageResourceId
            , int near_place_image_ResourceId, int local_food_image_ResourceId) {
        mInformation = information;
        mNearPlace = nearPlace;
        mLocalFood = localFood;
        mItemImageResourceId = itemImageResourceId;
        mNear_place_image_ResourceId = near_place_image_ResourceId;
        mLocal_food_image_ResourceId = local_food_image_ResourceId;

    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeString(mInformation);
        out.writeString(mNearPlace);
        out.writeString(mLocalFood);
        out.writeInt(mItemImageResourceId);
        out.writeInt(mNear_place_image_ResourceId);
        out.writeInt(mLocal_food_image_ResourceId);

    }

    private CityDetails(Parcel in) {
        mItemImageResourceId = in.readInt();
        mNear_place_image_ResourceId = in.readInt();
        mLocal_food_image_ResourceId = in.readInt();
        mNearPlace = in.readString();
        mLocalFood = in.readString();
        mInformation = in.readString();
    }

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

    // After implementing the `Parcelable` interface, we need to create the
    // `Parcelable.Creator<MyParcelable> CREATOR` constant for our class;
    // Notice how it has our class specified as its type.
    public static final Parcelable.Creator<CityDetails> CREATOR
            = new Parcelable.Creator<CityDetails>() {

        // This simply calls our new constructor (typically private) and
        // passes along the unmarshalled `Parcel`, and then returns the new object!
        @Override
        public CityDetails createFromParcel(Parcel in) {
            return new CityDetails(in);
        }

        // We just need to copy this and change the type to match our class.
        @Override
        public CityDetails[] newArray(int size) {
            return new CityDetails[size];
        }
    };

    public String getInformation() {
        return mInformation;
    }

    public String getNearPlace() {
        return mNearPlace;
    }

    public String getLocalFood() {
        return mLocalFood;
    }

    public int getItemImageResourceId() {
        return mItemImageResourceId;
    }

    public int getNear_place_image_ResourceId() {
        return mNear_place_image_ResourceId;
    }

    public int getLocal_food_image_ResourceId() {
        return mLocal_food_image_ResourceId;
    }
}

And lastly my Fragment is :

    public class CityInformationFragment extends Fragment {

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

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

        Bundle bundle = getArguments();

        if ((bundle != null)) {
            ArrayList<CityDetails> city = getArguments().getParcelable("key");

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

            // 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.city_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;
    }

}

EDIT: Here is my FragmentPagerDapter

public class CityDetailsPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 1;
private String tabTitles[] = new String[] { "City Information"};
private Context context;

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

@Override
public Fragment getItem(int position) {
    return new CityInformationFragment();
}
@Override
public CharSequence getPageTitle(int position) {
    // Generate title based on item position
    return tabTitles[position];
}


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

} And, here's my CityDetailsAdapter:

public class CityDetailsAdapter extends ArrayAdapter<CityDetails> {
// View lookup cache
private static class ViewHolder {
    TextView cityInformation;
    ImageView city_item_image;
    TextView city_near_place_Information;
    ImageView city_item_near_place_image;
    TextView city_local_food_Information;
    ImageView city_item_local_food_image;

}

public CityDetailsAdapter(Context context, ArrayList<CityDetails> cityDetails) {
    super(context, 0, cityDetails);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // Get the data item for this position
    CityDetails currentCity = getItem(position);
    // Check if an existing view is being reused, otherwise inflate the view
    ViewHolder viewHolder; // view lookup cache stored in tag
    if (convertView == null) {
        // If there's no view to re-use, inflate a brand new view for row
        viewHolder = new ViewHolder();
        LayoutInflater inflater = LayoutInflater.from(getContext());
        convertView = inflater.inflate(R.layout.city_list_item, parent, false);
                    /*Find the TextView and ImageView and set them on the VIewHolder*/
        viewHolder.cityInformation = (TextView) convertView.findViewById(R.id.cityInformation);
        viewHolder.city_near_place_Information = (TextView) convertView.findViewById(R.id.city_near_place_Information);
        viewHolder.city_local_food_Information = (TextView) convertView.findViewById(R.id.city_local_food_Information);
        viewHolder.city_item_image = (ImageView) convertView.findViewById(R.id.city_item_image);
        viewHolder.city_item_near_place_image = (ImageView) convertView.findViewById(R.id.city_item_near_place_image);
        viewHolder.city_item_local_food_image = (ImageView) convertView.findViewById(R.id.city_item_local_food_image);

        // Cache the viewHolder object inside the fresh view
        convertView.setTag(viewHolder);
    } else {
        // View is being recycled, retrieve the viewHolder object from tag
        viewHolder = (ViewHolder) convertView.getTag();
    }
    // Populate the data into the template view using the data object
    viewHolder.cityInformation.setText(currentCity.getInformation());
    viewHolder.city_item_image.setImageResource(currentCity.getItemImageResourceId());
    viewHolder.city_near_place_Information.setText(currentCity.getNearPlace());
    viewHolder.city_local_food_Information.setText(currentCity.getLocalFood());
    viewHolder.city_item_near_place_image.setImageResource(currentCity.getNear_place_image_ResourceId());
    viewHolder.city_item_local_food_image.setImageResource(currentCity.getLocal_food_image_ResourceId());

    return convertView;
}

Be as specific as possible to the mistake I'm making. Because being a beginner I may be unable to understand some concepts, but I'll try. Anyway, this is my first question here, so maybe I didn't tell the problem right. And your help is most welcome. Thanks.

The problem seems to be with your FragmentPagerAdapter class. You're not passing any arguments through the fragment returned by getItem() method it just returns the fragment object without any arguments passed to it.

So modify the method to below

@Override
public Fragment getItem(int position) {
    CityInfomationFragment fragment = new CityInformationFragment();
    Bundle args = new Bundle();
    args.putParcelableArrayList("key", your_array_list);
    fragment.setArguments(args);
    return fragment;
}

Pass the array_list to the constructor of the FragmentPagerAdapter class from the activity and save it using a field variable and reference it in the getItem() method

EDIT

The fragment instance you have created in the activity has no effect at all unless you do any fragment transaction with it. You can pass that fragment instance to the FragmentPagerAdater and return the same from getItem() method to show that fragment in the ViewPager.

试试下面的线

ArrayList<CityDetails> city = getArguments().getParcelableArrayList("key");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM