다시로드 할 때 조각 새로 고침


110

안드로이드 응용 프로그램에서 나는로 DB에서 데이터를로드하고있어 TableView, 안쪽 Fragment. 하지만 다시로드 Fragment하면 이전 데이터가 표시됩니다. Fragment이전 데이터 대신 현재 데이터로에 다시 채울 수 있습니까 ?


코드를 보여주세요. 데이터를 어디에서로드하고, 프래그먼트를 어디에서 시작하고, 값을 어디에 저장합니까?
AS

: 이것은 당신의 porly 기술 문제를 해결해야 stackoverflow.com/questions/6503189/...
벤자민 W.

더 많은 정보 코드 스 니펫을 제공해주세요
nikvs

이 참조 앱에 스 와이프 - 새로 고침을 사용하려고 stackoverflow.com/questions/41469040/fragment-refresh/...
Imtiaz Mamun

답변:


207

DB 업데이트시 조각 내용새로 고치고 싶다고 생각합니다.

그렇다면 조각을 분리하고 다시 연결하십시오.

// Reload current fragment
Fragment frg = null;
frg = getSupportFragmentManager().findFragmentByTag("Your_Fragment_TAG");
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.detach(frg);
ft.attach(frg);
ft.commit();

Your_Fragment_TAG는 프래그먼트를 만들 때 지정한 이름입니다.

이 코드는 지원 라이브러리 용입니다.

구형 장치를 지원하지 않는 경우 getSupportFragmentManager 대신 getFragmentManager 를 사용 하십시오.

[편집하다]

이 방법을 사용하려면 Fragment에 태그가 있어야합니다.
가지고 있지 않은 경우 @Hammer의 방법이 필요합니다.


3
이로 인해 다음 오류가 발생합니다. java.lang.RuntimeException : 결과 ResultInfo {who = null, request = 2, result = 3, data = null}을 활동 {xont.virtusel.v4.controller / xont.virtusel.v4.controller에 전달하지 못했습니다. .sale.InvocieBrandActivity} : java.lang.IllegalStateException는 : onSaveInstanceState 후이 작업을 수행 할 수 없습니다
사만다 Withanage

1
@Elizabeth 메이크업은 반드시 당신의 조각이 제대로 설정 태그가
Phantômaxx

1
@Rotwang 답장을 보내 주셔서 감사합니다. 긴 코드 대신 바로 가기를 사용했지만 길을
닦는

1
이 솔루션은 support-v4-library (25.1.0)의 새 버전에서 더 이상 작동하지 않습니다. 여기에 설명 : stackoverflow.com/questions/41270858/…
Brahim Bouaboud dec

1
경고 :이 트릭은 Support Fragments를 사용하는 경우에만 Oreo에서 작동합니다!
racs

146

현재 조각을 새로 고칩니다.

FragmentTransaction ft = getFragmentManager().beginTransaction();
if (Build.VERSION.SDK_INT >= 26) {
   ft.setReorderingAllowed(false);
}
ft.detach(this).attach(this).commit();

1
이 코드를 어디에 넣을까요? 내부 활동 또는 조각 자체?
Narendra Singh

2
새로 고쳐야하는 조각 안에 넣습니다.
Mbengue Assane 2015 년

1
@SagarChavada 코드를 어디에 넣었습니까? 데이터를 새로 고칠 때와 같은 일회성 이벤트에 넣어야합니다.
Mbengue Assane

5
재귀, 재귀, 끝없는 전화
제작 : Zulkarnain 샤

2
이것을 사용하면 조각의 onResume 내에서 루프가 생성됩니다. 어떻게 피할 수 있습니까?
Soul

32

조각 태그가없는 경우 다음 코드가 잘 작동합니다.

Fragment currentFragment = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);
if (currentFragment instanceof "NAME OF YOUR FRAGMENT CLASS") {
 FragmentTransaction fragTransaction =   (getActivity()).getFragmentManager().beginTransaction();
 fragTransaction.detach(currentFragment);
 fragTransaction.attach(currentFragment);
 fragTransaction.commit();}
}

1
프래그먼트 ID는 무엇입니까? 나는 어디에도 프래그먼트 ID를 선언하지 않았습니다. 어떻게 그리고 어디에서 선언합니까?
Narendra Singh

getActivity()내 활동에서 사용할 수없는 것 같습니다 . 사용해야합니까 Activity.this...?
Si8

@NarendraJi 그것은 FrameLayout ID로 조각을 컨테이너에 넣는 곳입니다.
Lokesh

여분의 중괄호를 제거하십시오. 그것은 나에게 많은 문제를 일으켰습니다.
Abhishek

9

사용자에게 표시 될 때 조각을 새로 고칠 수 있습니다.이 코드를 조각에 추가하면 조각이 표시 될 때 새로 고쳐집니다.

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        // Refresh your fragment here          
  getFragmentManager().beginTransaction().detach(this).attach(this).commit();
        Log.i("IsRefresh", "Yes");
    }
}

너무 느려서 다시로드 될 때까지 3 초가 걸립니다
Omar Boshra

이것은 viewpager 어댑터와 잘 작동하는 것 같습니다
DragonFire

2
setUserVisibleHint는 더 이상 사용되지 않습니다
Sai Aditya

저를 위해 일했습니다. 솔루션에 감사드립니다.
hetsgandhi

7

조각을 새로 고치려면 Nougat 이상 버전에서 응답이 작동하지 않습니다. 모든 OS에서 작동하도록하려면 다음을 수행 할 수 있습니다.

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        fragmentManager.beginTransaction().detach(this).commitNow();
        fragmentManager.beginTransaction().attach(this).commitNow();
    } else {
        fragmentManager.beginTransaction().detach(this).attach(this).commit();
    }

5

조각이 활동에 연결되어있는 동안에는 조각을 다시로드 할 수 없습니다. 여기서 " Fragment Already Added"예외가 발생합니다.

따라서 조각은 먼저 활동에서 분리 된 다음 연결되어야합니다. 한 줄에 유창한 API를 사용하여 모든 작업을 수행 할 수 있습니다.

getFragmentManager().beginTransaction().detach(this).attach(this).commit();

업데이트 : API 26 이상에 대한 변경 사항을 통합합니다.

FragmentTransaction transaction = mActivity.getFragmentManager()
                        .beginTransaction();
                if (Build.VERSION.SDK_INT >= 26) {
                    transaction.setReorderingAllowed(false);
                }
                transaction.detach(this).attach
                        (this).commit();

업데이트에 대한 자세한 설명은 https://stackoverflow.com/a/51327440/4514796을 참조 하십시오.


2
명확한 설명과 함께 답변을 제공하십시오. 코드를 작성하지 말고 공유 한 코드에 대한 설명을 제공하여 다른 사람들도 이해할 수 있고 도움이 될 것입니다. Stack Overflow를 효과적으로 사용하려면 FAQ 섹션을 읽어 보시기 바랍니다.
Sankar Ganesh

3
   MyFragment fragment = (MyFragment) getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
        getSupportFragmentManager().beginTransaction().detach(fragment).attach(fragment).commit();

이것은 FragmentManager조각을 초기화하는 데 사용 하는 경우에만 작동합니다 . u는 그것을이있는 경우 <fragment ... />XML에, 그것은 전화를하지 않습니다 onCreateView다시. 이것을 알아내는 데 30 분을 낭비했습니다.


1

여기에서 내가 한 일이 저에게 효과적이었습니다 .Firebase를 사용하고 사용자가 로그인 할 때 현재 Fragment를 먼저 새로 고치고 싶었습니다. 여기에서 활동 또는 컨텍스트에서 설정하지 않는 한 조각은 컨텍스트를 얻을 수있는 방법이 없기 때문에 활동에서 컨텍스트를 복구해야합니다. 내가 사용하고 kotlin 언어로 일한 코드는 자바 클래스에서 똑같이 사용할 수 있다고 생각합니다.

   override fun setUserVisibleHint(isVisibleToUser: Boolean) {
    super.setUserVisibleHint(isVisibleToUser)
    val context = requireActivity()
    if (auth.currentUser != null) {
        if (isVisibleToUser){
            context.supportFragmentManager.beginTransaction().detach(this).attach(this).commit()
        }
    }

}

0

a를 ContentProvider사용하고 'CursorLoader'를 사용하여 데이터를로드합니다. 이 아키텍처를 사용하면 데이터베이스 변경시 데이터가 자동으로 다시로드됩니다. 타사 프레임 워크 를 사용 ContentProvider하여 직접 구현하고 싶지는 않습니다.


0

나는 똑같은 문제가 있었지만 위의 어느 것도 나를 위해 일하지 않았습니다. 백 스택 문제가 있었거나 (로드 후 사용자가 뒤로 눌렀을 때 동일한 조각으로 다시 이동합니다) 또는onCreaetView

마침내 나는 이것을했다 :

public void transactFragment(Fragment fragment, boolean reload) {
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
    if (reload) {
        getSupportFragmentManager().popBackStack();
    }
    transaction.replace(R.id.main_activity_frame_layout, fragment);
    transaction.addToBackStack(null);
    transaction.commit();
}

좋은 점은 조각의 태그 또는 ID가 필요하지 않다는 것입니다. 재장 전하고 싶다면


0

조각 활동과 조각을 보유하는 활동 모두에서 onResume 메소드를 사용하십시오.


0
getActivity().getSupportFragmentManager().beginTransaction().replace(GeneralInfo.this.getId(), new GeneralInfo()).commit();

GeneralInfo 그것은 내 Fragment 클래스입니다. GeneralInfo.java

프래그먼트 클래스에 메서드로 넣었습니다.

public void Reload(){
    getActivity().getSupportFragmentManager().beginTransaction().replace(LogActivity.this.getId(), new LogActivity()).commit();
}

0

예를 들어 TabLayout의 경우 : OnTabSelectedListener를 구현하기 만하면됩니다. 페이지를 다시로드하려면 구현 SwipeRefreshLayout.OnRefreshListener ie를 사용할 수 있습니다.public class YourFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {

onRefresh () 메소드는 인터페이스에서 @Override가됩니다.

@Override
public void onRefresh() {
 loadData();
}

레이아웃은 다음과 같습니다.

<com.google.android.material.tabs.TabLayout
    android:id="@+id/tablayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimaryLighter"
    app:tabGravity="fill"
    app:tabIndicatorColor="@color/white"
    app:tabMode="fixed"
    app:tabSelectedTextColor="@color/colorTextPrimary"
    app:tabTextColor="@color/colorTextDisable" />

활동의 코드

TabLayout tabLayout = (TabLayout) findViewById (R.id.tablayout); tabLayout.setupWithViewPager (viewPager);

    tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            if (tab.getPosition() == 0) {
                yourFragment1.onRefresh();
            } else if (tab.getPosition() == 1) {
                yourFragment2.onRefresh();
            }
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

-2
protected void onResume() {
        super.onResume();
        viewPagerAdapter.notifyDataSetChanged();
    }

viewpagerAdapter.notifyDataSetChanged ();를 작성하십시오. MainActivity의 onResume ()에 있습니다. 행운을 빕니다 :)


-2

가장 쉬운 방법

viewpager.setAdapter를 포함하는 공개 정적 메소드를 만듭니다.

어댑터 및 뷰 페이저를 정적으로 만들기

public static void refreshFragments(){
        viewPager.setAdapter(adapter);
    }

어디서나, 모든 활동, 모든 조각을 호출하십시오.

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