Cách thực hành tốt nhất để khởi tạo một đoạn Android mới


706

Tôi đã thấy hai thực tiễn chung để khởi tạo một Đoạn mới trong một ứng dụng:

Fragment newFragment = new MyFragment();

Fragment newFragment = MyFragment.newInstance();

Tùy chọn thứ hai sử dụng một phương thức tĩnh newInstance()thường chứa phương thức sau.

public static Fragment newInstance() 
{
    MyFragment myFragment = new MyFragment();
    return myFragment;
}

Lúc đầu, tôi nghĩ lợi ích chính là việc tôi có thể quá tải phương thức newInstance () để tạo sự linh hoạt khi tạo các phiên bản mới của Fragment - nhưng tôi cũng có thể làm điều này bằng cách tạo một hàm tạo quá tải cho Fragment.

Tôi đã bỏ lỡ một cái gì đó?

Lợi ích của một phương pháp này so với phương pháp khác là gì? Hay đó chỉ là thực hành tốt?


Khi có các tham số, không có lựa chọn nào, và điều này được trả lời rộng rãi ở đây. Tuy nhiên, câu hỏi vẫn còn cho việc xây dựng không có đối số của đoạn.
rds

1
Sau khi tìm hiểu về mô hình nhà máy và cách một lớp gọi không khởi tạo một đối tượng sẽ giúp tách chúng ra, tôi nghĩ rằng đây sẽ là một điểm mạnh cho phương thức newInstance (). Tôi có sai về điều này? Tôi chưa thấy lập luận cụ thể này được coi là một lợi ích.
Ứng dụng di động

Câu trả lời:


1136

Nếu Android quyết định tạo lại Mảnh vỡ của bạn sau này, thì nó sẽ gọi hàm tạo không có đối số của mảnh đó. Vì vậy, quá tải các nhà xây dựng không phải là một giải pháp.

Như đã nói, cách để chuyển nội dung vào Fragment của bạn để chúng có sẵn sau khi Fragment được Android tạo lại là chuyển một gói cho setArgumentsphương thức.

Vì vậy, ví dụ, nếu chúng ta muốn truyền một số nguyên cho đoạn, chúng ta sẽ sử dụng một cái gì đó như:

public static MyFragment newInstance(int someInt) {
    MyFragment myFragment = new MyFragment();

    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    myFragment.setArguments(args);

    return myFragment;
}

Và sau đó trong Fragment, onCreate()bạn có thể truy cập số nguyên đó bằng cách sử dụng:

getArguments().getInt("someInt", 0);

Gói này sẽ khả dụng ngay cả khi Fragment được tạo lại bằng cách nào đó bởi Android.

Cũng lưu ý: setArgumentschỉ có thể được gọi trước khi Đoạn được gắn vào Hoạt động.

Cách tiếp cận này cũng được ghi lại trong tài liệu tham khảo dành cho nhà phát triển Android: https://developer.android.com/reference/android/app/Fragment.html


7
@Vlasto không may các phương thức tĩnh không thể bị ghi đè.
AJD

8
@yydl Tôi nghĩ rằng tôi đang thiếu một cái gì đó ở đây, dù sao bạn cũng không thể sử dụng một hàm tạo, một cái tạo Bundle và gọi setArgument () vì nó sẽ chỉ được gọi bởi mã của bạn (chứ không phải khi Android tạo lại miếng)?
Mike Tunnicliffe

9
@mgibson Bạn phải sử dụng một gói nếu bạn muốn dữ liệu có sẵn khi đoạn được tạo lại sau đó.
yydl

114
Việc bị buộc phải tạo ra một hàm tạo không có đối số cho các đoạn có khả năng là một vấn đề lớn nhất trong tất cả các chương trình, ở bất cứ đâu. Nó buộc một sự thay đổi mô hình hoàn chỉnh trong việc tạo và khởi tạo đối tượng. Nếu bạn chưa quen với Android và đã vấp phải chủ đề này, vui lòng đọc lại câu trả lời nhiều lần.
rmirabelle

9
Tôi sẽ tranh luận với khẳng định đó. Đầu tiên, an toàn loại là mối quan tâm về ngôn ngữ, không phải là mối quan tâm khuôn khổ. Thứ hai, IMO, khuôn khổ đang bước vào lĩnh vực "những điều API của bạn không bao giờ phải làm". Nếu tôi muốn chuyển thư viện quốc hội vào nhà xây dựng phân đoạn của mình, thì tôi nên được phép. Hợp đồng xây dựng "không tranh luận" về cơ bản sẽ giết chết việc sử dụng phép tiêm phụ thuộc vào các mảnh - chính là yuck.
rmirabelle

95

Lợi ích duy nhất trong việc sử dụng cái newInstance()mà tôi thấy là như sau:

  1. Bạn sẽ có một nơi duy nhất mà tất cả các đối số được sử dụng bởi đoạn có thể được gói lại và bạn không phải viết mã bên dưới mỗi khi bạn khởi tạo một đoạn.

    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    args.putString("someString", someString);
    // Put any other arguments
    myFragment.setArguments(args);
  2. Đó là một cách tốt để nói với các lớp khác những đối số mà nó mong đợi sẽ hoạt động trung thực (mặc dù bạn sẽ có thể xử lý các trường hợp nếu không có đối số nào được gói trong ví dụ phân đoạn).

Vì vậy, tôi nghĩ rằng việc sử dụng một tĩnh newInstance()để khởi tạo một đoạn là một thực hành tốt.


4
1) Làm thế nào khác với việc đưa logic vào một hàm tạo? Cả hai đều là nơi duy nhất mà bạn bao gồm logic này. 2) Các tham số trên một nhà máy tĩnh khác với các tham số trên một hàm tạo như thế nào? Cả hai đều nói những gì lập luận được mong đợi. Quan điểm của tôi là một mô hình khác, chắc chắn, nhưng không có lợi ích rõ ràng cho việc này bằng cách sử dụng các nhà xây dựng.
RJ Cuthbertson

2
Bạn không thể sử dụng các hàm tạo tùy chỉnh cho đoạn. Framework sử dụng hàm tạo không có đối số để khôi phục các đoạn.
500865

5
Vâng, tôi đồng ý với bạn ở đó. Tôi đang nói về mặt khái niệm không có lợi ích gì trong việc sử dụng mẫu nhà máy tĩnh thay vì sử dụng các hàm tạo quá tải và ngược lại. Cả hai điểm của bạn đều hợp lệ trong cả hai mẫu; không có lợi ích của việc sử dụng cái này hơn cái kia Android buộc bạn phải sử dụng mô hình nhà máy tĩnh - nhưng không có lợi ích gì khi sử dụng cái này hay cái kia.
RJ Cuthbertson

pastebin.com/EYJzES0j
RJ Cuthbertson

@RJCuthbertson Một lợi ích có thể có là khả năng tạo và trả về các lớp con của lớp của phương thức nhà máy tĩnh tức là trả về một lớp con thích hợp cho tình huống.
khẩn cấp

62

Cũng có một cách khác:

Fragment.instantiate(context, MyFragment.class.getName(), myBundle)

Nếu tôi không nhầm, điều này chỉ có thể khi bạn sử dụng thư viện Hỗ trợ của Android.
Timo

2
Đã thử điều này với thư viện hỗ trợ, nhưng trong onCreateView (trong đoạn của tôi), gói được truyền là null, vì vậy tôi đã sử dụng tùy chọn setArgument / getArgument và nó đã hoạt động (cho bất kỳ ai đọc nó).
Jrop

1
Thật thú vị, tôi chưa thấy cách tiếp cận này trước đây. Liệu nó có bất kỳ lợi thế nào so với các cách tiếp cận khác để khởi tạo một mảnh vỡ không?
IgorGanapolsky

22
Từ các tài liệu dành cho nhà phát triển ,instantiate() Creates a new instance of a Fragment with the given class name. This is the same as calling its empty constructor.
Brian Bowman

2
Mặc dù họ đề cập giống như gọi nhà xây dựng trống. "args.setClassLoader (f.getClass (). getClassLoader ());" được gọi bên dưới cho các đối số Bundle
Gökhan Barış Aker

49

Trong khi @yydl đưa ra một lý do thuyết phục về lý do tại sao newInstancephương pháp này tốt hơn:

Nếu Android quyết định tạo lại Mảnh vỡ của bạn sau này, thì nó sẽ gọi hàm tạo không có đối số của mảnh đó. Vì vậy, quá tải các nhà xây dựng không phải là một giải pháp.

vẫn hoàn toàn có thể sử dụng một hàm tạo . Để xem lý do tại sao, trước tiên chúng ta cần xem tại sao cách giải quyết trên được Android sử dụng.

Trước khi một đoạn có thể được sử dụng, một ví dụ là cần thiết. Các cuộc gọi Android YourFragment()(hàm tạo không có đối số ) để xây dựng một thể hiện của đoạn. Ở đây, mọi hàm tạo quá tải mà bạn viết sẽ bị bỏ qua, vì Android không thể biết nên sử dụng cái nào.

Trong vòng đời của một Hoạt động, đoạn được tạo như trên và bị phá hủy nhiều lần bởi Android. Điều này có nghĩa là nếu bạn đặt dữ liệu vào chính đối tượng mảnh, nó sẽ bị mất một khi mảnh bị phá hủy.

Để giải quyết, android yêu cầu bạn lưu trữ dữ liệu bằng cách sử dụng Bundle(gọi setArguments()), sau đó có thể được truy cập từ đó YourFragment. Các đối số bundleđược bảo vệ bởi Android và do đó được đảm bảo là bền bỉ .

Một cách để đặt gói này là sử dụng newInstancephương thức tĩnh :

public static YourFragment newInstance (int data) {
    YourFragment yf = new YourFragment()
    /* See this code gets executed immediately on your object construction */
    Bundle args = new Bundle();
    args.putInt("data", data);
    yf.setArguments(args);
    return yf;
}

Tuy nhiên, một nhà xây dựng:

public YourFragment(int data) {
    Bundle args = new Bundle();
    args.putInt("data", data);
    setArguments(args);
}

có thể làm chính xác điều tương tự như newInstancephương pháp.

Đương nhiên, điều này sẽ thất bại và là một trong những lý do Android muốn bạn sử dụng newInstancephương pháp này:

public YourFragment(int data) {
    this.data = data; // Don't do this
}

Như giải thích thêm, đây là Lớp phân mảnh của Android:

/**
 * Supply the construction arguments for this fragment.  This can only
 * be called before the fragment has been attached to its activity; that
 * is, you should call it immediately after constructing the fragment.  The
 * arguments supplied here will be retained across fragment destroy and
 * creation.
 */
public void setArguments(Bundle args) {
    if (mIndex >= 0) {
        throw new IllegalStateException("Fragment already active");
    }
    mArguments = args;
}

Lưu ý rằng Android hỏi rằng các đối số được thiết lập chỉ ở xây dựng, và đảm bảo rằng chúng sẽ được giữ lại.

EDIT : Như được chỉ ra trong các nhận xét của @JHH, nếu bạn đang cung cấp một hàm tạo tùy chỉnh yêu cầu một số đối số, thì Java sẽ không cung cấp đoạn của bạn với hàm tạo mặc định không có đối số . Vì vậy, điều này sẽ yêu cầu bạn xác định một hàm tạo không có arg , đây là mã mà bạn có thể tránh với newInstancephương thức xuất xưởng.

EDIT : Android không cho phép sử dụng hàm tạo quá tải cho các đoạn nữa. Bạn phải sử dụng newInstancephương pháp.


Khi nào thì người ta sẽ biện minh cho việc sử dụng android: configChanges = "direction | keyboardHidden | screenSize"?
Luke Allison

1
Android Studio hiện đưa ra lỗi cho tất cả các nhà xây dựng không mặc định theo từng mảnh, do đó, điều này không còn hoạt động nữa.
Sheharyar

6
Chúa ơi, tôi tự hỏi có bao nhiêu nhà phát triển droid đã từng viết mã bên ngoài droid. Điều này là điên rồ mà chúng tôi không thể sử dụng phương pháp bạn mô tả. KHÔNG có lý lẽ thuyết phục từ bất kỳ bình luận nào về lý do tại sao chúng ta PHẢI sử dụng phương pháp nhà máy tĩnh. Điều đáng lo ngại hơn nữa là họ sẽ phát sinh lỗi khi biên dịch. Đây chắc chắn là câu trả lời tốt nhất được cung cấp và cho thấy rằng không có lợi cho sfm.
MPavlak

3
Vâng, có một lý do tinh tế. Bạn có thể tự do tạo ra hàm tạo của riêng mình bằng các đối số, nhưng vẫn cần phải có một hàm tạo không có đối số . Vì các lớp luôn có hàm tạo không có đối số ngầm trừ khi hàm tạo có đối số được xác định rõ ràng , điều này có nghĩa là bạn sẽ phải xác định rõ cả hàm tạo arg hàm tạo không đối số của mình, hoặc hệ thống sẽ không thể gọi bất kỳ nhà xây dựng không có đối số. Tôi tin rằng đây là lý do tại sao khuyến nghị là thay vào đó sử dụng phương pháp tĩnh nhà máy - nó chỉ đơn giản là giảm nguy cơ quên định nghĩa một hàm tạo không có đối số.
JHH

@JHH sẽ thất bại vào thời gian biên dịch, do đó không phải là rủi ro lớn. Tuy nhiên, vấn đề ở đây là quá tải của nhà xây dựng, một mô hình lập trình chính, đang bị Android từ chối.
ps95

20

Tôi không đồng ý với câu trả lời của yydi :

Nếu Android quyết định tạo lại Mảnh vỡ của bạn sau này, thì nó sẽ gọi hàm tạo không có đối số của mảnh đó. Vì vậy, quá tải các nhà xây dựng không phải là một giải pháp.

Tôi nghĩ đó là một giải pháp và một giải pháp tốt, đây chính xác là lý do nó được phát triển bởi ngôn ngữ cốt lõi Java.

Đúng là hệ thống Android có thể phá hủy và tạo lại của bạn Fragment. Vì vậy, bạn có thể làm điều này:

public MyFragment() {
//  An empty constructor for Android System to use, otherwise exception may occur.
}

public MyFragment(int someInt) {
    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    setArguments(args);
}

Nó sẽ cho phép bạn kéo someInttừ getArguments()sau này, ngay cả khi Fragmenthệ thống được tạo lại. Đây là giải pháp thanh lịch hơnstatic xây dựng.

Đối với ý kiến ​​của tôi, các nhà staticxây dựng là vô dụng và không nên được sử dụng. Ngoài ra, họ sẽ giới hạn bạn nếu trong tương lai bạn muốn mở rộng điều này Fragmentvà thêm nhiều chức năng hơn cho nhà xây dựng. Vớistatic constructor, bạn không thể làm điều này.

Cập nhật:

Android đã thêm kiểm tra gắn cờ tất cả các nhà xây dựng không mặc định có lỗi.
Tôi khuyên bạn nên vô hiệu hóa nó, vì những lý do đã đề cập ở trên.


4
Một lợi ích khác của việc có một phương thức tĩnh, mà tôi không đề cập ở trên là bạn không thể vô tình đặt các thuộc tính từ nó.
yydl

4
Ngoài ra, liên quan đến quan điểm của bạn về "mở rộng đoạn này", phương pháp này thực sự sẽ rất tệ nếu bạn mở rộng lớp. Gọi siêu sẽ khiến cuộc gọi setArgument () chỉ có hiệu lực đối với trẻ hoặc cha mẹ, nhưng không phải cả hai!
yydl

2
@yydle bạn có thể tránh tình huống này bằng cách gọi get argument để khởi tạo Bundle con. Cách Java luôn tốt hơn.
Ilya Gazman

9
Đúng, nhưng đó là một lý do khác để khuyến khích mọi người sử dụng mẫu mà Google đã đề xuất. Tất nhiên, tất cả chúng tôi đồng ý rằng giải pháp của bạn là khả thi về mặt kỹ thuật 100%. Cũng giống như vậy, có nhiều cách để làm nhiều thứ. Tuy nhiên, câu hỏi đặt ra là liệu nó có tốt nhất không. Và tôi cảm thấy mạnh mẽ rằng việc sử dụng hàm tạo không thể hiện đúng bản chất của cách thức hoạt động của nó.
yydl

3
Tôi đồng ý với @yydl rằng tạo tĩnh là tốt hơn. Một lợi ích khác là tiêm phụ thuộc vào các phụ thuộc mới trong tương lai - hàm tạo không phù hợp với điều đó và có thể sẽ gây ra nhiều thay đổi mã (hoặc thêm nhiều hàm tạo).
Boon

19

Một số mã kotlin :

companion object {
    fun newInstance(first: String, second: String) : SampleFragment {
        return SampleFragment().apply {
            arguments = Bundle().apply {
                putString("firstString", first)
                putString("secondString", second)
            }
        }
    }
}

Và bạn có thể nhận được các đối số với điều này:

val first: String by lazy { arguments?.getString("firstString") ?: "default"}
val second: String by lazy { arguments?.getString("secondString") ?: "default"}

3

Thực hành tốt nhất để ví dụ các đoạn với các đối số trong Android là có phương thức nhà máy tĩnh trong đoạn của bạn.

public static MyFragment newInstance(String name, int age) {
    Bundle bundle = new Bundle();
    bundle.putString("name", name);
    bundle.putInt("age", age);

    MyFragment fragment = new MyFragment();
    fragment.setArguments(bundle);

    return fragment;
}

Bạn nên tránh đặt các trường của bạn với ví dụ của một đoạn. Bởi vì bất cứ khi nào hệ thống Android tạo lại đoạn của bạn, nếu cảm thấy rằng hệ thống cần nhiều bộ nhớ hơn, nó sẽ tạo lại đoạn của bạn bằng cách sử dụng hàm tạo không có đối số.

Bạn có thể tìm thêm thông tin về thực tiễn tốt nhất để khởi tạo các đoạn bằng các đối số ở đây.


2

Vì các câu hỏi về thực tiễn tốt nhất, tôi sẽ nói thêm, rất thường xuyên sử dụng phương pháp lai để tạo phân đoạn khi làm việc với một số dịch vụ web REST

Chúng tôi không thể vượt qua các đối tượng phức tạp, ví dụ như một số mô hình Người dùng, trong trường hợp hiển thị phân đoạn người dùng

Nhưng những gì chúng ta có thể làm, là kiểm tra onCreate người dùng đó! = Null và nếu không - sau đó đưa anh ta từ lớp dữ liệu, nếu không - sử dụng hiện có.

Bằng cách này, chúng tôi có được cả khả năng tái tạo bởi userId trong trường hợp giải trí phân mảnh bằng Android và sự nhanh nhẹn cho hành động của người dùng, cũng như khả năng tạo ra các mảnh vỡ bằng cách giữ đối tượng hoặc chỉ id của nó

Một cái gì đó thích điều này:

public class UserFragment extends Fragment {
    public final static String USER_ID="user_id";
    private User user;
    private long userId;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        userId = getArguments().getLong(USER_ID);
        if(user==null){
            //
            // Recreating here user from user id(i.e requesting from your data model,
            // which could be services, direct request to rest, or data layer sitting
            // on application model
            //
             user = bringUser();
        }
    }

    public static UserFragment newInstance(User user, long user_id){
        UserFragment userFragment = new UserFragment();
        Bundle args = new Bundle();
        args.putLong(USER_ID,user_id);
        if(user!=null){
            userFragment.user=user;
        }
        userFragment.setArguments(args);
        return userFragment;

    }

    public static UserFragment newInstance(long user_id){
        return newInstance(null,user_id);
    }

    public static UserFragment newInstance(User user){
        return newInstance(user,user.id);
    }
}

3
Bạn nói: "Chúng tôi không thể vượt qua các đối tượng phức tạp, ví dụ như một số mô hình Người dùng" - Điều đó không đúng, chúng tôi có thể. Như thế này: User user = /*...*/ đưa người dùng vào gói: Bundle bundle = new Bundle(); bundle.putParcelable("some_user", user); và lấy người dùng từ các đối số: User user = getArguments().getParcelable("some_user"); Đối tượng phải được thực hiện Giao diện Parcelable. liên kết
Adam Varhegyi

3
Vâng, vâng, nhưng khi lớp học phức tạp và chứa các tham chiếu đến các đối tượng khác ... Cá nhân tôi thích giữ cho nó đơn giản, hoặc tôi có đối tượng, hoặc tôi không và sau đó cần phải có được nó
Tigra

1

sử dụng mã này 100% khắc phục sự cố của bạn

nhập mã này vào FirstFragment

public static yourNameParentFragment newInstance() {

    Bundle args = new Bundle();
    args.putBoolean("yourKey",yourValue);
    YourFragment fragment = new YourFragment();
    fragment.setArguments(args);
    return fragment;
}

mẫu này gửi dữ liệu boolean

và trong SecendFragment

yourNameParentFragment name =yourNameParentFragment.newInstance();
   Bundle bundle;
   bundle=sellDiamondFragments2.getArguments();
  boolean a= bundle.getBoolean("yourKey");

phải giá trị trong đoạn đầu tiên là tĩnh

mã hạnh phúc


0

Cách tốt nhất để khởi tạo đoạn đó là sử dụng phương thức Fragment.instantiate mặc định hoặc tạo phương thức nhà máy để khởi tạo đoạn đó
Chú ý: luôn tạo một hàm tạo trống trong đoạn khác trong khi khôi phục bộ nhớ đoạn sẽ ném ngoại lệ thời gian chạy.


0

Tôi đang ở đây gần đây. Nhưng đôi khi tôi chỉ biết rằng có thể giúp bạn một chút.

Nếu bạn đang sử dụng Java, không có gì nhiều để thay đổi. Nhưng đối với các nhà phát triển kotlin, đây là một số đoạn sau tôi nghĩ rằng có thể làm cho bạn một tầng hầm để chạy trên:

  • Đoạn cha mẹ:
inline fun <reified T : SampleFragment> newInstance(text: String): T {
    return T::class.java.newInstance().apply {
        arguments = Bundle().also { it.putString("key_text_arg", text) }
    }
}
  • Cuộc gọi bình thường
val f: SampleFragment = SampleFragment.newInstance("ABC")
// or val f = SampleFragment.newInstance<SampleFragment>("ABC")
  • Bạn có thể mở rộng thao tác init cha trong lớp phân đoạn con bằng cách:
fun newInstance(): ChildSampleFragment {
    val child = UserProfileFragment.newInstance<ChildSampleFragment>("XYZ")
    // Do anything with the current initialized args bundle here
    // with child.arguments = ....
    return child
}

Chúc mừng mã hóa.


-2

setArguments()là vô dụng Nó chỉ mang lại một mớ hỗn độn.

public class MyFragment extends Fragment {

    public String mTitle;
    public String mInitialTitle;

    public static MyFragment newInstance(String param1) {
        MyFragment f = new MyFragment();
        f.mInitialTitle = param1;
        f.mTitle = param1;
        return f;
    }

    @Override
    public void onSaveInstanceState(Bundle state) {
        state.putString("mInitialTitle", mInitialTitle);
        state.putString("mTitle", mTitle);
        super.onSaveInstanceState(state);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
        if (state != null) {
            mInitialTitle = state.getString("mInitialTitle");
            mTitle = state.getString("mTitle");
        } 
        ...
    }
}

Ngoại trừ bạn vừa bị buộc phải ghi đè thêm một phương thức và tạo một trường có thể được tách ra theo onViewCreatedphạm vi. Tôi đoán đó là sự tiện lợi, nhiều cách để làm điều tương tự. Ngoài ra, đây là cách dễ dàng để kiểm tra các bản cập nhật được thực hiện bởi người dùng (so sánh các gói getArgumentsvà gói từ onSaveInstanceState)
Overclover

@Asagen, tôi thích bình luận của bạn về việc so sánh giá trị ban đầu và người dùng. Tôi đã chỉnh sửa mã và xem xét rằng nó vẫn còn thống nhất và rõ ràng getArguments. Điều gì về onViewCreatedphạm vi ... Chúng ta có thể khôi phục gói trạng thái ở đó. Nhưng tôi chỉ thích làm cho onCreateViewnhẹ và nhanh và thực hiện tất cả các khởi tạo nặng trong một onActivityCreatedFragment.getActivity() đôi khi muốn quay lại nullvà vì những onAttach()thay đổi trong phiên bản mới của API 23.
Ngôi sao Vadim

Tất cả những gì bạn làm ở đây là di chuyển setget Argumentsvào saveInstanceState. Về cơ bản, bạn đang làm điều tương tự được thực hiện "dưới mui xe"
OneCricketeer

1
@ cricket_007, hoặc ngược lại . Sử dụng saveInstanceStatelà "dưới mui xe". Và việc sử dụng Argumentslà sao chép chức năng giúp bạn kiểm tra lại: Argumentsgiá trị đầu tiên và sau đó là saveInstanceStategiá trị. Bởi vì bạn phải sử dụng saveInstanceStatebất kỳ cách nào. Thế còn Arguments... chúng không cần thiết.
Ngôi sao

Đối số là tương đương với bổ sung ý định cho các mảnh. Chúng không vô dụng, chúng chứa các tham số ban đầu khác với trạng thái hiện tại.
BladeCoder

-12

Tôi tin rằng tôi có một giải pháp simpeler nhiều cho việc này.

public class MyFragment extends Fragment{

   private String mTitle;
   private List<MyObject> mObjects;

   public static MyFragment newInstance(String title, List<MyObject> objects)
   MyFragment myFrag = new MyFragment();
   myFrag.mTitle = title;
   myFrag.mObjects = objects;
   return myFrag;
   }

12
mObjects sẽ bị xóa nếu MyFragment tình cờ được tạo lại (người dùng đi đến màn hình chính của thiết bị và sau đó mở ứng dụng đã tắt ở MyFragment). Bạn có thể giữ lại các mObject bằng cách gửi MyFragment một gói làm đối số.
ynnadkrap

1
Ngoài ra, làm thế nào là phương thức tĩnh truy cập các biến thành viên không tĩnh?
OrhanC1

2
@ynnadkrap Bạn đã đúng, sử dụng một gói là cách để đi đến đây.
Stefan Bogaard

2
@ OrhanC1 Theo mã ví dụ này, phương thức tĩnh không truy cập vào các biến thành viên. Ví dụ của MyFragment là truy cập vào các thành viên của nó. Không có lỗi ở đây. Tuy nhiên, tôi không đề xuất câu trả lời này cho bất kỳ ai vì khi đoạn của bạn bị xóa khỏi bộ nhớ để mở ra một khoảng trống bằng hệ điều hành android thì sau khi khởi động lại hoạt động và đoạn này sẽ được tạo với hàm tạo trống mặc định mà không gán biến ant.
Gunhan

@Gunhan Bạn nói đúng! Nó không thể. Xin lỗi vì sự nhầm lẫn :)
OrhanC1
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.