Android에서 조각 숨기기 표시


100

2 개의 조각이 포함 된 응용 프로그램을 개발 중이며 필요에 따라 숨기기를 표시하고 싶습니다. 다음 코드에는 내 문제에 대한 간단한 예가 있습니다. 이 간단한 Fragmentactivity에는 버튼 1 개와 listfragment 1 개가 있습니다.

이 간단한 예제는 완벽하게 작동합니다. 그러나 나는 show hide 조각에 만족하지 않습니다. layout.setVisibility (View.GONE); 코드에서 ft.hide (f); 조각을 숨기지 않습니다. 사실 우리는 조각을 숨기지 않고 컨테이너를 숨기고 있습니다.

내 질문은, 이것이 조각 숨기기를 표시하는 방법입니까? 그렇지 않다면 많은 사람들이이 문제에 직면하고 있기 때문에 프래그먼트를 숨기고 표시하는 방법을 테스트 한 예제로 설명하십시오.

 public class MainActivity extends FragmentActivity implements OnClickListener {

        Fragment1 f;
        Button b;
        LinearLayout layout;
        Fragment myf;
        @Override
        public void onCreate(Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            b = (Button) findViewById(R.id.button1);
            layout = (LinearLayout) findViewById(R.id.ll);
            f = new Fragment1();
        }

        @Override
        public void onClick(View v) {

            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);

            if (f.isHidden()) {
                ft.show(f);
                layout.setVisibility(View.VISIBLE);
                b.setText("Hide");
            } else {
                ft.hide(f);
                b.setText("Show");
                layout.setVisibility(View.GONE);
            }
            ft.commit();
            // TODO Auto-generated method stub
        }

컨테이너의 가시성을 설정해야하는 이유는 무엇입니까? 가시성을 설정하지 않고 작동해야합니다.
Andrii Chernenko 2013 년

정확히 컨테이너가 보이지 않고 작동해야하지만 작동하지 않습니다. 간단한 작업 예제를 저와 공유 해주세요. 그럼 내가 어디 있는지 알 수있을거야.
abidkhan303

1
내 생각 엔 당신은 매번 조각의 다른 인스턴스를 표시하거나 숨기려고합니다. 조각을 추가 할 때 (이 코드는 보이지 않습니다) 태그와 함께 추가 한 다음 해당 태그로 검색합니다 (참조를 저장하려는 대신). 그것은 당신이 놓친 것일 수 있습니다.
Andrii Chernenko

답변:


159

컨테이너의 가시성 플래그를 엉망으로 만들지 마십시오. FragmentTransaction.hide / show가 내부적으로 수행합니다.

따라서이를 수행하는 올바른 방법은 다음과 같습니다.

FragmentManager fm = getFragmentManager();
fm.beginTransaction()
          .setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
          .show(somefrag)
          .commit();

또는 android.support.v4.app.Fragment를 사용하는 경우

 FragmentManager fm = getSupportFragmentManager();
 fm.beginTransaction()
          .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
          .show(somefrag)
          .commit();

5
플래그를 직접 엉망으로 만드는 것을 권장하지 않는 이유는 무엇입니까? (난 그냥 그것을 이해하려고, 당신의 추천 이의를 제기하고 있지 않다.)
엘렌 스퍼터 스

1
예, 귀하의 원본 메시지에서 읽었습니다. 추가 오버 헤드에 대한 정당성을 추가 할 수 있기를 바랍니다. 그 동안 백 스택에 추가하는 옵션과 같은 일부를 발견했습니다.
Ellen Spertus 2014

2
낮은 수준의 API와 높은 수준의 API에서 플래그를 변경할 수 있기 때문에 오류가 발생하기 쉬우 며주의하지 않으면 (예 : 플래그가 동기화되지 않음) 이상한 버그를 쫓을 수 있습니다. 그렇기 때문에 조각 관리자를 사용하여 조각을 숨기고 표시하는 것이 좋습니다.
numan salati 2014

안녕 @numansalati의 버전 (지원 라이브러리에서) 어떤 호환성 (을)가 android.R.animator.fade_in, 그리고 android.R.animator.fade_out?
Solace

1
컨테이너를 사용하여 SHOW, HIDE 또는 GONE으로 설정할 수 있습니다. 조각을 숨길 때 GONE 옵션이 없습니다.
Stealth Rabbi

58

또한 Fragment에서 수행 할 수 있습니다 (예 : 서버 데이터 가져 오기 실패시).

 getView().setVisibility(View.GONE);

11
Fragment는 View가 아닌 ​​Object의 자식이므로 호출 할 수 없습니다. fragment.setVisibility (View.INVISIBLE);
AndroidGeek

8
Arià는 다른 것을 제안하고 해당 조각에서보기를 가져와 가시성을 제거하도록 제안하고 있습니다.
AlvaroSantisteban 2014 년

10
아직 초기화되지 않은 경우 주의 getView()할 수 있습니다 null.
TWiStErRob

23

안녕하세요,이 접근 방식을 사용하면 모든 조각이 처음에 추가되면 컨테이너에 남아 있으며 원하는 조각을 표시하고 다른 조각은 컨테이너 내에 숨 깁니다.

// Within an activity
private FragmentA fragmentA;
private FragmentB fragmentB;
private FragmentC fragmentC;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (savedInstanceState == null) {
        fragmentA = FragmentA.newInstance("foo");
        fragmentB = FragmentB.newInstance("bar");
        fragmentC = FragmentC.newInstance("baz");
    }
}


// Replace the switch method
protected void displayFragmentA() {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    if (fragmentA.isAdded()) { // if the fragment is already in container
        ft.show(fragmentA);
    } else { // fragment needs to be added to frame container
        ft.add(R.id.flContainer, fragmentA, "A");
    }
    // Hide fragment B
    if (fragmentB.isAdded()) { ft.hide(fragmentB); }
    // Hide fragment C
    if (fragmentC.isAdded()) { ft.hide(fragmentC); }
    // Commit changes
    ft.commit();
}

자세한 내용은 https://github.com/codepath/android_guides/wiki/Creating-and-Using-Fragments 를 참조 하세요 . 누군가를 도울 수 있기를 바랍니다. 이것은 오래된 질문이더라도.


1
따라서 displayFragmentB () 및 displayFragmentC ()와 같은 두 가지 메서드가 더 있어야합니까?
temirbek

예 @temirbek displayFragmentA () 메서드가 구현되는 방법을 따를 수 있습니다.
mangu23

1
하나의 활동 (2 개 이상)에 여러 조각이 있고 위의 방법을 사용하는 경우 이를 사용 하십시오 . 쓰기와 읽기가 더 쉬울 것입니다.
막심 클로드

8
public void showHideFragment(final Fragment fragment){

    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.setCustomAnimations(android.R.animator.fade_in,
                    android.R.animator.fade_out);

    if (fragment.isHidden()) {
        ft.show(fragment);
        Log.d("hidden","Show");
    } else {
        ft.hide(fragment);
        Log.d("Shown","Hide");                        
    }

    ft.commit();
}

1
올바른 것은 ft.setCustomAnimations (android.R.anim.fade_in, android.R.anim.fade_out);
Webserveis

8

이 시도:

MapFragment mapFragment = (MapFragment)getFragmentManager().findFragmentById(R.id.mapview);
mapFragment.getView().setVisibility(View.GONE);

2

내 코드에서 위의 솔루션과 비교할 때 가장 간단한 방법은 조각을 포함하는 레이아웃을 정의하는 것입니다. 그런 다음 일반적인보기 방식과 일치하는 레이아웃 속성을 제어하여 조각을 숨기거나 숨김 해제 할 수 있습니다. 이 경우 추가 코드가 필요하지 않으며 조각의 추가 배포 속성을 외부 레이아웃으로 이동할 수 있습니다.

<LinearLayout style="@style/StHorizontalLinearView"
    >

    <fragment
        android:layout_width="match_parent"
        android:layout_height="390dp"
        android:layout_alignParentTop="true"
        />

</LinearLayout>

0

이것은 나를 위해 일했습니다.

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        if(tag.equalsIgnoreCase("dashboard")){

            DashboardFragment dashboardFragment = (DashboardFragment)
                    fragmentManager.findFragmentByTag("dashboard");
            if(dashboardFragment!=null) ft.show(dashboardFragment);

            ShowcaseFragment showcaseFragment = (ShowcaseFragment)
                    fragmentManager.findFragmentByTag("showcase");
            if(showcaseFragment!=null) ft.hide(showcaseFragment);

        } else if(tag.equalsIgnoreCase("showcase")){
            DashboardFragment dashboardFragment = (DashboardFragment)
                    fragmentManager.findFragmentByTag("dashboard");
            if(dashboardFragment!=null) ft.hide(dashboardFragment);

            ShowcaseFragment showcaseFragment = (ShowcaseFragment)
                    fragmentManager.findFragmentByTag("showcase");
            if(showcaseFragment!=null) ft.show(showcaseFragment);
        }

        ft.commit();

0

여기에 대한 답변은 정확하고 @Jyo the Whiff 아이디어를 좋아했습니다. 그가 현재 첫 번째 실행에서 조각을 숨기는 방식을 제외하고는 조각 구현을 숨길 수 있으므로 약간의 변경 사항을 추가했습니다. 조각이 아직없는 경우

public void showHideCardPreview(int id) {
    FragmentManager fm = getSupportFragmentManager();
    Bundle b = new Bundle();
    b.putInt(Constants.CARD, id);
    cardPreviewFragment.setArguments(b);
    FragmentTransaction ft = fm.beginTransaction()
        .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
    if (!cardPreviewFragment.isAdded()){
        ft.add(R.id.full_screen_container, cardPreviewFragment);
        ft.show(cardPreviewFragment);
    } else {
        if (cardPreviewFragment.isHidden()) {
            Log.d(TAG,"++++++++++++++++++++ show");
            ft.show(cardPreviewFragment);
        } else {
            Log.d(TAG,"++++++++++++++++++++ hide");
            ft.hide(cardPreviewFragment);
        }
    }

    ft.commit();
} 

0
final Fragment fragment1 = new fragment1();
final Fragment fragment2 = new fragment2();
final FragmentManager fm = getSupportFragmentManager();
Fragment active = fragment1;

onCreate에서 setContentView 후 두 개의 조각을 숨기고 조각 관리자에게 커밋했지만 홈으로 사용할 첫 번째 조각을 숨기지 않았습니다.

fm.beginTransaction().add(R.id.main_container, fragment2, "2").hide(fragment2).commit();
fm.beginTransaction().add(R.id.main_container,fragment1, "1").commit();
 @Override
    public void onClick(View v) {
        Fragment another = fragment1;
         if(active==fragment1){
          another = fragment2;
         }
            fm.beginTransaction().hide(active).show(another).commit();
            active = another;
}

참고 : https://medium.com/@oluwabukunmi.aluko/bottom-navigation-view-with-fragments-a074bfd08711


0

너무 늦었을지 모르지만 미래에 누군가를 도울 수 있습니다.
이 답변에 대한 수정입니다 mangu23 답변
난 단지 피하기 반복하는 루프를 추가하고 쉽게 상용구 코드없이 많은 조각을 추가 할 수 있습니다.

먼저 표시해야 할 조각 목록이 필요합니다.

public class MainActivity extends AppCompatActivity{
    //...
    List<Fragment> fragmentList = new ArrayList<>();
}

그런 다음 조각으로 채워야합니다.

@Override
protected void onCreate(Bundle savedInstanceState) {
    //...
    HomeFragment homeFragment = new HomeFragment();
    MessagesFragment messagesFragment = new MessagesFragment();
    UserFragment userFragment = new UserFragment();
    FavoriteFragment favoriteFragment = new FavoriteFragment();
    MapFragment mapFragment = new MapFragment();

    fragmentList.add(homeFragment);
    fragmentList.add(messagesFragment);
    fragmentList.add(userFragment);
    fragmentList.add(favoriteFragment);
    fragmentList.add(mapFragment);
}

그리고 목록에서 어떤 조각이 선택되었는지 알 수있는 방법이 필요하므로 getFragmentIndex기능이 필요 합니다.

private int getFragmentIndex(Fragment fragment) {
    int index = -1;
    for (int i = 0; i < fragmentList.size(); i++) {
        if (fragment.hashCode() == fragmentList.get(i).hashCode()){
            return i;
        }
    }
    return index;
}

마지막으로 displayFragment방법은 다음과 같습니다.

private void displayFragment(Fragment fragment) {
        int index = getFragmentIndex(fragment);
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        if (fragment.isAdded()) { // if the fragment is already in container
            transaction.show(fragment);
        } else { // fragment needs to be added to frame container
            transaction.add(R.id.placeholder, fragment);
        }
        // hiding the other fragments
        for (int i = 0; i < fragmentList.size(); i++) {
            if (fragmentList.get(i).isAdded() && i != index) {
                transaction.hide(fragmentList.get(i));
            }
        }
        transaction.commit();
    }

이런 식으로 우리는 displayFragment(homeFragment)예를 들어 부를 수 있습니다 .
그러면 HomeFragment목록의 다른 조각 이 자동으로 표시 되고 숨겨집니다.
이 솔루션을 사용하면 이전 버전 fragmentListif명령문 을 반복하지 않고도에 더 많은 조각을 추가 할 수 있습니다 displayFragment.
누군가 이것이 유용하다고 생각하기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.