Chuyển một đối tượng từ một Activity đến một Fragment


76

Tôi có một Activitymà sử dụng a Fragment. Tôi chỉ muốn chuyển một đối tượng từ cái này Activitysang cái Fragment.

Làm thế nào tôi có thể làm điều đó? Tất cả các hướng dẫn mà tôi đã xem cho đến nay, nơi lấy dữ liệu từ các tài nguyên.

BIÊN TẬP :

Hãy nói chính xác hơn một chút:

Hoạt động của tôi có một ListViewphần bên trái. Khi bạn nhấp vào nó, ý tưởng là tải một Fragmentphần bên phải.

Khi tôi nhập điều này Activity, một Đối tượng Categoryđược đưa ra thông qua Intent. Đối tượng này chứa một danh sách các đối tượng khác Questions(chứa một danh sách chuỗi). Các Questionsđối tượng này được hiển thị trên ListView. Khi tôi bấm vào một mục từ ListView, tôi muốn hiển thị Danh sách Stringthành Fragment(thành ListView).

Để làm điều đó, tôi gọi setContentView()từ của tôi Activityvới một bố cục. Trong cách bố trí này được định nghĩa Fragmentvới lớp chính xác để gọi. Khi tôi gọi cái này setContentView(), cái onCreateView()của tôi Fragmentđược gọi nhưng lúc này, getArguments()giá trị trả về là null.

Làm thế nào tôi có thể quản lý để có nó đầy trước cuộc gọi của onCreateView()? (cho tôi biết nếu tôi không đủ rõ ràng)

Cảm ơn

Câu trả lời:


132

Tạo một phương thức tĩnh trong Fragmentvà sau đó sử dụng nó getArguments().

Thí dụ:

public class CommentsFragment extends Fragment {
  private static final String DESCRIBABLE_KEY = "describable_key";
  private Describable mDescribable;

  public static CommentsFragment newInstance(Describable describable) {
    CommentsFragment fragment = new CommentsFragment();
    Bundle bundle = new Bundle();
    bundle.putSerializable(DESCRIBABLE_KEY, describable);
    fragment.setArguments(bundle);

    return fragment;
  }

  @Override
  public View onCreateView(LayoutInflater inflater,
      ViewGroup container, Bundle savedInstanceState) {

    mDescribable = (Describable) getArguments().getSerializable(
        DESCRIBABLE_KEY);

    // The rest of your code
}

Sau đó, bạn có thể gọi nó bằng cách Activitylàm như sau:

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment fragment = CommentsFragment.newInstance(mDescribable);
ft.replace(R.id.comments_fragment, fragment);
ft.commit();

8
Tôi muốn chuyển một số đối tượng không thể nối tiếp?
Bagusflyer

1
putParcelable là tốt nhất thực hành cách
panchicore

9
Tôi rất muốn biết tại sao không chỉ đơn giản là đặt fragment.mDescribable = describable;trong newInstance? Nó hoạt động, nhưng có điều gì đó mà tôi đang thiếu ở đây?
Rahul Thakur

2
@RahulThakur Bạn đang thiếu điểm của mtiền tố ở đây. Vì cộng đồng Java khuyến khích mạnh mẽ khái niệm đóng gói dữ liệu, nên cần lưu ý rằng các trường riêng tư không cần phải truy cập bên ngoài. Lý do tại sao, nó được truyền dưới dạng tham số từ phương thức singleton là vì trường đó là bắt buộc trong ngữ cảnh đó và do đó giảm nguy cơ tiềm ẩn mà bạn quên gán giá trị của nó.
mr5

16
Câu trả lời tốt nhất, nhưng bạn quên nói rằng Objectcần phải thực hiện Serializableđể làm việc (trong trường hợp, đối tượng Describable).
Gabriel Stafoca

12

Bạn nên tạo một phương thức bên trong phân đoạn của mình để chấp nhận loại đối tượng mà bạn muốn truyền vào nó. Trong trường hợp này, tôi đặt tên nó là "setObject" (sáng tạo hả? :)) Phương thức đó sau đó có thể thực hiện bất kỳ hành động nào bạn cần với đối tượng đó.

MyFragment fragment;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

        if (getSupportFragmentManager().findFragmentById(android.R.id.content) == null) {
            fragment = new MyFragment();
            getSupportFragmentManager().beginTransaction().add(android.R.id.content, detailsFragment)
                    .commit();
        } else {
           fragment = (MyFragment) getSupportFragmentManager().findFragmentById(
                    android.R.id.content);
        }


        fragment.setObject(yourObject); //create a method like this in your class "MyFragment"
}

Lưu ý rằng tôi đang sử dụng thư viện hỗ trợ và các lệnh gọi tới getSupportFragmentManager () có thể chỉ là getFragmentManager () cho bạn tùy thuộc vào những gì bạn đang làm việc với


2
Chỉ cần cẩn thận khi sử dụng phương pháp này trên một phân đoạn có thể tồn tại lâu hơn chế độ xem lưu trữ của bạn (keepInstance true).
Jannie Theunissen

7
Điều này sẽ không hoạt động. Khi ứng dụng của bạn chết ở chế độ nền và người dùng đưa nó trở lại nền trước, setObjectsẽ không nhất thiết được gọi.
Martin Konecny

5
@MartinKonecny ​​trong trường hợp đó phương thức onCreate sẽ được gọi lại (vì hoạt động sẽ được tạo lại) và do đó setObject cũng sẽ được gọi. Nếu nó không phải là trường hợp, xin vui lòng giải thích nhận xét của bạn. Cảm ơn bạn.
fklappan

Điều này không hoạt động trong trường hợp xem các phân đoạn máy nhắn tin. vì đối tượng không được giữ lại khi chuyển đổi.
rafa

12

Trong lớp hoạt động của bạn:

public class BasicActivity extends Activity {

private ComplexObject co;

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

    co=new ComplexObject();
    getIntent().putExtra("complexObject", co);

    FragmentManager fragmentManager = getFragmentManager();
    Fragment1 f1 = new Fragment1();
    fragmentManager.beginTransaction()
            .replace(R.id.frameLayout, f1).commit();

}

Lưu ý: Đối tượng của bạn nên triển khai giao diện Serializable

Sau đó, trong phân đoạn của bạn:

public class Fragment1 extends Fragment {

ComplexObject co;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    Intent i = getActivity().getIntent();

    co = (ComplexObject) i.getSerializableExtra("complexObject");

    View view = inflater.inflate(R.layout.test_page, container, false);
    TextView textView = (TextView) view.findViewById(R.id.DENEME);
    textView.setText(co.getName());

    return view;
}
}

4

Việc truyền đối số theo gói bị hạn chế đối với một số kiểu dữ liệu. Nhưng bạn có thể chuyển bất kỳ dữ liệu nào sang phân đoạn của mình theo cách này:

Trong phân đoạn của bạn, hãy tạo một phương thức công khai như thế này

public void passData(Context context, List<LexItem> list, int pos) {
    mContext = context;
    mLexItemList = list;
    mIndex = pos;
}

và trong hoạt động của bạn, hãy gọi passData () với tất cả các kiểu dữ liệu cần thiết của bạn sau khi khởi tạo phân đoạn

        WebViewFragment myFragment = new WebViewFragment();
        myFragment.passData(getApplicationContext(), mLexItemList, index);
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.add(R.id.my_fragment_container, myFragment);
        ft.addToBackStack(null);
        ft.commit();

Lưu ý: Đoạn của tôi mở rộng "android.support.v4.app.Fragment", do đó tôi phải sử dụng "getSupportFragmentManager ()". Tất nhiên, nguyên tắc này cũng sẽ hoạt động với một lớp phân mảnh mở rộng "Fragment", nhưng sau đó bạn phải sử dụng "getFragmentManager ()".


4

Lấy tham chiếu từ ví dụ sau.

1. Trong phân mảnh : Tạo một biến tham chiếu cho lớp có đối tượng mà bạn muốn trong phân mảnh. Chỉ cần tạo một phương thức setter cho biến tham chiếu và gọi setter trước khi thay thế phân đoạn khỏi hoạt động.

 MyEmployee myEmp;
 public void setEmployee(MyEmployee myEmp)
 {
     this.myEmp = myEmp;
 }

2. Trong hoạt động :

   //we need to pass object myEmp to fragment myFragment

    MyEmployee myEmp = new MyEmployee();

    MyFragment myFragment = new MyFragment();

    myFragment.setEmployee(myEmp);

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.replace(R.id.main_layout, myFragment);
    ft.commit();

1

Để chuyển một đối tượng vào một phân mảnh, hãy làm như sau:

Đầu tiên hãy lưu trữ các đối tượng trong Bundle, đừng quên đặt các triển khai có thể tuần tự hóa trong lớp.

            CategoryRowFragment fragment = new CategoryRowFragment();

            // pass arguments to fragment
            Bundle bundle = new Bundle();

            // event list we want to populate
            bundle.putSerializable("eventsList", eventsList);

            // the description of the row
            bundle.putSerializable("categoryRow", categoryRow);

            fragment.setArguments(bundle);

Sau đó, truy xuất các gói trong Fragment

       // events that will be populated in this row
        mEventsList = (ArrayList<Event>)getArguments().getSerializable("eventsList");

        // description of events to be populated in this row
        mCategoryRow = (CategoryRow)getArguments().getSerializable("categoryRow");


0

Nếu dữ liệu sẽ tồn tại trong suốt vòng đời ứng dụng và được chia sẻ giữa nhiều phân đoạn hoặc hoạt động, a Model lớp có thể được xem xét, lớp này có ít chi phí tuần tự hóa hơn.

Kiểm tra ví dụ thiết kế này


0

Điều này đã làm việc cho tôi:

Đang hoạt động:

User user;
public User getUser(){ return this.user;}

Trong phương thức onCreateView của Fragment:

User user = ((MainActivity)getActivity()).getUser(); 

Thay thế MainActivitybằng Tên hoạt động của bạn.

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.