将模型对象传递到另一个Activity

7

我有一个RecyclerView,使用Recycler Adapter输出列表布局,像这样:

http://i.imgur.com/ORkXXTb.png

我需要将下面的模型附加到每个列表项上,这样,如果用户点击列表项中的任何元素(如圆形或两个 TextView 中的一个),它会将模型对象传递给下一个 Activity。
这是 User 模型:
public class User {

    private String id;
    private String username;
    private String displayName;
    private Object deletedAt;
    private Statistic stat;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username= username;
    }

    public String getDisplayName() {
        return displayName;
    }

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    public Object getDeletedAt() {
        return deletedAt;
    }

    public void setDeletedAt(Object deletedAt) {
        this.deletedAt = deletedAt;
    }

    public Statistic getStat() {
        return stat;
    }

    public void setStat(Statistic stat) {
        this.stat = stat;
    }

}

以下是每个列表项的布局(user_layout.xml):
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/user_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <RelativeLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/white">

            <ImageView
                android:id="@+id/avatar"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_alignParentLeft="true"
                android:background="@drawable/avatar" />


            <TextView
                android:id="@+id/display_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignTop="@+id/avatar"
                android:layout_toRightOf="@+id/avatar"
                />

            <TextView
                android:id="@+id/username"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/display_name"
                />

        </RelativeLayout>

    </LinearLayout>

</LinearLayout>

这是用于填充上述布局的 UserRecyclerAdapter

public class UserRecyclerAdapter extends RecyclerView.Adapter<UserRecyclerAdapter.ViewHolder> {

    private Context context;
    private List<User> mDataset;

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public ImageView avatar;
        public TextView displayName;
        public TextView username;

        public ViewHolder(LinearLayout view) {
            super(view);

            avatar = (ImageView) view.findViewById(R.id.avatar);
            displayName = (TextView) view.findViewById(R.id.display_name);
            username = (TextView) view.findViewById(R.id.username);
        }
    }

    public UserRecyclerAdapter(Context context, List<User> myDataset) {
        this.context = context;
        this.mDataset = myDataset;
    }

    @Override
    public UserRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.user_layout, parent, false);
        ViewHolder vh = new ViewHolder((LinearLayout) view);

        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        User userItem = mDataset.get(position);

        holder.displayName.setText(userItem.getDisplayName());
        holder.username.setText(userItem.getUsername());
    }

    @Override
    public int getItemCount() {
        return mDataset.size();
    }

}

所以我的问题是,如何将User模型对象附加到每个列表项中,以便当单击元素(如圆形或两个TextView)时,将模型对象传递给下一个Activity?谢谢。
3个回答

11

请在您的 User 类中添加 implements Serializable,例如 User implements Serializable

通过 Bundle 传递可序列化的类,例如:

User userItem = mDataset.get(position);

Intent yourIntent = new Intent(this, YourNextActivity.class);
Bundle b = new Bundle();
b.putSerializable("user", userItem);
yourIntent.putExtras(b); //pass bundle to your intent
startActivity(yourIntent);

并获得

Intent i = getIntent();
Bundle bundle = i.getExtras();
User user = (User) bundle.getSerializable("user");

4
让用户实现 Parceable 接口。
如果您使用 Android Studio,有一个非常好的插件可以帮助您完成这个任务,叫做 "Android Parcelable code generator"。使用该插件,您可以自动生成所有必要的代码,但基本思路如下:
您需要一个空构造函数:
public User() {}

然后实现接口方法:

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

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(id);
    dest.writeString(userName);
    dest.writeString(displayName);
    ...
    // Any object to be added to dest must implement Parceable in its turn
    // Please note that Lists and Serializable objects are already supported out of the box
}

public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {

    @Override
    public EventFrame createFromParcel(Parcel source) {
        return new User(source);
    }

    @Override
    public EventFrame[] newArray(int size) {
        return new User[size];
    }
};

private EventFrame(Parcel source) {
    id = source.readString();
    accessToken = source.readString();
    displayName = source.readString();
    ...
}

接下来,当您为下一个活动创建意图时,请执行以下操作:

Intent yourIntent = new Intent(this, DestinyClass.class);
yourIntent.putExtra("user_identifier", user);

1
我该如何将模型对象附加到列表项布局中,以便当单击布局中的元素时,它使用特定的模型对象实例。 - user5314557
那是一个不同的问题,我建议您查看一些RecyclerView示例,Stack Overflow上有很多。无论如何,评论区不是讨论该答案的地方,只需为此创建另一个问题。请检查此链接 https://developer.android.com/training/material/lists-cards.html - Edson Menegatti
我觉得你有些困惑了。我并不是在问如何制作RecyclerView,这方面我已经搞定了。我在问的是如何将对象附加到布局上,使得当用户点击布局元素时,该对象能够被发送到下一个Activity。 - user5314557
对不起,我确实有些困惑。您可以将用户对象直接包含在ViewHolder中,其内容不仅需要是UI元素。然后,您可以像@tibo一样在所需的UI元素上设置单击侦听器。 - Edson Menegatti
同样的功能使用 Bundle 类也可以实现,为什么要使用这个库? - Hussain Shabbir

3
使用这个库
@Parcel
public class User {
    public User() {}
    // You can keep all the members private with @Parcel(Serialization.BEAN)
    public String id;
    public String username;
    public String displayName;
    public Object deletedAt;
    public Statistic stat; // Needs to be @Parcel annotated as well
}

ActivityA.java
void openActivityB() {
    Intent intent = new Intent(this, ActivityB.class);
    intent.putExtra("user", Parcels.wrap(user));
    startActivity(intent);
}

ActivityB.java
void receive() {
    User user = Parcels.unwrap(getIntent().getParcelableExtra("user"));
} 

更新:
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    User userItem = mDataset.get(position);

    holder.displayName.setText(userItem.getDisplayName());
    holder.username.setText(userItem.getUsername());

    setOnClickListener(...
        onClick() {
            Context context = holder.displayName.getContext();
            Intent intent = new Intent(context, ActivityB.class);
            intent.putExtra("user", Parcels.wrap(userItem));
            context.startActivity(intent);
    });
}

我该如何将对象附加到列表项布局中呢?换句话说,我该如何获取user以便执行Parcels.wrap(user)操作? - user5314557
如果你从onBindViewHolder中启动Activity,那么会启动很多个Activity,而且没有点击...最好是将一个onClickListener附加到viewholder的视图上,然后从那里启动。 - stephane k.
点击整个布局会启动该活动,这样做是否合适? - user5314557
将监听器附加到您想要的任何视图。这是伪代码。 - mbmc

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