방향 변경시 Fragment를 처리하는 확실한 방법


87
public class MainActivity extends Activity implements MainMenuFragment.OnMainMenuItemSelectedListener {

 @Override
 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager
            .beginTransaction();

    // add menu fragment
    MainMenuFragment myFragment = new MainMenuFragment();
    fragmentTransaction.add(R.id.menu_fragment, myFragment);

    //add content
    DetailPart1 content1= new DetailPart1 ();
    fragmentTransaction.add(R.id.content_fragment, content1);
    fragmentTransaction.commit();

}
public void onMainMenuSelected(String tag) {
  //next menu is selected replace existing fragment
}

두 개의 목록보기를 나란히 표시해야합니다. 메뉴는 왼쪽에, 내용은 오른쪽에 있습니다. 기본적으로 첫 번째 메뉴가 선택되고 해당 내용이 오른쪽에 표시됩니다. 콘텐츠를 표시하는 Fragment는 다음과 같습니다.

public class DetailPart1 extends Fragment {
  ArrayList<HashMap<String, String>> myList = new ArrayList<HashMap<String, String>>();
  ListAdapter adap;
  ListView listview;

  @Override
  public void onActivityCreated(Bundle savedInstanceState) {
      super.onActivityCreated(savedInstanceState);

       if(savedInstanceState!=null){
        myList = (ArrayList)savedInstanceState.getSerializable("MYLIST_obj");
        adap = new LoadImageFromArrayListAdapter(getActivity(),myList );
        listview.setAdapter(adap);
       }else{
        //get list and load in list view
        getlistTask = new GetALLListTasks().execute();
    }


     @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.skyview_fragment, container,false);
           return v;
        }


     @Override
      public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
          outState.putSerializable("MYLIST_obj", myList );
        }
    }

onActivityCreated 및 onCreateView는 두 번 호출 됩니다 . 조각을 사용하는 많은 예제가 있습니다. 나는이 주제의 초보자이기 때문에 예제를 내 문제와 관련시킬 수 없습니다. 방향 변경을 처리하는 바보 증명 방법이 필요합니다. android:configChanges매니페스트 파일에 선언하지 않았습니다 . 가로 모드에서 다른 레이아웃을 사용할 수 있도록 활동을 파괴하고 다시 만들어야합니다.


일반적으로 조각 방향 변경은 아무것도 할 필요없이 처리됩니다. 그렇다면 방향을 바꿀 때 겪는 문제는 무엇입니까?
Alexander Kulyakhtin 2012

Alex 세로 모드에서 listView로 레이아웃을 표시하고 가로 모드에서 Grid View로 레이아웃을 표시하려면 DetailPart1 클래스가 필요합니다.이를 위해 매번 조각을 다시 만들어야하지만 동일한 레코드를 다시로드하고 싶지 않습니다. 위의 코드는 두 번 DetailPart1을 재현 onSaveInstanceState 나누었다에 그들을 내가 원하는대로 작동하게 누락 된 코드를 알 필요가 저장
user1811741

답변:


132

활동에서 화면을 돌릴 때마다 새 조각을 생성 onCreate();하지만 super.onCreate(savedInstanceState);. 따라서 태그를 설정하고 존재하는 경우 조각을 찾거나 null 번들을 super에 전달하십시오.

이것은 배우는 데 시간이 오래 걸렸고 뷰 페이저와 같은 작업을 할 때 정말 bi ****가 될 수 있습니다.

이 정확한 주제가 다루어 지므로 추가 시간 에 조각 에 대해 읽는 것이 좋습니다 .

다음은 일반적인 방향 변경시 조각을 처리하는 방법의 예입니다.

활동 :

public class MainActivity extends FragmentActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            TestFragment test = new TestFragment();
            test.setArguments(getIntent().getExtras());
            getSupportFragmentManager().beginTransaction().replace(android.R.id.content, test, "your_fragment_tag").commit();
        } else {
            TestFragment test = (TestFragment) getSupportFragmentManager().findFragmentByTag("your_fragment_tag");
        }
    }
}

조각 :

public class TestFragment extends Fragment {

    public static final String KEY_ITEM = "unique_key";
    public static final String KEY_INDEX = "index_key";
    private String mTime;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_layout, container, false);

        if (savedInstanceState != null) {
            // Restore last state
            mTime = savedInstanceState.getString("time_key");
        } else {
            mTime = "" + Calendar.getInstance().getTimeInMillis();
        }

        TextView title = (TextView) view.findViewById(R.id.fragment_test);
        title.setText(mTime);

        return view;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("time_key", mTime);
    }
}

노력에 대한 Warpzit에게 감사하지만, 당신이 당신의 요점에 대해 코드에서 설명해 주시면 기쁩니다. 조각을 다시로드하지 않고 방향 변경을 처리하도록 코드를 변경하는 방법.
user1811741

1
따라서 방향에 따라 변경 될 조각의 레이아웃이 필요하지만 모든 레코드를 다시로드하고 싶지 않습니다. 1. 매니페스트에 android : configchanges = "orientation"을 추가합니다. 조각에서 onConfigurationChanged를 재정의하고 방향을 감지합니다. 방향에 따라 listview 또는 gridview를 숨기거나 표시합니다.
user1811741

@ user1811741이 예제로 업데이트되었습니다. 나는 그것이 모든 것을 명확히하기를 바랍니다.
Warpzit

@Warpzit ViewPager가 표시된 모든 fragment..any 제안을 처리하므로 ViewPager Fragment 구현의 경우 동일한 시나리오를 어떻게 처리 할 수 ​​있습니까?
CoDe 2015

1
@Shubh 잘 나는 viewpager가 이것을 적절하게 처리한다고 믿습니다. 적절한 질문 : 넣어하지 않을 경우 희망, 올바른 방향을 지적하는
Warpzit

21

방향 변경과 활동 레크리에이션 사이에 데이터를 유지하는 방법에 대한 좋은 지침은 안드로이드 지침에서 찾을 수 있습니다 .

요약:

  1. 조각을 유지 가능하게 만드십시오.

    setRetainInstance(true);
    
  2. 필요한 경우에만 새 조각을 만듭니다 (또는 최소한 여기에서 데이터 가져 오기).

    dataFragment = (DataFragment) fm.findFragmentByTag("data");
    
    // create the fragment and data the first time
    if (dataFragment == null) {
    

내 시간 Wah 절약
Arjun saini
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.