简体   繁体   中英

Sending array list of object between activities with Parcelable

I want to send an array list of object from one activity to another. I am extending my object class with Parcelable and transferred list using intent onActivityResult.

But the list shows null in second activity.

first activity :

public class PlanEventActivity extends AppCompatActivity implements TimePickerDialog.OnTimeSetListener,
DatePickerDialog.OnDateSetListener{

private boolean mHoursMode;
RelativeLayout chooseEvent,time,date;
EditText eventName;
TextView timeTextView,dateTextView,chooseEventText;
static final int CUSTOM_DIALOG_ID = 0;
ListView dialog_ListView;
private ImageView addOrganizer;
static final int PICK_CONTACT_REQUEST = 1;
private ArrayList<contact> mSelectedContacts;
private ListViewAdapter mAdapter;
private ListView mContactsList;
private ArrayList<Integer> selectedItemsPositions;
private boolean mContactListActivity;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_plan_event);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    toolbar.setTitle("");

    TextView toolbarTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
    toolbarTitle.setText("MeaVita");
    setSupportActionBar(toolbar);

    setUpUI();

    mAdapter = new ListViewAdapter(this,mSelectedContacts);
    mContactsList.setAdapter(mAdapter);
    mAdapter.setMode(Attributes.Mode.Single);

    mContactsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            ((SwipeLayout)(mContactsList.getChildAt(position - mContactsList.getFirstVisiblePosition()))).open(true);
        }
    });

}

public void setUpUI()
{
    chooseEvent = (RelativeLayout)findViewById(R.id.chooseEventLayout);

    time = (RelativeLayout)findViewById(R.id.timeLayout);

    date = (RelativeLayout)findViewById(R.id.dateLayout);

    eventName  = (EditText)findViewById(R.id.editTextEventName);

    timeTextView = (TextView)findViewById(R.id.timeTextView);

    dateTextView = (TextView)findViewById(R.id.dateTextView);

    chooseEventText = (TextView)findViewById(R.id.chooseEventTextView);

    addOrganizer = (ImageView)findViewById(R.id.addOrganizer);

    mContactsList = (ListView)findViewById(R.id.selectedContactsList);

    mSelectedContacts = new ArrayList<>();

    contact contact = new contact();

    contact.setContactid("1");
    contact.setContactName("sid");


    mSelectedContacts.add(contact);
    contact.setContactid("2");
    contact.setContactName("ssss");

    mSelectedContacts.add(contact);

    addOrganizer.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Intent pickContactIntent = new Intent(PlanEventActivity.this,ContactList.class);
            startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);

        }
    });



@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check which request we're responding to
    if (requestCode == PICK_CONTACT_REQUEST) {
        // Make sure the request was successful
        if (resultCode == RESULT_OK) {


            Bundle bundle = data.getExtras();

            mContactListActivity =  bundle.getBoolean("contactListActivity",true);
            mSelectedContacts = bundle.getParcelableArrayList("selectedContacts");
        }

        if(mContactListActivity)
        {

            addOrganizer.setVisibility(View.INVISIBLE);
            mContactsList.setVisibility(View.VISIBLE);

        }

        else {

            mContactsList.setVisibility(View.GONE);
        }

    }
}

Second activity :

public class ContactList extends AppCompatActivity {

private ArrayList<contact> contact_list = null;
private contactAdapter mContactAdapter = null;

private ArrayList<contact> items;
private ArrayList<contact> selectedContacts;
boolean[] isChecked;
Cursor mCursor;
ListView lv;
public int RQS_PICK_CONTACT = 1;
private static final int PERMISSIONS_REQUEST_READ_CONTACTS = 100;
ArrayList<Integer> selectedItemsPositions;
private ImageView done;
private boolean mContactListActivity;

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

    setContentView(R.layout.activity_contacts_list);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

    toolbar.setTitle("");
    TextView toolbarTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);

    toolbarTitle.setText("Select Contacts");

    setSupportActionBar(toolbar);

    done = (ImageView)findViewById(R.id.done);

    contact_list = new ArrayList<contact>();

    selectedContacts = new ArrayList<contact>();

    lv = (ListView)findViewById(R.id.list);

    showContacts();


    done.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Log.d("selectd",String.valueOf(selectedItemsPositions));

            mContactListActivity = true;

            selectedContacts = new ArrayList<>();//to store selected items

            for (Integer pos : selectedItemsPositions) {
                selectedContacts.add(items.get(pos));
            }

            Intent i = new Intent(ContactList.this,PlanEventActivity.class);

            Bundle b = new Bundle();
            b.putSerializable("selectedContacts",(Serializable) selectedContacts);
            i.putExtras(b);

            setResult(RESULT_OK, i);

           finish();


        }
    });

}

@SuppressWarnings("unused")
private void getContacts() {


    String[] projection = new String[] {
            ContactsContract.Contacts.DISPLAY_NAME,
            ContactsContract.Contacts.HAS_PHONE_NUMBER,
            ContactsContract.Contacts._ID };


    mCursor = managedQuery(ContactsContract.Contacts.CONTENT_URI, null, null, null,null);

    while (mCursor.moveToNext()) {
        contact contact = new contact();

        String contactId = mCursor.getString(mCursor.getColumnIndex(ContactsContract.Contacts._ID));

        contact.setContactid(mCursor.getString(mCursor.getColumnIndex(ContactsContract.Contacts._ID)));
        contact.setContactName(mCursor.getString(mCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
        contact_list.add(contact);
    }
    isChecked = new boolean[mCursor.getCount()];

    for (int i = 0; i < isChecked.length; i++) {
        isChecked[i] = false;
    }


    this.mContactAdapter = new contactAdapter(this, R.layout.contact_list_item, contact_list);
    lv.setAdapter(this.mContactAdapter);
 //   mCursor.close();

}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == RQS_PICK_CONTACT) {
        if (resultCode == RESULT_OK) {

            getContacts();

        }
    }
}

public class contactAdapter extends ArrayAdapter<contact> {


    public contactAdapter(Context context, int textViewResourceId, ArrayList<contact> items1) {
        super(context, textViewResourceId, items1);
        items = items1;
        selectedItemsPositions = new ArrayList<>();
    }

//to store all selected items position

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder mViewHolder;

        if (convertView == null) {
            mViewHolder = new ViewHolder();
            LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = vi.inflate(R.layout.contact_list_item, parent, false);
            mViewHolder.cb = (CheckBox) convertView.findViewById(R.id.checkBox);
            mViewHolder.name = (TextView) convertView.findViewById(R.id.name);

            mViewHolder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {

                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean ischecked) {
                    int position = (int) mViewHolder.cb.getTag();
                    if (ischecked) {
                        //check whether its already selected or not
                        if (!selectedItemsPositions.contains(position))
                            selectedItemsPositions.add(position);
                    } else {
                        //remove position if unchecked checked item
                        selectedItemsPositions.remove((Object) position);
                    }
                }
            });

            convertView.setTag(mViewHolder);
        } else {
            mViewHolder = (ViewHolder) convertView.getTag();
        }

        contact contacts = items.get(position);
        mViewHolder.cb.setTag(position);

        if (selectedItemsPositions.contains(position))
            mViewHolder.cb.setChecked(true);
        else
            mViewHolder.cb.setChecked(false);

        mViewHolder.name.setText(contacts.getContactName());


        return convertView;
    }


    public class ViewHolder {
        CheckBox cb;
        TextView name;
    }


}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                       int[] grantResults) {
    if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // Permission is granted
            getContacts();
        } else {
            Toast.makeText(this, "Until you grant the permission, we canot display the names", Toast.LENGTH_SHORT).show();
        }
    }
}


private void showContacts()
{
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {

        requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS);
        //After this point you wait for callback in onRequestPermissionsResult(int, String[], int[]) overriden method
    }

    else {

        getContacts();

    }

}

}

Object class:

public class contact implements Parcelable {

    private String contactName;
    private String contactId;

    contact(){}

    contact(String contactId,String contactName)
    {
        this.contactId = contactId;
        this.contactName = contactName;

    }

    public contact(Parcel in) {
        this();
        contactId  = in.readString();
        contactName = in.readString();

    }
    public void writeToParcel(Parcel dest, int flags) {

        dest.writeString(contactId);
        dest.writeString(contactName);

    }

    public static final Parcelable.Creator<contact> CREATOR = new Parcelable.Creator<contact>()
    {
        public contact createFromParcel(Parcel in)
        {
            return new contact(in);
        }
        public contact[] newArray(int size)
        {
            return new contact[size];
        }
    };

    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    public String getContactName() {
        return contactName;
    }

    public void setContactName(String contactName) {
        this.contactName = contactName;
    }

    public String getContactid() {
        return contactId;
    }

    public void setContactid(String contactId) {
        this.contactId = contactId;
    }



}

Not getting what's going wrong. Can anyone help please. Thank you..

When you receive the results from a startActivityForResult() call, the result Intent is passed into the onActivityResult() method as the last parameter. You're using the Intent returned from getIntent() , which is the Intent used to start the current Activity , so it will not have the extras you're looking for.

In onActivityResult() , get the Bundle from the data Intent passed into the method.

Bundle bundle = data.getExtras();

You'll also need to remove this line in onActivityResult() :

mSelectedContacts = bundle.getParcelableArrayList("selectedContacts");

And replace it with:

ArrayList<contact> newContacts = bundle.getParcelableArrayList("selectedContacts");
mSelectedContacts.addAll(newContacts);
mAdapter.notifyDataSetChanged();

And make sure you've changed the b.putSerializable() call in ContactList to b.putParcelableArrayList("selectedContacts", selectedContacts) .

USE THIS

        Bundle b = this.getIntent().getExtras();
       mSelectedContacts  =    b.getParcelableArrayList("selectedContacts");

INSTEAD OF

        Intent i = getIntent();
        Bundle bundle = i.getExtras();
        mSelectedContacts =  i.getParcelableArrayListExtra("selectedContacts");

I have checked your code and get some minor issues,

So may be by fixing it you can get results.

Follow below steps.

(1) In PlanEventActivity file, change onActivityResult by below,

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     // Check which request we're responding to
     if (requestCode == PICK_CONTACT_REQUEST) {
        // Make sure the request was successful
        if (resultCode == RESULT_OK) {


           Bundle bundle = data.getExtras();

           mContactListActivity =  bundle.getBoolean("contactListActivity",true);
           mSelectedContacts = (ArrayList<contact>) bundle.getSerializable("selectedContacts");
           mAdapter.notifyDataSetChanged();
    }

      if(mContactListActivity)
      {

        addOrganizer.setVisibility(View.INVISIBLE);
        mContactsList.setVisibility(View.VISIBLE);

      }

      else {

          mContactsList.setVisibility(View.GONE);
      }

}

As you are getting result properly but without converting it in proper type you will get null, so you need to convert your result parcelable array list in your contact arraylist other wise it will not work. And also after getting list to display in list view you need to notify your adapter for dataset changed. Also you are paassing Serializable object then also get it by getSerializable method.

(2) Implement Serializable instead of parcelable for object, like below

public class contact implements Serializable.

And now try to run your app, almost done you will get result.

Do it like this:

 Bundle b = new Bundle();
 b.putSerializable("selectedContacts", selectedContacts);
 i.putExtras(b);

EDIT 2: Retrieve it by :

 Bundle bundle = i.getExtras();
 mContactListActivity =  i.getBooleanExtra("contactListActivity",true);
 mSelectedContacts = (ArrayList<contact>) i.getSerializableExtra("selectedContacts");

And don't forget :

public class contact implements Serializable {...}

EDIT:

REMOVE (Serializable) :

Don't write this :

b.putSerializable("selectedContacts",(Serializable) selectedContacts);

write this :

b.putSerializable("selectedContacts",selectedContacts);

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