반응형

이전 포스트(Fragment 만들기) 에서

레이아웃 xml 파일안에 프레그먼트(Fragment)를 만들어서

화면에 보여주는 작업을 소개했습니다.


이번에는

이렇게 만들어진 Fragment를 보여주는 Activity에서 Fragment 안에 있는 View들을 제어하는 예제입니다.


간단하게 소개하기 위해

activity_main안에 Button을 하나 만들고

이 버튼을 누르면 Fragment안에 있는 TextView의 글씨가 변경되는 예제입니다.


동작결과입니다. 간단합니다.

노란색 배경이 Fragment가 보여주는 View의 영역입니다.

MainActivity의 버튼을 눌렀더니 Fragment 안에 있는 TextView의 글씨가 Hello 변경되었습니다.


  



이전 예제를 그대로 활용하겠습니다.


먼저 activity_main.xml에 버튼하나를 추가했습니다.

굵은 글씨가 추가된 부분입니다.

 

activity_main.xml

<LinearLayout 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"

    android:orientation="vertical">

    

    <TextView android:id="@+id/text"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="The TextView into the MainActivity"/>

    

    <Button android:id="@+id/btn"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="Change Text in the Fragment"

        android:onClick="mOnClick"/>

    

    <!-- TestFragment를 MainActivity가 보여줄 View로 고정시켜서 배치 -->

    <!-- 직접적으로 XML 레이아웃 파일에 태그문으로 생성된 Fragment는  동적으로 재배치/삭제 불가-->

    <fragment android:name="com.kitesoft.fragment.TestFragment"

        android:id="@+id/frag"

        android:layout_width="match_parent"

        android:layout_height="match_parent"/>    


</LinearLayout>

 

 


이제 제어하기 위한 자바 소스파일입니다.

가장 중요한 부분은 <fragment/>로 만들어진 Fragment

자바에서 참조하는 작업입니다.


xml에 만들어진 TextView나 ImageView 같은 View들

Java 소스코드 에서 참조하려면

findViewById()로 찾아옵니다.

메소드의 이름만 봐도 View객체를 찾으라는 것을 알수 있는 매우 직관적인 메소드명입니다.


우리가 하고자 하는 것은 Fragment를 찾는 것입니다.

Fragment는 View가 아닙니다.

이전에 사용했던 findViewById()는 좀 이상하지 않나요?

findFragmentById()가 맞지 않겠어요?

 맞습니다. 이 메소드를 사용해야 합니다. 하지만 애석하게도

Activity 클래스는 이런 메소드가 없습니다.


그래서 Activity 클래스 대신

Fragment를 제어하기 위한 별도의 클래스가 존재하게 됩니다.

Fragment를 add/remove/replace 하는 등의 작업들을 수행할 수 있도록 관리해주는

클래스라고 보면 됩니다.


이름도 참 직관적인 FragmentManager 입니다.

요놈이 findFragmentById() 메소드를 가지고 있습니다.

이 클래스 객체를 이용해서 Fragment가 보여주는 레이아웃(fragment_text.xml)안에 있는

View들을 제어합니다.


자바 소스파일입니다.

주석의 설명을 참고하시기 바랍니다.

 

 MainActivity.java

import android.app.Activity;

import android.app.FragmentManager;

import android.os.Bundle;

import android.view.View;

import android.widget.TextView;


public class MainActivity extends Activity {

TestFragment frag; //TestFragment 참조변수

FragmentManager manager; //FragmentManager 참조변수


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//Fragment는 View가 아닌만큼 다른 Widget을 찾을 때 처럼 

//findViewById()메소드를 사용할 수 없음

//대신 findFragmentById()메소드를 사용해서 찾아와야 하지만

//Activity 클래스는 이런 메소드가 없음.

//대신 Fragment를 추가/삭제/재배치 등 제어를 할 수 있는 FragmentManager 클래스가 존재함.

//Fragment를 제어하기 위한 매니져 객체

manager= getFragmentManager();

//매니져 객체에게 findFragmentById()를 요청하면서 id 전달

frag= (TestFragment)manager.findFragmentById(R.id.frag);

}

//Activity가 보여주는 activity_main.xml 파일에 태그문으로

//onClick속성이 설정된 View를 클릭했을 때 자동으로 호출되는 콜백 메소드

public void mOnClick(View v){

switch( v.getId() ){

case R.id.btn:

//TestFragment 객체가 보여주고 있는 View 객체( fragment_test.xml 로 만들어진 View) 안에 있는

//TextView 객체를 찾아오기

TextView text= (TextView)frag.getView().findViewById(R.id.text_fragment);

//Fragment가 보여 주는 레이아웃 안에 있는 TextView의 글씨를 변경

text.setText("Hello");

break;

}

}

}


여기까지 입니다.


참고로

위의 방법은 Activity에서 Fragment안에 있는 TextView를 직접 참조해와서

제어하는 방식입니다.



객체 지향적 프로그래밍 방식의 기본 개념은


"니껀 니가!!"


즉, 그 객체의 멤버 변수는 그 객체 스스로 제어하는 것이 좋다는 것이죠.

그래야 재사용성이 높아지고

클래스 간의 독립성을 유지 할 수 있기 때문이죠.

시간이 나면 강좌게시판을 통해 자세히 설명할 예정입니다.


그래서 이를 좀 더 반영하여

Activity에서 Fragment의 TextView를 직접 제어하지 않고

Fragment의 특정 메소드에 값을 전달하고 Fragment가 전달 된 값으로 TextView의 글씨를 변경하도록 해보겠습니다.


TestFragment.java 파일과 MainActivity.java 파일의 일부분만 추가 변경해 주면 됩니다.


변경된 부분만 굵은 글씨로 소개합니다.

 

 TestFragment.java

public class TestFragment extends Fragment {

TextView text;  //TextView 참조변수

public TestFragment() {

// TODO Auto-generated constructor stub

}

//Fragment의 lifecycle 메소드 중에서 Fragment가 보여줄 View를 설정하는 메소드

//MainActivity.java 에서 onCreate() 메소드 안에 setContentView()하듯이

//Fragment에서는 이 메소드에서 Fragment가 보여줄 View 객체를 생성해서 return 시켜줘야 함.

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// TODO Auto-generated method stub

View view=null;//Fragment가 보여줄 View 객체를 참조할 참조변수

//매개변수로 전달된 LayoutInflater객체를 통해 fragment_test.xml 레이아웃 파일을

//View 객체로 생성

view= inflater.inflate(R.layout.fragment_test, null);

//위에 만들어진 view객체 안에 있는 TextView를 찾아오기

    text= (TextView)view.findViewById(R.id.text_fragment);

//생성된 View 객체를 리턴

return view;

}

//TextView의 글씨를 변경하기 위해 만든 메소드

public void setTextViewValue(String str){

text.setText(str); //전달 받은 문자열로 TextView의 글씨를 변경

}

}

 

 



 

MainActivity.java


      //... 위 생략


      //Activity가 보여주는 activity_main.xml 파일에 태그문으로

      //onClick속성이 설정된 View를 클릭했을 때 자동으로 호출되는 콜백 메소드

public void mOnClick(View v){

switch( v.getId() ){

case R.id.btn:

   /* 이 영역은 모두 주석 처리///////////////

//TestFragment 객체가 보여주고 있는 View 객체( fragment_test.xml 로 만들어진 View) 안에 있는

//TextView 객체를 찾아오기

TextView text= (TextView)frag.getView().findViewById(R.id.text_fragment);

//Fragment가 보여 주는 레이아웃 안에 있는 TextView의 글씨를 변경

text.setText("Hello");

*/

   //Fragment 객체안에 정의 된 TextView의 글씨를 변경하는 메소드를 호출면서 "Hello"문자열 전달.

frag.setTextViewValue("Hello");

   break;

}

}


동작의 결과는 같습니다.

필자의 경우는 이 방법을 더 선호합니다.



이번에 소개된 예제는 XML안에 Fragment를 태그문을 이용해 고정적으로 만들어낸 방식입니다.

이 방식은 Fragment의 값은 바꿀 수 있어도 Fragment 자체를 동적으로 재배치 하거나 삭제 하지 못하는 단점이 있습니다.


다음 포스트에서는 동적으로 Fragment를 추가하는 예제를 소개하겠습니다.


반응형

+ Recent posts