在活动之间使用Parcelable发送对象数组列表

5

我想从一个活动中向另一个活动发送对象数组列表。我使用Parcelable扩展我的对象类,并使用intent onActivityResult传输列表。

但是在第二个活动中,列表显示为null。

第一个活动:

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);
        }

    }
}

第二个活动:

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();

    }

}

}

对象类:

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;
    }



}

不知道出了什么问题,有人可以帮忙吗?谢谢。


当你说“第二个活动”时,是指调用了startActivityForResult()Activity吗? - Mike M.
4个回答

5
当你从startActivityForResult()调用中收到结果时,结果Intent将作为最后一个参数传递到onActivityResult()方法中。你正在使用从getIntent()返回的Intent,它是用于启动当前ActivityIntent,因此它不会有你要查找的额外信息。
onActivityResult()中,从传入该方法的dataIntent中获取Bundle
Bundle bundle = data.getExtras();

您还需要在 onActivityResult() 中删除此行:

mSelectedContacts = bundle.getParcelableArrayList("selectedContacts");

将其替换为:

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

请确保您已经将 ContactList 中的b.putSerializable()调用更改为b.putParcelableArrayList("selectedContacts", selectedContacts)

2

请使用这个

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

替代

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

如果我使用这个,它会抛出空指针异常。@Satnam Singh - Sid
使用以下代码获取传递的数据: Bundle b = data.getExtras(); mSelectedContacts = b.getParcelableArrayList("selectedContacts"); - user1682446
因为你正在使用onActivityResult,并且你的意图是数据。 - user1682446
抱歉,我使用了这个,但列表仍然显示为空。@Satnam Singh - Sid

2

我已经检查了您的代码并发现了一些小问题,

因此通过修复它,您可能会得到结果。

请按照以下步骤操作:

(1) 在PlanEventActivity文件中,将onActivityResult更改为以下内容:

@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);
      }

}

如果您正确地获取了结果但没有将其转换为正确的类型,那么您将获得null,因此您需要将结果parcelable数组列表转换为联系人arraylist,否则它将不起作用。在将列表显示在列表视图中后,您需要通知适配器数据集已更改。如果您传递Serializable对象,则还需通过getSerializable方法获取它。

(2) 对象实现Serializable而不是parcelable,如下所示:

public class contact implements Serializable.

现在尝试运行你的应用程序,几乎完成了,你将获得结果。


1

Do it like this:

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

编辑2:通过以下方式检索它:
 Bundle bundle = i.getExtras();
 mContactListActivity =  i.getBooleanExtra("contactListActivity",true);
 mSelectedContacts = (ArrayList<contact>) i.getSerializableExtra("selectedContacts");

不要忘记:

并且:

public class contact implements Serializable {...}

编辑:

删除(Serializable)

不要写成这样:

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

写下这个:

b.putSerializable("selectedContacts",selectedContacts);

它在ArrayList上报错了。需要将ArrayList序列化。@janki gadhiya - Sid
它显示错误,需要java.uti.arraylist,但找到了java.io.serializable。我已经实现了Serializable。@janki gadhiya - Sid
我尝试了移除它,但仍然出现相同的错误。@janki gadhiya - Sid
在PlanEventActivity中,我遇到了一个错误:“mSelectedContacts = i.getSerializableExtra(“selectedContacts”);”,它无法正常运行。 - Sid
只需将其转换为 ArrayList<contact> - Janki Gadhiya
1
明白了。问题出在我使用的意图上。现在我使用了onActivityResult方法的意图,即直接使用数据,如ArrayList<contact> selectedContacts = (ArrayList<contact>)data.getSerializableExtra("selectedContacts");。 - Sid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接