21091


アンドロイドでonCreateではなく、onclick内でスピナーをアダプターにセットしているのですが、  
画面回転した際に、onclickで作ったスピナーの内容が消えてしまいます。  
のでonSaveInstanceStateでスピナーごと保存し、
onRestoreInstanceState内で取り出したスピナーのデータをそのままアダプターにセットしたいのですが、  
[Android Parcelable
を使ってクラスのメンバを一時保存](http://y-anz-m.blogspot.jp/2010/03/androidparcelable.html)  
を参考にして自作のスピナーを一時保存して取り出そうとしたのですが初心者の為、何がいけないのか上手くいきません。どなたか添削のほどお願いします。  
その他必要なもの等あればコメントにてお願いします。

AllContactParcelable.java

[code]

    public class AllContactParcelable implements Parcelable, SpinnerAdapter {
    
    private ArrayList < MainActivity.RowData[] > contactList;
    
    public int describeContents() {
     return 0;
    }
    
    public void writeToParcel(Parcel out, int flags) {
     //out.writeTypedList(contactList);
    }
    
    public static final Creator < AllContactParcelable > CREATOR = new Creator < AllContactParcelable > () {
     public AllContactParcelable createFromParcel(Parcel in ) {
      return new AllContactParcelable( in );
     }
    
     public AllContactParcelable[] newArray(int size) {
      return new AllContactParcelable[size];
     }
    };
    
    private AllContactParcelable(Parcel in ) {
     //contactList = (ArrayList<MainActivity.RowData[]>) (ArrayList<MainActivity.RowData[]>) in.createTypedArrayList(MainActivity.RowData.CREATOR);
    }
    
    public AllContactParcelable(ArrayAdapter < MainActivity.RowData > contactList) {
     //this.contactList = contactList;
    }
    
    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
     return null;
    }
    
    @Override
    public void registerDataSetObserver(DataSetObserver observer) {}
    
    @Override
    public void unregisterDataSetObserver(DataSetObserver observer) {}
    
    @Override
    public int getCount() {
     return 0;
    }
    
    @Override
    public Object getItem(int position) {
     return null;
    }
    
    @Override
    public long getItemId(int position) {
     return 0;
    }
    
    @Override
    public boolean hasStableIds() {
     return false;
    }
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
     return null;
    }
    
    @Override
    public int getItemViewType(int position) {
     return 0;
    }
    
    @Override
    public int getViewTypeCount() {
     return 0;
    }
    
    @Override
    public boolean isEmpty() {
     return false;
    }
    
[/code]

MainActiviy.java 一部抜粋

[code]

    public class MainActivity extends Activity
    implements OnClickListener {
     AllContactParcelable AllContactParcelable;
    
     public static class RowData implements Parcelable {
      private String name;
      private String code;
    
      public int describeContents() {
       return 0;
      }
    
      public void writeToParcel(Parcel out, int flags) {
       out.writeString(name);
       out.writeString(code);
      }
    
      public static final Parcelable.Creator < RowData > CREATOR = new Parcelable.Creator < RowData > () {
       public RowData createFromParcel(Parcel in ) {
        return new RowData( in );
       }
    
       public RowData[] newArray(int size) {
        return new RowData[size];
       }
      };
    
      private RowData(Parcel in ) {
        name = in .readString();
        code = in .readString();
       }
       // コンストラクタ・セッタ・ゲッタ省略
      RowData(String name, String code) {
       this.TOKCO = name;
       this.TOKNA = code;
      }
    
      public String getname() {
       return name;
      }
    
      public String getcode() {
       return code;
      }
    
      @Override
      public String toString() {
        return TOKNA;
      }
    
[/code]

:  
:  
:  
:  
:  
: （onclick内でのドロップダウン作成処理）

[code]

      db = helper.getReadableDatabase();
      // 列名の定義
      String[] columns = {
       "NAME",
       "CODE",
       "NAK"
      };
      // 得意先データの取得
      Cursor cursor = db.query(DB_TABLE, columns, null, null, null, null, "CODE");
      final RowData[] dataArray = new RowData[cursor.getCount()];
      // 取得したデータをテーブル明細部に設定
      for (int i = 0; cursor.moveToNext(); i++) {
       dataArray[i] = new RowData(cursor3.getString(0), cursor3.getString(0) + "\n" + cursor3.getString(1));
      }
      ArrayAdapter < RowData > adapter = new ArrayAdapter < > (this, R.layout.list, dataArray);
      Spinner spinner = (Spinner) findViewById(R.id.n_naiyo);
      spinner3.setAdapter(adapter);
      AllContactParcelable = new AllContactParcelable(adapter);
    
      @Override
      protected void onSaveInstanceState(Bundle outState) {
       super.onSaveInstanceState(outState);
       outState.putParcelable("contact", AllContactParcelable);
      }
    
      @Override
      protected void onRestoreInstanceState(Bundle savedInstanceState) {
       super.onRestoreInstanceState(savedInstanceState);
       AllContactParcelable = savedInstanceState.getParcelable("contact");
       Spinner spinner = (Spinner) findViewById(R.id.n_naiyo);
       spinner.setAdapter(AllContactParcelable);
      }
     }
    }
    
[/code]


CC BY-SA 3.0
2015-12-20T04:35:47.870
20203
2021-03-07T05:15:27.913
2021-03-07T05:15:27.913
3060
13247
question
java android
アンドロイドでアダプターにセットしたスピナーを画面回転させても維持させたい


コードを見る限り、どうやらアダプターを `Parcelable` を利用して保存しようとしていますね。

今回の場合、 `Parcelable` を利用して保持する必要があるデータは（おそらくデータベースからロードをしたのであろう） `RowData`
クラスのインスタンスのみであると思います。

と言うのも、アダプターは表示するべきデータがあれば再生成できる物であるのに対し、表示するべきデータそのものである `RowData`
はデータベースから再度読み込まない限り再生成できない物であると考えられるからです。

という訳で、今回のケースに対応するコードを書いてみました。レイアウトとかは適当ですが、参考にしてください。

`MainActivity.java`

[code]

    public class MainActivity extends Activity implements View.OnClickListener{
        /** 表示用の RowData で Parcelable を実装します */
        public static class RowData implements Parcelable {
            private String name;
            private String code;
    
            public RowData(String name, String code) {
                this.name = name;
                this.code = code;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public String getCode() {
                return code;
            }
    
            public void setCode(String code) {
                this.code = code;
            }
    
            @Override
            public int describeContents() {
                return 0;
            }
    
            @Override
            public void writeToParcel(Parcel dest, int flags) {
                dest.writeString(this.name);
                dest.writeString(this.code);
            }
    
            protected RowData(Parcel in) {
                this.name = in.readString();
                this.code = in.readString();
            }
    
            public static final Parcelable.Creator<RowData> CREATOR = new Parcelable.Creator<RowData>() {
                public RowData createFromParcel(Parcel source) {
                    return new RowData(source);
                }
    
                public RowData[] newArray(int size) {
                    return new RowData[size];
                }
            };
    
            // toString を実装しておくと、 ArrayAdapter で良い感じに表示してくれます
            @Override
            public String toString() {
                return "RowData{" +
                        "name='" + name + '\'' +
                        ", code='" + code + '\'' +
                        '}';
            }
        }
    
        private Spinner spinner;
        private ArrayList<RowData> rowList;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            findViewById(R.id.reload_button).setOnClickListener(this);
    
            spinner = (Spinner) findViewById(R.id.spinner);
        }
    
    
        @Override
        public void onClick(View v) {
            final Cursor cursor = load(); //DBからの読み込みを想定
            // 読み込んだデータを表示用に修正
            rowList = new ArrayList<>(cursor.getCount());
            while(cursor.moveToNext()) {
                final String name = cursor.getString(cursor.getColumnIndex("NAME"));
                final String code = cursor.getString(cursor.getColumnIndex("CODE"));
                rowList.add(new RowData(name, code));
            }
            final MyAdapter adapter = new MyAdapter(this, rowList);
            spinner.setAdapter(adapter);
        }
    
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            if (rowList != null) {
                outState.putParcelableArrayList("content", rowList);
            }
            super.onSaveInstanceState(outState);
        }
    
        @Override
        protected void onRestoreInstanceState(Bundle savedInstanceState) {
            super.onRestoreInstanceState(savedInstanceState);
            final ArrayList<RowData> content = savedInstanceState.getParcelableArrayList("content");
            if (content != null) {
                rowList = content;
                final MyAdapter myAdapter = new MyAdapter(this, rowList);
                spinner.setAdapter(myAdapter);
            }
        }
    }
    
[/code]

`MyAdapter.java`

[code]

    public class MyAdapter extends ArrayAdapter<MainActivity.RowData> {
        public MyAdapter(Context context, List<MainActivity.RowData> objects) {
            super(context, android.R.layout.simple_list_item_1, android.R.id.text1, objects);
        }
    }
    
[/code]

コード全体はリポジトリからどうぞ

<https://github.com/numa08/stackoverflow_20203>


CC BY-SA 3.0
2016-01-19T14:52:05.540
21091
2016-01-19T14:52:05.540
7949
20203
answer