2017-02-18 5 views
0

일부 네트워크 작업을 수행하는 사용자 지정보기가 있습니다. 그 조작 결과로부터 뷰는 UI를 빌드합니다.onRestoreInstanceState 이후 조각에서 연산 실행

보기에는 인터넷을 통해 가져온 카드 목록이 있습니다. 이보기는 여러 위치에서 사용됩니다. 그 중 하나가 내 조각이라고하자. 여기

class MyFragment extends Fragment { 
    // same as findViewById 
    @BindView(R.id.card_list) CardHelper cardHelper; 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     // init my element with some data before it initializes 
     cardHelper.init(data); 
    } 
} 

내 사용자 정의보기 모양을

처럼 : 내 응용 프로그램에서 다른 하나에 대한 사용자 스위치

public class CardHelper extends ListView { 

    // some info that is built from internet data 
    private List<HashMap<String, String>> cardElements = new ArrayList<>(); 

    public void init(Data data) { 
     // does async network and then build a view based on results 
     // Network operations could depend on data param 
    } 
} 

OK, 지금 때, 나의 조각은 할 수 여기에

내가 조각의 내부에 무슨이다 파괴되다. 그리고 내 사용자 정의보기의 상태를 저장하고 싶습니다. 따라서 내 견해는 인터넷에서 정보를 다시 얻을 필요가 없습니다. 그래서 ( this 답변에 따라) 다음과 같은 데이터를 내 CardHelper을 추가 : 인수를 위해서
public class CardHelper extends ListView { 
    // some info that is built from internet data 
    private List<HashMap<String, String>> cardElements = new ArrayList<>(); 

    public void init(Data data) { 
     // does async network and then build a view based on results 
    } 

    @Override 
    public Parcelable onSaveInstanceState() { 
     Parcelable superState = super.onSaveInstanceState(); 
     SavedState ss = new SavedState(superState); 
     ss.cardElements = this.cardElements; 
     return ss; 
    } 

    @Override 
    public void onRestoreInstanceState(Parcelable state) { 
     if(state instanceof SavedState) { 
      SavedState ss = (SavedState)state; 
      super.onRestoreInstanceState(ss.getSuperState()); 
      this.cardElements = ss.cardElements; 
     } else { 
      super.onRestoreInstanceState(state); 
     } 
    } 

    private static class SavedState extends BaseSavedState { 
     private List<HashMap<String, String>> cardElements = new ArrayList<>(); 

     SavedState(Parcelable superState) { 
      super(superState); 
     } 

     private SavedState(Parcel in) { 
      super(in); 
      this.cardElements = new ArrayList<>(); 
      in.readList(this.cardElements, null); 
     } 

     @Override 
     public void writeToParcel(Parcel out, int flags) { 
      super.writeToParcel(out, flags); 
      out.writeList(this.cardElements); 
     } 

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

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

, 나는이보기 자체에서 뷰의 데이터를 저장 싶어요. 그래서 파편/활동 또는 승/사용은 그것이 어떻게 작동 하는지를 알 필요가 없습니다. 그리고 여러 곳에서 사용하는 경우이 뷰를 저장 \ 복원하는 코드를 복제 할 필요가 없습니다.

좋아, 지금 문제에 : CardHelper가 좀 data 수동으로 뷰를 초기화 init을 수행하는 최초의 시간을 만들어

. 내 조각이 복원됩니다 다음 파괴 및 응용 프로그램이 백그라운드로 이동 및 도착하면, 방법은 다음의 우선 순위에서 실행됩니다

  1. SavedState : 개인 SavedState (소포에서) {
  2. SavedState : 공공 무효 writeToParcel (소포를, 공공 무효 초기화 (데이터 데이터) {
  3. CardHelper : 공공 무효 onRestoreInstanceState (Parcelable 상태) {

이 보시다시피) {

  • CardHelper 플래그를 int로 0은 onActivityCreated 이후에만 실행됩니다. 하지만 그 전에 init 메서드에서 네트워크 작업을 수행해야하는지 알고 싶습니다. 그래서 나는 onRestoreInstanceState을 먼저 수행하고 오직 init을 실행하고 싶습니다. 그러나이 후에 수행 할 수있는 단편 LifeCycle에 메소드가 없습니다.

    onRestoreInstanceStateCardHelper이 호출 된 후 내 조각 내에서 일부 작업을 호출 할 수있는 코드를 다시 포맷하는 방법은 무엇입니까? onRestoreInstanceStateCardHelper이 처음 생성 될 때 처음으로 호출되지 않는 것이 하나 더 있습니다. 하지만이 경우에도 CardHelper를 초기화해야합니다.

  • 답변

    1

    cardHelper을 배치 한 후 init() 단계를 게시하는 것이 쉬운 방법이므로 onRestoreInstanceState이 이미 호출되었습니다. 그냥 post(...)init()을 수행하기 위해해야 ​​할 일 :

    cardHelper.post(new Runnable() { 
            public void run() { 
             cardHelper.init(); 
            } 
           }); 
    

    그것을 테스트하지 않았습니다, 나는 그것이 작동합니다 가정합니다.

    +0

    그래,이 작동합니다. 아마도 거기에 더 우아한 해결책이있을 것입니다. – deathangel908

    +0

    코드의 문제는'View'가 비즈니스 로직을 인식한다는 것입니다. 일반적으로 그렇게해서는 안됩니다. 우아한 솔루션은보기 자체에 데이터를 저장하지 말고 아키텍처를 변경하는 것입니다. – azizbekian

    +0

    어떻게해야하는지 제안 해 주시겠습니까? 아이디어는 로직을 캡슐화하여 자신을 볼 수있게하는 것이 었습니다. 따라서 내 view를 사용하는 사람들은'layout.xml'에 대한 view를 지나치는 것에 대해 걱정할 필요가 없습니다. 내 견해를 벗어난 로직을 옮기면 사용자는 수동으로 번들을 저장해야한다는 것을 알아야합니다. – deathangel908