반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

[CookBook] Fragments 이해하기 -9-

2013. 10. 1. 21:11 | Posted by 솔웅


반응형

Displaying Dialog Through DialogFragment



안드로이드에서는 dialogs가 비동기적입니다. 동기적인 dialogs들은 이 dialog가 실행되는 동안 activity가 suspends 됩니다. 유저가 이 dialog를 사용하고 있는 동안에는 다른 것들이 올 수 없습니다. 비동기적인 dialogs들은 유저가 dialog를 사용하고 있는 동안에도 activity의 작업은 계속 됩니다. 이 activity는 콜백 메소드를 implement 함으로서 dialog와 함께 유저의 접근을 허용할 수 있습니다. 안드로이드의 dialogs는 자연스럽습니다. dialog가 open 돼 있는 동안 유저는 어플리케이션의 다른 부분에 접근할 수 없습니다. dialog를 비동기적으로 호출하는 방법의 잇점은 코딩을 줄일 뿐만 아니라 code를 통해서 이 dialog를 dismiss 할 수 있는 기능이 제공 된다는 것입니다.



DialogFragment base class를 extends 함으로서 DialogFragment를 사용하실 수 있습니다. 이 DialogFragment base 클래스는 Fragment 클래스에서 파생된 것입니다. 이 DialogFragment를 구현하기 위해 DialogFragmentApp이라는 프로젝트를 만들겠습니다. 여기에는 두개의 fragments들이 있을 건데요. 하나는 DialogFragment를 보여줄거고 다른 하나는 텍스트뷰를 보여줄 겁니다. DialogFragment와 유저의 상호작용은 두번째 fragment에 있는 텍스트뷰를 통해서 이뤄질 겁니다. DialogFragment에 있는 selected button은 두번째 fragment의 텍스트뷰를 통해서 display 됩니다.




이 DialogFragment를 만들기 전에 우선 텍스트뷰를 가지고 있는 fragment의 UI를 정의하겠습니다.


fragment2.xml



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView 
        android:id="@+id/selectedopt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Select Open Dialog Button"
        android:textSize="@dimen/text_size"
        android:textStyle="bold" />
</LinearLayout>



LinearLayout 안에 id 가 selectedopt인 한개의 TextView 가 있습니다. 여기에 할당된 텍스트는 Select Open Dialog Button이네요. 볼드체이고 사이즈는 dimension resource의 text_size를 갖다가 사용합니다.
이 UI를 load 할 자바 클래스를 만들어 보죠.



Fragment2Activity.java



public class Fragment2Activity extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment2, container, false);
    }
}



아주 간단합니다. Fragment base 클래스를 extends 했고 onCreateView() 메소드 안에는 방금 만들었던 fragment2.xml 의 UI를 로드하기 위해 LayoutInflater를 사용했습니다.



이 fragment를 사용할 layout xml파일을 만들겠습니다.



activity_dialog_fragment_app.xml



<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >
    <fragment
        android:name="com.androidtablet.dialogfragmentapp.Fragment2Activity"
        android:id="@+id/fragment2"
        android:layout_weight="0"
        android:layout_width="wrap_content"
        android:layout_height="match_parent" />
    <Button
        android:id="@+id/dialog_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Open Dialog"
        android:textSize="@dimen/text_size" />
</LinearLayout>


Button 이 있습니다. 이 버튼을 클릭하면 DialogFragment가 나타나도록 할 겁니다. fragment와 button 이 LinearLayout 안에 배치해 있습니다. Fragment는 id 가 fragment2 이고 Button 은 id 가 dialog_button 입니다. Caption은 Open Dialog로 돼 있네요. 이 Caption은 dimention resource에서 text_size로 정의된 텍스트 크기를 가질 거구요.



이제 DialogFragment를 보여줄 코드를 작성할 차례입니다. DialogFragment를 보이기 위해서 자바 클래스는 DialogFragment 클래스를 extend 해야 합니다.



Fragment1Avtivity.java



public class Fragment1Activity extends DialogFragment{
    static Fragment1Activity newInstance(String title) {
        Fragment1Activity fragment = new Fragment1Activity();
        Bundle args = new Bundle();
        args.putString("title", title);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {   
        String title = getArguments().getString("title");
        Dialog diag = new AlertDialog.Builder(getActivity())
        .setIcon(R.drawable.ic_launcher)
        .setTitle(title)
        .setPositiveButton("OK", new DialogInterface.
            OnClickListener() {
            public void onClick(DialogInterface dialog, int
                whichButton) {
                ((DialogFragmentAppActivity) getActivity()).PositiveButton();
            }
        })
        .setNegativeButton("Cancel", new DialogInterface.
            OnClickListener() {
            public void onClick(DialogInterface dialog, int
                whichButton) {
                ((DialogFragmentAppActivity) getActivity()).NegativeButton();
            }
        }).create();
 
        return diag;
    }
}



보시다시피 DialogFragment를 생성하기 위해 이 자바 클래스는 DialogFragment 클래스를 extends 했습니다.
newInstance() 메소드는 이 fragment의 new instance를 생성합니다. 이 DialogFragment의 제목이 파라미터로 전달 됩니다. 이 파라미터는 Bundle 에 저장되고 fragment에 세팅 됩니다. (setArguments().



DialogFragment의 view hierarchy를 생성하기 위해 onCreateDialog() 메소드를 오버라이드 합니다. 그리고 title을 만들기 위한 Bundle 객체가 파라미터로 전달 됩니다. 이 onCreateDialog() 메소드 안에서 이 Dialog를 생성하기 위해 AlertDialog.Builder()를 사용하시는 것을 보실 수 있을 겁니다. 여기에 아이콘을 세팅하고 타이틀을 세팅하고 OK 버튼과 Cancel 버튼을 생성합니다.
이 OK와 Cancel 버튼에는 각각 onClickListener()를 달구요. OK를 클릭하면 PositiviButton() 메소드가 호출 디고 Cancel 버튼을 클릭하면 NegativeButton()이 호출 됩니다.



마지막에 이 메소드에서는 이 AlertDialog를 return 하구요.



이제 이 DialogFragment를 invoke 시킬 자바 액티비티 파일을 만들어야 합니다. 이 java activity file에는 OK와 Cancel을 눌렀을 때 실행되어야 할 PositiveButton()과 NegativeButton()메소드들이 구현되어야 하구요.



DialogFragmentAppActivity.java



public class DialogFragmentAppActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dialog_fragment_app);
        Button dialogButton = (Button)findViewById(R.id.dialog_button);
        dialogButton.setOnClickListener(new Button.OnClickListener(){
            @Override
            public void onClick(View arg0) {
                Fragment1Activity dialogFragment =
                    Fragment1Activity.newInstance( "Continue Processing?");
                dialogFragment.show(getFragmentManager(),  "Dialog Fragment Example");
            }
        });
    }

    public void PositiveButton() {
        TextView selectedOpt = (TextView)findViewById(R.id.selectedopt);
        selectedOpt.setText("You have selected OK button");
    }

    public void NegativeButton() {
        TextView selectedOpt = (TextView) findViewById(R.id.selectedopt);
        selectedOpt.setText("You have selected Cancel button");   
    }
}


onCreate() 메소드를 보시면 아까 만들었던 activity_dialog_fragment_app.xml 의 UI를 view로 set 하고 그 안의 Button에 대한 객체를 만듭니다. 그리고 이 버튼에 리스너를 달아서 클릭하면 Fragment1Activity.java 의 newInstance() 메소드를 호출합니다. 이때 타이틀이 될 Continue Processing?이라는 텍스트가 파라미터로 전달 되구요.
이 DialogFragment는 show() 메소드를 호출함으로서 visible 하게 됩니다. 이 show() 메소드는 이 fragment를 주어진 FragmentManager에 추가하게 되죠.
이 코드에는 아까 말했듯이 PositiveButton()과 NegativeButton() 메소드가 구현되었습니다. OK와 Cancel 버튼이 눌렸을 때 호출될 메소드 들입니다. 이 두 메소드에서는 모두 selectedopt라는 id를 가진 텍스트뷰의 객체를 만들고 여기에 text를 세팅하고 있습니다.



이 앱을 실행하고 Open Dialog 라는 버튼을 누르면 AlertDialog가 뜹니다. 여기서 OK를 누르면 이 Dialog 가 사라지고 왼쪽의 텍스트뷰에 You have selected OK Button이 쓰여지고 Cancel을 누르면 You have selected Cancel button 이 출력됩니다.



이 Dialog box는 사용자에게 중요한 메세지를 alert 하거나 사용자로부터 어떤 feedback을 받을 때 사용합니다.

반응형