3

Я хочу сохранить и восстановить некоторые данные для изменения ориентации экрана (портрет/пейзаж).реализация Parcelable в производном графическом классе для onSaveInstanceState (Bundle)

Для этого я применил onSaveInstanceState и onRestoreInstanceState в своем классе, который содержит список, который я хочу восстановить. Кажется, что он работает, и в классе MyObject я реализовал Исходный номер.

Проблема заключается в том, что мой объект расширяет GifImageButton и осуществлять Parcelable так что я получаю эту ошибку в моих конструкторов объектов: «Там нет конструктора по умолчанию не доступен для pl.droidsonroids.gif.GifImageButton»

public class MyDerivedClass extends MyBaseClass { // extends AppCompatActivity 
    ArrayList<MyObject> list; 

     @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.episode_five); 
    if(savedInstanceState == null || !savedInstanceState.containsKey("key"))  { 
      String[] colors = {"black", "red"}; 
      String[] numbers = {"one", "two"}; 

      list = new ArrayList<MyObject>(); 
      for(int i = 0; i < numbers.length; i++) 
       list.add(new MyObject(numbers[i], colors[i])); 
     } 
     else { 
      list = savedInstanceState.getParcelableArrayList("key"); 
     } 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     outState.putParcelableArrayList("key", list); 
     super.onSaveInstanceState(outState); 
    } 
    @Override 
    protected void onRestoreInstanceState(Bundle inState) { 
     list = inState.getParcelableArrayList("key"); 
     super.onSaveInstanceState(inState); 
     init(); 
    } 
    public void init() { 
     list.add(new MyObject("three", "transparent")); 
     list.add(new MyObject("for", "white")); 
    } 
} 

и задачи, просматривать код ниже:

Я хочу расширяет GifImageButton, но потом я получаю сообщение об ошибке «Там нет конструктора по умолчанию не доступны для pl.droidsonroids.gif.GifImageButton» по адресу:

общественного MyObject (номер String, String цвет) И общественного MyObject (Parcel в)

Примечание: если я удалю: «extends GifImageButton» и «public MyObject (контекст контекста, AttributeSet attrs)», тогда код скомпилируется.

class MyObject extends GifImageButton implements Parcelable { 
    String color; 
    String number; 

    public MyObject(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     setImageResource(R.drawable.a); 
    } 

    public MyObject(String number, String color) { 
     this.color = color; 
     this.number = number; 
    } 

    private MyObject(Parcel in) { 
     color = in.readString(); 
     number = in.readString(); 
    } 

    public int describeContents() { 
     return 0; 
    } 

    @Override 
    public String toString() { 
     return number + ": " + color; 
    } 

    public void writeToParcel(Parcel out, int flags) { 
     out.writeString(color); 
     out.writeString(number); 
    } 

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

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

Могу ли я расширить GifImageButton в классе объектов, который реализует Parcelable? если нет, то как я могу это исправить?

ответ

1

Сообщение об ошибке появляется, потому что вам нужно вызвать конструктор суперкласса в вашем конструкторе. Если явного вызова нет, компилятор вставляет вызов конструктору без аргументов. Тем не менее, все конструкторы суперкласса имеют некоторые аргументы, поэтому компиляция терпит неудачу.

В вашем случае я бы не реализовал Parcelable в вашем классе вообще. Суперкласс не реализует его, поэтому вам также нужно каким-то образом сохранить состояние суперкласса, чего не удастся сделать. Суперкласс - это View, поэтому он сохраняет ссылку на текущую активность, которую нельзя поместить в Parcel.

Вместо этого вы должны сохранить не сам экземпляр, а состояние, в котором вы нуждаетесь. Ваше состояние в настоящее время выражается двумя строками. Вы можете создать отдельный класс State внутри MyObject:

static class State implements Parcelable { 
    private String color; 
    private String number; 

    //Parcelable implementation omitted 
} 

Тогда вы реализуете Parcelable для него. MyObject будет иметь поле private State state вместо двух текущих полей, конструктор, который принимает State, и метод State getState(), который вернет состояние. Когда вам нужно сохранить состояние, вы не сохраняете объект, вы получаете его состояние и сохраняете его. Когда вам нужно восстановить, сначала вы восстанавливаете State, а затем используйте его с конструктором для создания нового MyObject с тем же состоянием, что и раньше.

+0

Я пробовал, но затем в MyDerivedClass Я ошибки. например, в onCreate в строке: list = savedInstanceState.getParcelableArrayList («ключ»); Ошибка: inferred type MyObject для параметра типа 'T' не находится в пределах его границы; должен реализовывать «android.os.Parcelable». другая ошибка в onSaveInstanceState в строке: outState.putParcelableArrayList («ключ», список); ошибка: неправильный тип второго аргумента; Найдено «MyObject», требуется: «java.util.ArrayList ' –

+1

@ErezShmiel Как я уже сказал, вам нужно сохранить состояния, а не сами объекты. Конечно, если у вас есть список объектов и попытайтесь его сохранить, вы не сможете, потому что он не реализует 'Parcelable'. Вам нужно получить состояния от всех объектов в списке, создать новый 'ArrayList' и поместить его в' Bundle'. – Malcolm

0

вы MyObject класс имеет частный конструктор MyObject (Parcel в), сделать его открытым, так компилятор может получить доступ к нему

+0

Я сделал это общедоступным, но он показывает ту же ошибку –