마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

안드로이드 하위 Fragment 간의 이동

0 추천
네비게이션 드로어를 사용 중인데 하위 Fragment 끼리 이동시키는 방법을 도저히 모르겠어서 질문드립니다.

 

현재 프레그먼트를 가지고 있는 FrameLayout으로 이뤄진 메인 액티비티와, 이 하위로 구성된 5개의 Fragment가 있습니다.

 

여기서 MainActivity 에서 fragment로의 이동은 쉽게 했는데

fragment1에서 fragment2로 화면 전환하는 방법을 모르겠습니다..

그냥 액티비티에서 Intent i = new Intent(this, MainActivity.class);

뭐 이런 식으로 이동하는 것 처럼 하고 싶은데... 도와주세요 ㅠㅠ

느린마라토너 (240 포인트) 님이 2014년 7월 21일 질문

3개의 답변

+1 추천
MainActivity가 Fragment들을 Contain하시는건 이해하고 계시죠?
 
Fragment의 Transaction은 액티비티가 가지고있는 FragmentManager가 담당하구요.
 
//FragmentManager SupportFragmentManager 둘다 이하 FragmentManager라고 하겠습니다.
 
 
 
첫 Fragment1을 셋팅할때는
 
if(savedInstanceState==null){
 
getFragmentManager().beginTransaction().replace(R.id.content, new Fragment1()).commit();
 
}
 
이런식으로 셋팅하고 나서 Fragment1 내부에서 startActivity(Fragment.clas)호출처럼 Fragment2로의 전환작업이 이루어 지길 원하시는건가요?
 
제가 이해한게 맞다면 결론은 가능합니다.
 
옵저버패턴 이나 리플렉션을 이용하면 됩니다. 뭐... 혼합시켜서 프레임워크화 시켜도 되구요.
 
1. 옵저버패턴을 이용한 콜백 호출로 MainActivity에서 FragmentTransactoin을 호출하는 방법.
 
2. 리플렉션을 이용해서 startActivity처럼 Fragment.class를 기술해서 호출하는 방법.
 
3. 뭐 여러가지 응용 혼합...
 
 
2번이 뭔가 고객님께서 원하시는방법 같으니... 방법상 제일 쉽기도 하구요.
문제라면 중간 옵저버나 컨트롤매니저가 없어 다른 곳에서 컨트롤이 안된다는 점?
 
이쁘게 짠 소스는 아니지만 봐주시기 바랍니다...
 
1. 액티비티 레이아웃 파일입니다. 별거 없습니다. id를 content를 가진 프레임레이아웃 하나입니다.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.startfragmenttest.MainActivity" >

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

 

2. 모든 플래그먼트들이 상속하게될 최상위 부모 Fragment를 생성합니다. BaseFragment가 좋겠군요.

package com.example.startfragmenttest;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;

public class BaseFragment extends Fragment {

	protected void startFragment(FragmentManager fm, Class<? extends BaseFragment> fragmentClass) {
		BaseFragment fragment = null;
		try {
			fragment = fragmentClass.newInstance();
		} catch (java.lang.InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		if (fragment == null) {
			throw new IllegalStateException("cannot start fragment. " + fragmentClass.getName());
		}
		getActivity().getSupportFragmentManager().beginTransaction().add(R.id.content, fragment).addToBackStack(null).commit();
	}

	protected void finishFragment() {
		getFragmentManager().popBackStack();
	}

	public void onPressedBackkey() {
		finishFragment();
	}
}

3. 이제 BaseFragment를 상속한 DummyFragment를 만듭니다. 실제 구현되었을때 사용방법입니다.

자기 자신의 인스턴스된 횟수를 TextView에 표시하며, 다음 Fragment를 호출하는것과 자기자신을 종료하는 버튼을 가지고있습니다. 물론 addFragment에 add stack 해놓았으니 백키로도 스택 팝업이 됩니다.

onClickListener를 보면 startFragment와 finishFragment 항목이 보입니다. BaseFragment에서 구현한 것이지요.

package com.example.startfragmenttest;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class DummyFragment extends BaseFragment implements View.OnClickListener {

	protected static volatile int instanceCount;

	public DummyFragment() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		LinearLayout root = new LinearLayout(getActivity());
		root.setOrientation(LinearLayout.VERTICAL);
		root.setBackgroundColor(Color.GREEN);

		TextView tv = new TextView(getActivity());
		tv.setText("fragment " + instanceCount);

		Button btnNew = new Button(getActivity());
		Button btnFinish = new Button(getActivity());
		btnNew.setId(0xA0A0);
		btnFinish.setId(0xA0A1);
		btnNew.setText("add fragment");
		btnFinish.setText("finish");

		btnNew.setOnClickListener(this);
		btnFinish.setOnClickListener(this);

		root.addView(tv);
		root.addView(btnNew);
		root.addView(btnFinish);

		return root;
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case 0xA0A0:
			Log.i(getClass().getSimpleName(), "start");
			startFragment(getFragmentManager(), DummyFragment.class);
			break;
		case 0xA0A1:
			Log.i(getClass().getSimpleName(), "finish");
			finishFragment();
			break;

		default:
			break;
		}
	}

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		instanceCount++;
	}

	@Override
	public void onDetach() {
		super.onDetach();
		instanceCount--;
	}
}

 

4. 이제 액티비티에 셋팅합니다.

package com.example.startfragmenttest;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;

public class MainActivity extends ActionBarActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		if (savedInstanceState == null) {
			getSupportFragmentManager().beginTransaction().replace(R.id.content, new DummyFragment()).commit();
		}
	}
}

 

 

 

 

참 쉽죠?

칠리님 (10,910 포인트) 님이 2014년 7월 22일 답변
액티비티처럼 플래그먼트에서 다름 플래그 먼트로 가고 싶다면 startFragment를 호출하시면 되고, 종료하시려면 finishFragment를 호출하시면 됩니다.
혹 옵저버 패턴으로 한소스를 볼수있을까요ㅠㅠ
0 추천
플래그 먼트간 화면 전환이라고 해봐야 액티비티 전환하는 것마냥 되는 것은 아니구요.

예를 들어 님이 위에 기제하신

메인 액티비티가 플래그 먼트 액티비티를 확장하고 있고

그 이하 플래그 먼트들은 각각 플래그먼트를 확장하고 onCreateView를 통해 레이아웃을 가지고 잇는 상태여야 합니다.

그 상태에서 원하시는 대로 플래그먼트간 액티비티 이동하는 것처럼 하시면 됩니다.
쭈쭈총각 (17,750 포인트) 님이 2014년 7월 22일 답변
0 추천
getActivity 하면 액티비티 가져올텐데여?

메인액티비티에다가 함수하나 만들고 이동할것들 정의하고 각 프래그먼트에서 그거 호출하면 될텐데요
건방진프로그래머 (26,630 포인트) 님이 2014년 7월 22일 답변
...