0

FragmentPagerAdapter를 사용할 때 프래그먼트간에 통신하는 올바른 방법을 알아 내는데 약간의 문제가 있습니다.오리엔테이션 변경 후 정확하게 조각과 통신 할 수 없음

일부 상황에서는 FragmentPagerAdapter를 사용하여 두 조각을 호스팅하는 활동이 있습니다. 프래그먼트 A에는 버튼이 있고 프래그먼트 B의 텍스트가 변경됩니다.

방향 변경 후 버튼을 누르면 모든 것이 예상대로 작동하지만 EditText에서 널 포인터 예외가 발생합니다. 프래그먼트 B에서 변경 중입니다. 디버깅 일 후에 마치 Fragment의 오래된 인스턴스 인 텍스트를 변경하는 Fragment B의 메소드를 호출하는 것처럼 보입니다. 여기

코드입니다 :

내 활동의 내부 클래스입니다 FragmentPagerAdapter :

이 조각은 활동에서 onCreate 메서드에서 인스턴스화
public class MyPagerAdapter extends FragmentPagerAdapter { 

    public MyPagerAdapter (FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int i) { 
     switch (i) { 
      case 0: 
       return fragmentA; 
      case 1: 
       return fragmentB; 
     } 
     return null; 
    } 

    @Override 
    public int getCount() { 
     return tabs.length; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     return tabs[position]; 
    } 
} 

다음과 같이

FragmentA fragmentA; //Declared outside of onCreate 
FragmentB fragmentB; //Declared outside of onCreate 

fragmentA = FragmentA.newInstance(); 
fragmentB = FragmentB.newInstance(); 

에서가 내가 버튼을 눌러 조각을 다음과 같이 인터페이스를 설정 :

마지막으로 그 다음

@Override 
public void onTextChanged(String testText) { 
    fragmentB.updateText(testText); 

} 

그리고 :

testTextInterface.onTextChanged("Some test text"); 
차례로 활동에서 다음 메소드를 호출

: I 버튼을 누르면

@Override 
public void onAttach(Activity activity) { 
    super.onAttach(activity); 
    try { 
     testTextInterface = (TestTextInterface) activity; 
    } catch (ClassCastException e) { 
     throw new ClassCastException(activity.toString() 
       + " must implement testTextInterface"); 
    } 
} 

그런 다음 다음 코드를 발생 OnClickListener를이 FragmentB의 메소드 :

private void updateText(String incomingText){ 
    myEditText.setText(incomingText); 
} 

그리고이게 전부 완벽하게 작동합니다. 장치를 회전시켜야 액티비티가 다시 생성됩니다. 그런 다음 버튼을 누르면 myEditText보기는 updateText 메소드의 FragmentB에서 null입니다.

저는 2 일 동안 이유를 알아 내려고 노력했기 때문에 누군가 내가 잘못 가고있는 부분을 발견 할 수 있는지 궁금 해서요. 문제의 원인이되는 부분을 올바른 방향으로 가리키고 있습니까?

+0

를 참조 그것에 대해 명확있어? oncreate에서? 그렇다면 장치를 회전 할 때 onCreate는 null이 아닌 번들과 함께 호출됩니다. 따라서'savedInstanceState'가 null인지 확인한 다음 단편을 첨부해야합니다. 또한 onAttach 콜백을 제거하고 액티비티의 조각에서 유지하는 참조를 제거합니다. 대신 액티비티에서 리스너를 호출해야 할 때 조각 자체에서'getActivity()'를 수행하면된다. –

+0

한 가지 더, 어댑터에서 새 조각을 만드는 대신 조각을 유지하는 것입니까? 그렇다면 [이 답변] (http://stackoverflow.com/questions/6976027/reusing-fragments-in-a-fragmentpageradapter)을 확인하십시오. –

+0

직접 조각을 첨부하지 마십시오. FragmentPagerAdapter가 자동으로 getItem 메소드에서 그렇게한다고 생각합니까? –

답변

1

회전 할 때 안드로이드는 조각 모음의 새 인스턴스를 생성하지만 새로운 인스턴스에 대한 참조를 얻지 못하는 것이 문제입니다. 액티비티의 프래그먼트에 대한 참조를 유지하는 것이 아니라 필요할 때 findFragmentByTag를 사용하는 것이 더 안전합니다.

@Override 
public void onTextChanged(String testText) { 
    Fragment fragmentB = getFragmentManager().findFragmentByTag("FragmentB"); 
    fragmentB.updateText(testText); 
} 

그리고 조각의 태그를 XML 또는 코드로 설정해야합니다.

+0

조각에 ID가 없어서 FragmentPAgerAdapter와 함께 사용할 수 있다고 생각하지 않습니까? –

+1

각 조각 유형의 인스턴스가 하나만있는 경우 newInstance를 호출 한 직후 ID 또는 태그를 설정하면됩니다. 그렇게하면 FragmentA 또는 FragmentB의 모든 인스턴스에 할당 된 태그 또는 ID가 있음을 알 수 있습니다. 안드로이드는 회전 후에 조각을 다시 만든 후에 조각 태그와 ID를 유지 관리합니다. – Bruce

1

나는 브루스에 동의하지만,이 활동의 ​​조각에 대한 참조를 유지해야하는 경우, 당신은 같은 것을 할 수 있습니다

는 활동에서의이 'setFragmentInstance'를 가정 해 봅시다, 방법을 구현한다.

조각에서 onActivityCreated 메서드를 재정의하면 해당 액티비티를 액티비티로 캐스팅하거나 (해당 프래그먼트가 항상 해당 액티비티에 남아있는 경우) 해당 setFragmentInstance 메서드를 호출하거나 조각에 인터페이스를 추가 할 수 있습니다 , 그 액티비티를 구현하고 onActivityCreated의 인터페이스 메소드를 호출하여 프래그먼트 인스턴스를 설정한다.

나는 하나 개의 유사한 질문하기 전에 질문, 곧 그 후 나는 어떻게 활동에 조각을 부착하는 DialogFragment members becomes null after screen rotation