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

프래그먼트 질문입니다..

0 추천
public class MainActivity extends AppCompatActivity {

    MainFragment mainFragment;
    MenuFragment menuFragment;

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

        mainFragment = (MainFragment) getSupportFragmentManager().findFragmentById(R.id.mainFragment);
        menuFragment = (MenuFragment) getSupportFragmentManager().findFragmentById(R.id.menuFragment);
//        menuFragment = new MenuFragment();

    }

    public void onFragMentChanged(int index) {
        if( index == 0 ) {
            getSupportFragmentManager().beginTransaction().replace(R.id.container, mainFragment).commit();
        }
        else if ( index == 1) {
            getSupportFragmentManager().beginTransaction().replace(R.id.container, menuFragment).commit();
        }
    }
}

MainActivity.java

 

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <fragment
        android:id="@+id/mainFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.example.test.MainFragment"/>

    <fragment
        android:id="@+id/menuFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.example.test.MenuFragment"/>
</FrameLayout>

activity_main.xml

 

public class MainFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_main, container, false);

        Button button = rootView.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MainActivity activity = (MainActivity) getActivity();
                activity.onFragMentChanged(1);
            }
        });
        return rootView;
    }
}

MainFragment.xml

 

<?xml version="1.0" encoding="utf-8"?>
<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:background="#A8DEF6"
    android:orientation="vertical"
    tools:context=".MainFragment">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="메인 프래그먼트"
        android:textSize="50sp" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="화면 전환" />
</LinearLayout>

fragment_main.xml

 

public class MenuFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_menu, container, false);

        Button button = rootView.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MainActivity activity = (MainActivity) getActivity();
                activity.onFragMentChanged(0);
            }
        });
        return rootView;
    }
}

MenuFragment.java

<?xml version="1.0" encoding="utf-8"?>
<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:background="#99F19D"
    android:orientation="vertical"
    tools:context=".MainFragment">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="메뉴 프래그먼트"
        android:textSize="50sp" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="돌아가기" />
</LinearLayout>

fragment_menu.xml

 

안드로이드 초보,,프래그먼트 공부중입니다..영상보면서 공부중인데 이해가 안되는 부분이 있어서

질문드립니다. 원래 코드는 화면전환 버튼을 누르면 다른 프래그먼트를 보여주고 그 프래그먼트 화면에서 돌아가기 버튼을 누르면 다시 이전 프래그먼트를 보여주는 코드입니다.

즉 해당 프래그먼트에서 버튼을 누르면 프래그먼트 두개를 서로 계속해서 전환해서 보여주는 것입니다.

 

공부중에 MainActivity.java 파일의 주석 처리한

 menuFragment = new MenuFragment(); 부분이 원본 코드이고

getSupportFragmentManager().findFragmentById(R.id.menuFragment);

이 부분이 제가 넣은부분 입니다, 또한

activity_main.xml의  아이디가 menu_fragment 인 프래그먼트 태그도 마찬가지로 제가 넣은것입니다.

 

이걸 왜 넣었냐면 주석처리한 부분이 왜 있는지 이해가 가질 않기때문입니다..

new를 해준것보니 객체를 생성했다는 말인데..제가 공부하기로는 인플레이션하는 과정이 메모리에

올라가 객체가 만들어지는 과정이라고 배웠거든요..

근데 MenuFragment.java파일이나 MainFragment.java 파일이나 보시다시피 둘다 인플레이션을 해주는데

Menu프래그먼트만 new를 해주는 이유가 무엇인가요?

제가 추가한 코드를 넣고하니 MainFragment가 먼저 뜨지않고 MenuFragment 화면이 먼저뜨고 버튼을 누르니 앱이 죽어버리더군요.. 

 

main 프래그먼트든 menu프래그먼트든 소슨느 똑같이 짰고 xml도 똑같이 짰고 뭐..아이디 이런것만 다르지

두개다 똑같이 만들었으니 버튼 클릭할때 인덱스만 다르게줘서  해줘도 충분히 실행가능할거라 생각했는데 

바로 죽어버리니 이해하기가 어렵네요..

 

프래그먼트 너무 어렵네요 ㅠ

 

 

--------------------------------------------------------------------

원본 MenuFragment.java 입니다

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

    }
}

그리고 본문에서도 언급했듯이 주석이나 activity_main.xml 부분에서 아이디가 menu_fragment 인 프래그먼트 태그가 없는것이 원래 영상에서 진행했던 코드입니다.

참고바랍니다 감사합니다

codeslave (3,940 포인트) 님이 2020년 8월 19일 질문
codeslave님이 2020년 8월 21일 수정

1개의 답변

0 추천
생각하신대로 menu fragment만 new 하는 것은 잘못된 코드 입니다.

첨부된 코드로 test해보니 저는 앱이 죽지는 않았습니다.

예측컨데, 첨부되지 않은 onFragMentChanged(int index) 함수내에 logic이 문제인 것 같습니다.
디자이너정 (42,810 포인트) 님이 2020년 8월 19일 답변
선생님 우선 답변감사드립니다.
제가 실수로 onFragmentChanged() 부분을 짤라서 올려버렸네요. 수정했습니다.
다시한번 봐주시면 감사하겠습니다.

그리고 new 하는것은 잘못된 코드라고 하셨는데, 제가 do it안드로이드 스튜디오 유튜브를 보고 공부를 하는데 해당 영상에서는 menuFragment라는 것은 xml 레이아웃에 추가되어있지 않다고 언급을 하면서 new 키워드를 쓰는데요. 제가 무엇을 잘못이해하고 있는 걸까요? 혹시해서 유튜브 링크도 남겨드립니다
https://www.youtube.com/watch?v=BKzoDGEUC3E&list=PLzkhjlqMgxvBxi3Wyak9NicQI7UwhFU2O&index=39
7분 5초부터 보시면 될것같습니다

원래 원본 영상은 fragment_main.xml의 화면전환 버튼을 누르면 fragment_menu.xml로 바뀌는 코드입니다. 바뀐 화면에서는 돌아가기 버튼을 눌러도 돌아가지 않는게 원본 코드입니다. 버튼을 눌러도 돌아가도록 기능이 설정되어있지않으니까요. 근데 제가 왔다갔다 하는 코드를 공부해보려고 추가한것이 본문 코드인데..잘이해가 가질 않습니다 뭐가 잘못 되었을까요?

혹시해서 MenuFragment.java 의 원본 소스도 추가해서 올리겠습니다
첨부된 유튜브 내 예제 소스와 질문에 올려주신 소스 내용이 서로 다르네요.
유뷰브 내 예제에는 activity_main.xml에 fragment가 하나만 추가되어 있습니다.
그래서 MenuFragment를 따로 new하는 것 입니다.
본문에도 써놨지만 activity_main.xml의 id menu_fragment..즉 메뉴 프래그먼트는 제가 추가한것입니다. 유튜브 내용은 앱 실행후 버튼을 클릭하면 프래그먼트가 전환은 되지만 전환된 프래그먼트에서 버튼을 누르면 다시 원래 프래그먼트로 돌아오지 않습니다. 저는 제가 공부겸 수정을 해서 계속해서 전환하는 기능을 만들려고 하는 것입니다.

와중에 궁금했던게 MainActivity.java에서
 mainFragment =(MainFragment) getSupportFragmentManager()~~~
으로 했지만 menuFragment는 new로 작성됐던게 이해되지 않았기도하고
mainFragment와 똑같이 작성해주면 되겠다 싶어 menuFragment도 같은 방식으로 작성했습니다.

그리고 activity_main.xml에 메뉴 프래그먼트를 하나 더 추가한것이구요...
mainFragment와 똑같은 방식으로 menuFragment를 추가했는데도 동작하지 않는 이유가 궁금합니다..

요약하자면 new 부분을 빼고 MainActivity.java에서  menuFragment를 mainFragment와 똑같은 방식으로 진행하고 actyvity_main.xml에서 fragment를 추가하는 방식은 왜 안되는 것인지 궁금합니다.

+) 답변주신 new와 관련해서는 유튜브의 본 소스에서는 actyvity_main.xml 내에
메뉴 프래그먼트가 없는데 없으면 new로 진행을 해줘야만 하나요?
저는MenuFragment.java와 fragment_menu.xml이 인플레이션을 했기때문에 메모리에 객체화 되었다고 배워서 딱히 필요 없는줄 알았는데..잘못알고 있는건가요?
fragment_menu.xml 파일을 작성한 것만으로 메모리에 객체화 되지는 않습니다.
fragment_menu.xml 파일을 실제로 inflate하는 곳은 MenuFragment.java 밖에 없기 때문에
MenuFragment.java이 실제로 메모리화 되어야합니다.
MenuFragment.java이 메모리화 되는 것은 new 통해 이루어 집니다.
음 제가 댓글을 읽고 이해하는 것을 적어보자면..
메모리화, 객체화라는 것은 inflate라고 하는데 fragment_menu.xml을 MenuFragment.java와 연결(?)하고 메모리에 올리는..그러니까 inflate하는 것은
MenuFragment.java에서 진행을하고 또!
이 MenuFragment도 inflate해야하는데 원본소스에서는 그게 없으니 new로 한것이다..

이게 맞나요? 이게 맞다면.. 저는 fragment_menu.xml을 MenuFragment.java에서 inflate 했으므로 여기서 끝났다고 생각했어요. MenuFragment도 inflate 하는건 몰랐습니다. xml파일을 inflate 했으니 사용할 수있을거라고 생각했거든요.

만약 이게 맞는다면 MainActivity.java내에서
 menuFragment =(MenuFragment) getSupportFragmentManager()~~~
로 진행하는건 왜 안될까요..? 물론 xml에도 fragment를 추가했을때 얘기에요!

자꾸 질문드려죄송합니다
...