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

최근에 받은 트랙백

글 보관함

[CookBook] Fragments 이해하기 -6-

2013. 9. 29. 06:47 | Posted by 솔웅


Fragment1Activity.java



public class Fragment1Activity extends Fragment {
    OnOptionSelectedListener  myListener;
    @Override
    public View onCreateView(LayoutInflater inflater,
        ViewGroup container, Bundle savedInstanceState) {
        Context c = getActivity().getApplicationContext();
        View vw = inflater.inflate(R.layout.fragment1, container, false);
        String[] products={"Camera", "Laptop", "Watch", "Smartphone", "Television"};
        ListView productsList = (ListView) vw.findViewById(R.id.products_list);
        ArrayAdapter<String> arrayAdpt= new ArrayAdapter <String>(c, R.layout.list_item, products);
        productsList.setAdapter(arrayAdpt);
        productsList.setOnItemClickListener(new OnItemClickListener(){
            @Override
            public void onItemClick(AdapterView<?> parent, View v, int position, long id){
                myListener.onOptionSelected(((TextView) v).getText().toString());  
            }
        });
        return vw;
    }
   
    public interface OnOptionSelectedListener {
        public void onOptionSelected(String message);
    }

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




이 Fragment1Activity 클래스는 Fragment 클래스를 extends 했습니다. onCreateView() 메소드 안에서는 LayoutInflater 객체가 fragment1.xml 에서 정의된 ListView를 inflate하기 위해 사용됐습니다. 이 리스트 뷰는 product_list라는 id를 가진 xml 내의 listview 를 가져와서 productsList 라는 객체에 넣었습니다. 그리고 ArrayAdapter 를 사용해서 list_item.xml 을 이용해서 각 아이템들을 세팅하고 구체적인 아이템 내용은 products 배열에서 가져오고 있습니다. 그리고 이 Adapter를 productsList에 세팅합니다. 그리고 productsList 에 onItemClickListener를 달아서 리스트뷰 내의 아이템이 선택되면 어떤 일을 하도록 정의합니다. setOnItemClickListener 안에는 inItemClick()이라는 콜백 메소드가 있는데요. 아이템이 클릭되면 이 메소드가 자동으로 호출됩니다. 여기서는 아이템이 클릭되면 onOptionSelected() interface를 호출하네요. 그 인터페이스 안에는 onOptionSelected() 메소드가 선언돼 있구요. 이 fragment와 연관된 activity는 OnOptionSelectedListener 인터페이스를 implements 했을 겁니다. 그리고 이 인터페이스의 body인 onOptionSelected() 메소드를 구현했을 거구요. 그러니까 여기서 아이템이 클릭되면 구체적인 동작은 이 OnOptionSelectedListener 인터페이스를 implements 한 activity에서 구현됩니다.



이제 만들어야 할 파일은 Fragment2Activity.java인데요. 여기서는 아래 두가지 일을 해야 합니다.

- fragment2.xml 에서 UI를 load 합니다.
- 유저가 선택한 제품을 출력할 dispOption 메소드를 정의 해야 합니다.



이 두가지 일을 하기 위해서 아래와 같이 코딩을 합니다.



Fragment2Activity.java



public class Fragment2Activity extends Fragment {
    TextView selectedOpt;
    String messageReceived="";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View vw= inflater.inflate(R.layout.fragment2,  container, false);
           Bundle bundle=getArguments(); 
           if(bundle !=null) {
               messageReceived = bundle.getString("msg");
               selectedOpt = (TextView) vw.findViewById(R.id.selectedopt);
               selectedOpt.setText(messageReceived);
           }
           return vw;     
    }

    public void dispOption(String msg){
        TextView selectedOpt = (TextView) getActivity().findViewById(R.id.selectedopt);
        selectedOpt.setText("You have selected "+msg);  
    }
}


여기서도 fragment를 생성하기 위해 Fragment 클래스를 extends 했습니다. 그리고 onCreateView() 메소드를 오버라이드 해서 그 안에서 LayoutInflater 객체를 이용해 fragment2.xml 안에 정의된 TextView를 inflate 했습니다. 리스트뷰에서 선택된 제품 이름은 dispOption() 메소드로 전달되서 이 TextView 를 통해 화면에 뿌려질 겁니다.



이제 맨 처음 만든 activity_fragments_by_code_app.xml 을 불러와서 사용할 java 파일을 만들 차례입니다.
이 xml layout에 정의된 frag1_container와 frag2_container로 id가 정의된 LinearLayout 에 위에서 만든 fragment들을 배치시켜야겠죠.
소스 내용은 아래와 같습니다.



FragmentsByCodeAppActivity.java



public class FragmentsByCodeAppActivity extends Activity implements OnOptionSelectedListener {
    private static final String TAG1 = "1";
    private static final String TAG2 = "2";
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragments_by_code_app);
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        if(null==fragmentManager.findFragmentByTag(TAG1)){
            Fragment1Activity fragment1 = new Fragment1Activity();
            fragmentTransaction.add(R.id.frag1_container, fragment1, TAG1); 
        }
        Bundle args = new Bundle();
        String message="Message from Fragment 1";  
        if(null==fragmentManager.findFragmentByTag(TAG2)){
            Fragment2Activity fragment2 = new Fragment2Activity();
            args.putString("msg", message);
            fragment2.setArguments(args);
            fragmentTransaction.add(R.id.frag2_container, fragment2, TAG2); 
        }
        fragmentTransaction.commit();
        }

    public void onOptionSelected(String msg){
        Fragment2Activity frag2 = (Fragment2Activity) getFragmentManager().findFragmentById(R.id.frag2_container);
        frag2.dispOption(msg);             
    }
}


보시면 FragmentManager 객체를 보실 수 있을 겁니다. fragment에 접근할 수 있도록 해주는 클래스 입니다. fragment를 추가하거나 제거하거나 replace를 해야 될 때 사용할 FragmentTransaction도 이 FragmentManager의 beginTransaction() 메소드를 사용해서 정의했습니다.



그리고 frag1_container에 첫번째 fragment를 넣고 frag2_container에 두번째 fragment를 넣었습니다. 넣기 전에 이미 존재하는지 여부를 먼저 체크했습니다. 이때 Fragmentmanager의 findFragmentByTag() 메소드를 사용했죠. 두번째 fragment에는 메세지도 argument로 세팅했습니다. 그 다음에 FragmentTransaction 클래스의 commit()메소드를 사용해서 작업을 완료합니다.



그 아래에 onOptionSelected() 메소드가 있는데요. 이것은 ListView에서 아이템이 선택됐을 때 실행될 메소드 입니다. 선택된 제품을 fragment2의 TextView에 표시하도록하는 메소드죠.



이로서 동적으로 fragment를 생성하고 할당해서 사용하는 코드가 완성됐습니다.

반응형

Comment