Search

Android - Activity 傳遞自訂物件參數

2015-10-09 8:14 PM

傳遞字串, 數字等參數的方法我想大家應該都沒問題

但 Intent 就是沒有 putExtra( Object ); 的方法

用 Serializable 又會出現錯誤訊息 而且其實有點偷吃步

正確的方法是應該使用 Parcelable 這個介面來完成

首先須實作 Parcelable 介面

public class ArticleBean implements Parcelable

並在 writeToParcel 將欄位值寫入 Parcel 內

@Override
public void writeToParcel(Parcel dest, int flags) {
 dest.writeInt(serialNumber);
 dest.writeString(boardTitle);
 dest.writeString(aid);
 dest.writeString(title);
 dest.writeString(status);
 dest.writeString(pushes);
 dest.writeString(category);
 dest.writeString(author);
 dest.writeString(date);
 dest.writeBooleanArray( new boolean[]{online, read, changed, locked, connected, mail} );
 dest.writeString( articleType.getValue() );
 dest.writeString(articleHeader.getValue());
}

然後再新增一個 static 的 CREATOR 讓參數可以被重新產生

是的 傳遞到另一個 Activity 的參數是重新產生過的新物件

public static final Parcelable.Creator<ArticleBean> CREATOR = new Parcelable.Creator<ArticleBean>() {
 public ArticleBean createFromParcel(Parcel parcel) {
     return new ArticleBean(parcel);
 }

 public ArticleBean[] newArray(int size) {
     return new ArticleBean[size];
 }
};

最後再新增一個使用 Parcel 創建的建構子

重點是所有參數不論型態皆須依照你放入的順序依次取出

例如你第一個放的是字串 第一個取出來的就必須是字串

如果你取得 boolean 他就會報錯

private ArticleBean(Parcel parcel) {
 boolean[] booleans = new boolean[6];

 serialNumber = parcel.readInt();
 boardTitle = parcel.readString();
 aid = parcel.readString();
 title = parcel.readString();
 status = parcel.readString();
 pushes = parcel.readString();
 category = parcel.readString();
 author = parcel.readString();
 date = parcel.readString();

 parcel.readBooleanArray(booleans);

 online = booleans[0];
 read = booleans[1];
 changed = booleans[2];
 locked = booleans[3];
 connected = booleans[4];
 mail = booleans[5];
 articleType = ArticleType.fromValue( parcel.readString() );
 articleHeader = ArticleHeader.fromValue( parcel.readString() );
}

其中的 ArticleType.fromValue 是我慣用的列舉參數方式

詳細建構方式可以參考這個連結 Google 也愛用的列舉參數建構法

傳遞參數時則一樣使用 intent.putExtra

intent.putExtra( "Article.Bean", articleBean );

取出參數則是使用 getParcelable 取出對應的值

articleBean = getIntent().getExtras().getParcelable("Article.Bean");

以下是完整的 Class 程式碼範例

public class ArticleBean implements Parcelable {

    private int serialNumber;

    private String aid;

    private String boardTitle;

    private String title;

    private String status;

    private String pushes;

    private String category;

    private String author;

    private String date;

    private boolean online;

    private boolean read;

    private boolean changed;

    private boolean locked;

    private boolean connected = false;

    private boolean mail = false;

    private ArticleType articleType;

    private ArticleHeader articleHeader;

    public int getSerialNumber() {
        return serialNumber;
    }

    public void setSerialNumber(int serialNumber) {
        this.serialNumber = serialNumber;
    }

    public String getAid() {
        return aid;
    }

    public void setAid(String aid) {
        this.aid = aid;
    }

    public String getBoardTitle() {
        return boardTitle;
    }

    public void setBoardTitle(String boardTitle) {
        this.boardTitle = boardTitle;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getPushes() {
        return pushes;
    }

    public void setPushes(String pushes) {
        this.pushes = pushes;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public boolean isOnline() {
        return online;
    }

    public void setOnline(boolean online) {
        this.online = online;
    }

    public boolean isRead() {
        return read;
    }

    public void setRead(boolean read) {
        this.read = read;
    }

    public boolean isChanged() {
        return changed;
    }

    public void setChanged(boolean changed) {
        this.changed = changed;
    }

    public boolean isLocked() {
        return locked;
    }

    public void setLocked(boolean locked) {
        this.locked = locked;
    }

    public boolean isConnected() {
        return connected;
    }

    public void setConnected(boolean connected) {
        this.connected = connected;
    }

    public boolean isMail() {
        return mail;
    }

    public void setMail(boolean mail) {
        this.mail = mail;
    }

    public ArticleType getArticleType() {
        return articleType;
    }

    public void setArticleType(ArticleType articleType) {
        this.articleType = articleType;
    }

    public ArticleHeader getArticleHeader() {
        return articleHeader;
    }

    public void setArticleHeader(ArticleHeader articleHeader) {
        this.articleHeader = articleHeader;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(serialNumber);
        dest.writeString(boardTitle);
        dest.writeString(aid);
        dest.writeString(title);
        dest.writeString(status);
        dest.writeString(pushes);
        dest.writeString(category);
        dest.writeString(author);
        dest.writeString(date);
        dest.writeBooleanArray( new boolean[]{online, read, changed, locked, connected, mail} );
        dest.writeString( articleType.getValue() );
        dest.writeString(articleHeader.getValue());
    }

    // 傳遞參數時 將會呼叫此方法重新創建物件
    public static final Parcelable.Creator<ArticleBean> CREATOR = 
     new Parcelable.Creator<ArticleBean>() {
         public ArticleBean createFromParcel(Parcel parcel) {
             return new ArticleBean(parcel);
         }

         public ArticleBean[] newArray(int size) {
             return new ArticleBean[size];
         }
     };

    private ArticleBean() {}

    // 以 Parcel 創建的建構子
    private ArticleBean(Parcel parcel) {
        boolean[] booleans = new boolean[6];

        // 所有參數皆須按照加入的順序取出
        serialNumber = parcel.readInt();
        boardTitle = parcel.readString();
        aid = parcel.readString();
        title = parcel.readString();
        status = parcel.readString();
        pushes = parcel.readString();
        category = parcel.readString();
        author = parcel.readString();
        date = parcel.readString();

        parcel.readBooleanArray(booleans);

        online = booleans[0];
        read = booleans[1];
        changed = booleans[2];
        locked = booleans[3];
        connected = booleans[4];
        mail = booleans[5];
        articleType = ArticleType.fromValue( parcel.readString() );
        articleHeader = ArticleHeader.fromValue( parcel.readString() );
    }

    public static class Builder {
        private int serialNumber;
        private String aid;
        private String boardTitle;
        private String title;
        private String status;
        private String pushes;
        private String category;
        private String author;
        private String date;
        private boolean online;
        private boolean read;
        private boolean changed;
        private boolean locked;
        private boolean connected = false;
        private boolean mail = false;
        private ArticleType articleType;
        private ArticleHeader articleHeader;

        private Builder() {
        }

        public static Builder anArticleBean() {
            return new Builder();
        }

        public Builder withSerialNumber(int serialNumber) {
            this.serialNumber = serialNumber;
            return this;
        }

        public Builder withAid(String aid) {
            this.aid = aid;
            return this;
        }

        public Builder withBoardTitle(String boardTitle) {
            this.boardTitle = boardTitle;
            return this;
        }

        public Builder withTitle(String title) {
            this.title = title;
            return this;
        }

        public Builder withStatus(String status) {
            this.status = status;
            return this;
        }

        public Builder withPushes(String pushes) {
            this.pushes = pushes;
            return this;
        }

        public Builder withCategory(String category) {
            this.category = category;
            return this;
        }

        public Builder withAuthor(String author) {
            this.author = author;
            return this;
        }

        public Builder withDate(String date) {
            this.date = date;
            return this;
        }

        public Builder withOnline(boolean online) {
            this.online = online;
            return this;
        }

        public Builder withRead(boolean read) {
            this.read = read;
            return this;
        }

        public Builder withChanged(boolean changed) {
            this.changed = changed;
            return this;
        }

        public Builder withLocked(boolean locked) {
            this.locked = locked;
            return this;
        }

        public Builder withConnected(boolean connected) {
            this.connected = connected;
            return this;
        }

        public Builder withMail(boolean mail) {
            this.mail = mail;
            return this;
        }

        public Builder withArticleType(ArticleType articleType) {
            this.articleType = articleType;
            return this;
        }

        public Builder withArticleHeader(ArticleHeader articleHeader) {
            this.articleHeader = articleHeader;
            return this;
        }

        public Builder but() {
            return anArticleBean().withSerialNumber(serialNumber).withAid(aid).withBoardTitle(boardTitle).withTitle(title).withStatus(status).withPushes(pushes).withCategory(category).withAuthor(author).withDate(date).withOnline(online).withRead(read).withChanged(changed).withLocked(locked).withConnected(connected).withMail(mail).withArticleType(articleType).withArticleHeader(articleHeader);
        }

        public ArticleBean build() {
            ArticleBean articleBean = new ArticleBean();
            articleBean.setSerialNumber(serialNumber);
            articleBean.setAid(aid);
            articleBean.setBoardTitle(boardTitle);
            articleBean.setTitle(title);
            articleBean.setStatus(status);
            articleBean.setPushes(pushes);
            articleBean.setCategory(category);
            articleBean.setAuthor(author);
            articleBean.setDate(date);
            articleBean.setOnline(online);
            articleBean.setRead(read);
            articleBean.setChanged(changed);
            articleBean.setLocked(locked);
            articleBean.setConnected(connected);
            articleBean.setMail(mail);
            articleBean.setArticleType(articleType);
            articleBean.setArticleHeader(articleHeader);
            return articleBean;
        }
    }
}
各項資料連結
Android Parcelable
Google 也愛用的列舉參數建構法

No comments:

Post a Comment