Làm mới Fragment khi tải lại


110

Trong một ứng dụng android, tôi đang tải dữ liệu từ Db vào TableViewbên trong a Fragment. Nhưng khi tôi tải lại Fragmentnó sẽ hiển thị dữ liệu trước đó. Tôi có thể tạo lại Fragmentdữ liệu hiện tại thay vì dữ liệu trước đó không?


xin vui lòng cho chúng tôi xem một số mã. Bạn tải dữ liệu của mình ở đâu, bạn bắt đầu phân đoạn ở đâu, nơi bạn lưu trữ các giá trị của mình?
AS

Điều này sẽ giải quyết vấn đề của bạn được mô tả porly: stackoverflow.com/questions/6503189/...
Benjamin W.

vui lòng cung cấp thêm thông tin-đoạn mã
nikvs

Cố gắng sử dụng Vuốt để làm mới ứng dụng của bạn xem stackoverflow.com/questions/41469040/fragment-refresh/…
Imtiaz Mamun

Câu trả lời:


207

Tôi nghĩ bạn muốn làm mới nội dung phân đoạn khi cập nhật db

Nếu vậy, hãy tách mảnh ra và gắn lại

// 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 là tên bạn đã đặt cho phân đoạn của mình khi tạo ra nó

Mã này dành cho thư viện hỗ trợ.

Nếu bạn không hỗ trợ các thiết bị cũ hơn, chỉ cần sử dụng getFragmentManager thay vì getSupportFragmentManager

[BIÊN TẬP]

Phương thức này yêu cầu Fragment phải có một thẻ.
Trong trường hợp bạn không có nó, thì phương pháp của @ Hammer là những gì bạn cần.


3
Điều này gây ra lỗi sau - java.lang.RuntimeException: Không cung cấp kết quả ResultInfo {ai = null, request = 2, result = 3, data = null} cho hoạt động {xont.virtusel.v4.controller / xont.virtusel.v4.controller .sale.InvocieBrandActivity}: java.lang.IllegalStateException: không thể thực hiện hành động này sau khi onSaveInstanceState
Samantha Withanage

1
@Elizabeth đảm bảo Fragment của bạn có một thẻ thiết lập đúng
Phantômaxx

1
@Rotwang Cảm ơn trả lời của bạn tôi chỉ mất một phím tắt chứ không phải là làm mã dài nhưng điều đó đã giúp mở đường :)
Si8

1
Giải pháp này không hoạt động nữa trong phiên bản mới của support-v4-library (25.1.0). Giải thích ở đây: stackoverflow.com/questions/41270858/...
Brahim Bouaboud

1
Cảnh báo: thủ thuật này chỉ hoạt động trên Oreo nếu bạn đang sử dụng Phân đoạn hỗ trợ!
racs

146

Điều này sẽ làm mới phân đoạn hiện tại:

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

1
đặt mã này ở đâu? hoạt động bên trong hay bản thân phân mảnh?
Narendra Singh

2
Bạn đặt nó vào bên trong phân mảnh cần được làm mới.
Mbengue Assane

1
@SagarChavada, bạn đã đặt mã ở đâu? Bạn phải đặt nó vào sự kiện một lần như khi dữ liệu được làm mới.
Mbengue Assane

5
Đệ quy, đệ quy, các cuộc gọi vô tận
shah zulkarnain

2
Sử dụng điều này tạo ra trong onResume trong phân đoạn tạo ra một vòng lặp, làm thế nào để tránh nó?
Soul

32

Trong trường hợp bạn không có thẻ phân mảnh, mã sau hoạt động tốt đối với tôi.

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 phân đoạn sẽ là gì, tôi chưa khai báo id phân đoạn ở đâu. Khai báo như thế nào và ở đâu?
Narendra Singh

Dường như không thể sử dụng getActivity()trong Hoạt động của tôi. Tôi có nên sử dụng Activity.this...không?
Si8

@NarendraJi chỉ có id FrameLayout là nơi bạn đặt các mảnh của mình vào vùng chứa.
Lokesh

Vui lòng loại bỏ dấu ngoặc nhọn. Nó gây ra rất nhiều rắc rối cho tôi.
Abhishek

9

bạn có thể làm mới phân đoạn của mình khi nó hiển thị với người dùng, chỉ cần thêm mã này vào Phân đoạn của bạn, mã này sẽ làm mới phân đoạn của bạn khi nó được hiển thị.

@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");
    }
}

quá chậm, phải mất 3 giây cho đến khi tải lại
Omar Boshra

Điều này dường như được làm việc tốt với bộ chuyển đổi ViewPager
DragonFire

2
setUserVnableHint không được dùng nữa
Sai Aditya

Làm việc cho tôi, cảm ơn vì giải pháp.
hetsgandhi

7

Để làm mới đoạn được chấp nhận, câu trả lời sẽ không hoạt động trên phiên bản Nougat trở lên. Để làm cho nó hoạt động trên tất cả các hệ điều hành, bạn có thể làm như sau.

    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

Bạn không thể tải lại phân đoạn khi nó được đính kèm với Hoạt động, nơi bạn nhận được Fragment Already Addedngoại lệ "".

Vì vậy, đoạn đầu tiên phải được tách ra khỏi hoạt động của nó và sau đó được gắn vào. Tất cả có thể được thực hiện bằng cách sử dụng api thông thạo trong một dòng:

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

Cập nhật: Điều này là để kết hợp các thay đổi được thực hiện cho API 26 trở lên:

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

Để biết thêm mô tả về bản cập nhật, vui lòng xem https://stackoverflow.com/a/51327440/4514796


2
Vui lòng cung cấp câu trả lời của bạn với mô tả rõ ràng. Đừng viết mã, hãy đưa ra lời giải thích về mã mà bạn đã chia sẻ để những người khác cũng có thể hiểu và nó sẽ hữu ích. Tôi yêu cầu bạn đọc Phần câu hỏi thường gặp để sử dụng Stack Overflow một cách hiệu quả.
Sankar Ganesh

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

điều này sẽ chỉ hoạt động nếu bạn sử dụng FragmentManagerđể khởi tạo phân mảnh. Nếu bạn có nó dưới <fragment ... />dạng XML, nó sẽ không gọi onCreateViewlại. Lãng phí 30 phút của tôi để tìm ra điều này.


1

Đây là những gì tôi đã làm và nó hoạt động với tôi, tôi sử dụng firebase và khi người dùng đăng nhập, tôi muốn làm mới Fragment hiện tại, trước tiên, bạn sẽ cần yêu cầu ngữ cảnh từ hoạt động vì phân mảnh không có cách nào để lấy ngữ cảnh trừ khi bạn đặt nó từ Activity hoặc ngữ cảnh ở đây là mã tôi đã sử dụng và làm việc bằng ngôn ngữ kotlin, tôi nghĩ bạn có thể sử dụng mã tương tự trong lớp java

   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

Sử dụng a ContentProvidervà tải dữ liệu của bạn bằng 'CursorLoader'. Với kiến ​​trúc này, dữ liệu của bạn sẽ được tự động tải lại khi thay đổi cơ sở dữ liệu. Sử dụng các khuôn khổ của bên thứ ba cho của bạn ContentProvider- bạn không thực sự muốn tự mình triển khai ...


0

Tôi đã gặp vấn đề tương tự nhưng không có vấn đề nào ở trên phù hợp với tôi. hoặc đã xảy ra sự cố backstack (sau khi tải khi người dùng nhấn lại, nó sẽ quay lại cùng một phân đoạn) hoặc nó không gọionCreaetView

cuối cùng tôi đã làm điều này:

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();
}

điểm tốt là bạn cũng không cần thẻ hoặc id của phân đoạn. nếu bạn muốn tải lại


0

Sử dụng phương pháp onResume ... cả trên hoạt động phân mảnh và hoạt động giữ phân mảnh.


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

GeneralInfo đó là lớp Fragment của tôi GeneralInfo.java

Tôi đặt nó như một phương thức trong lớp phân mảnh:

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

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

Viết viewpagerAdapter.notifyDataSetChanged (); trong onResume () trong MainActivity. Chúc may mắn :)


-2

Cách dễ nhất

tạo một phương thức tĩnh công khai chứa viewpager.setAdapter

làm cho bộ điều hợp và khung xem tĩnh

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

gọi ở bất kỳ đâu, bất kỳ hoạt động nào, bất kỳ phân đoạn nào.

MainActivity.refreshFragments();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.