Gửi dữ liệu từ hoạt động đến đoạn trong Android


316

Tôi có hai lớp. Đầu tiên là hoạt động, thứ hai là một đoạn mà tôi có một số EditText. Trong hoạt động tôi có một lớp con với tác vụ async và trong phương thức doInBackgroundtôi nhận được một số kết quả, mà tôi lưu vào biến. Làm thế nào tôi có thể gửi biến này từ lớp con "hoạt động của tôi" đến đoạn này?

Câu trả lời:


662

Từ Hoạt động bạn gửi dữ liệu với mục đích là:

Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);

và trong phương thức Fragment onCreateView:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    String strtext = getArguments().getString("edttext");    
    return inflater.inflate(R.layout.fragment, container, false);
}

15
bạn có thể vượt qua một đối tượng cho các mảnh?
yeahman

63
Hmm, tôi nhận được NullPulumException khi gọigetArguments().getString(key)
Nima G

9
NullPulumException "Chuỗi strtext setArgument (). GetString (" edttext ");"
Jorgesys

4
Trong khi đọc nội dung gói trong đoạn, trước tiên luôn nhận gói vào đối tượng Bundle bằng phương thức getArgument và kiểm tra xem nó có null không. Mặt khác, phương thức getString sẽ được áp dụng trên null và do đó NPE khi không có gói nào được thông qua. Điều này sẽ tránh các ngoại lệ con trỏ null khi gói không được thông qua.
balachandarkm

3
@Aznix. Không nên tạo constructor cho đoạn.
Azam

108

Ngoài ra, bạn có thể truy cập dữ liệu hoạt động từ đoạn:

Hoạt động:

public class MyActivity extends Activity {

    private String myString = "hello";

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

    public String getMyData() {
        return myString;
    }
}

Miếng:

public class MyFragment extends Fragment {

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

        MyActivity activity = (MyActivity) getActivity();
        String myDataFromActivity = activity.getMyData();
        return view;
    }
}

78
Giải pháp này tích hợp khớp nối chặt chẽ giữa hoạt động của bạn và Fragment, tốt hơn là sử dụng Bundlelớp để truyền thông tin. Ngoài ra, bạn có thể làm cho getMyData()phương thức đó được kế thừa và triển khai từ một giao diện và Fragmentkiểm tra xem getActivity có trả về instanceofGiao diện không onAttach().
Rudi Kershaw

1
Giải pháp này tốt nhất cho tôi. Ngoài ra, nếu myString được công khai, bạn chưa khai báo phương thức getMyData ()
Burak ztürk

1
Câu trả lời được chấp nhận hiện tại trả về ngoại lệ con trỏ null. Đây phải là câu trả lời được chấp nhận
Richmond

9
Đây không phải là câu trả lời được chấp nhận. Các khớp nối chặt chẽ là dễ dàng tránh được. Đây thường là một ý tưởng tồi và làm cho mảnh vỡ trở nên vô dụng, cũng có thể không có mảnh vỡ nếu bạn chỉ sử dụng nó gắn liền với một hoạt động. Các mảnh không thể được sử dụng lại trong các hoạt động khác.
Martin Marconcini

51

Tôi đã tìm thấy rất nhiều câu trả lời ở đây @ stackoverflow.com nhưng chắc chắn đây là câu trả lời đúng của:

"Gửi dữ liệu từ hoạt động đến đoạn trong Android".

Hoạt động:

        Bundle bundle = new Bundle();
        String myMessage = "Stackoverflow is cool!";
        bundle.putString("message", myMessage );
        FragmentClass fragInfo = new FragmentClass();
        fragInfo.setArguments(bundle);
        transaction.replace(R.id.fragment_single, fragInfo);
        transaction.commit();

Miếng:

Đọc giá trị trong đoạn

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Bundle bundle = this.getArguments();
        String myValue = bundle.getString("message");
        ...
        ...
        ...
        }

hoặc chỉ

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        String myValue = this.getArguments().getString("message");
        ...
        ...
        ...
        }

Tôi đoán đó không phải là cách tiếp cận tốt nhất để cập nhật onQueryTextSubmit-search-results trong ListView, được lồng trong một Fragment (nếu ai đó gõ nhanh, anh ta sẽ gửi các đối số hai lần một giây)?
Martin Pfeffer

1
Điều gì về Object bắt nguồn từ chuỗi hoặc int?
Dario

2
@Jorgesys Còn giải pháp này thì sao? developer.android.com/training/basics/fragments/ từ
yozhik

23

Câu trả lời này có thể là quá muộn. nhưng nó sẽ hữu ích cho độc giả trong tương lai.

Tôi có một số tiêu chí. Tôi đã mã hóa để chọn các tập tin từ ý định. và tập tin được chọn sẽ được chuyển đến đoạn cụ thể để xử lý thêm. tôi có nhiều đoạn có chức năng chọn File. tại thời điểm đó, mỗi lần kiểm tra điều kiện và nhận được đoạn và vượt qua giá trị là khá kinh tởm. Vì vậy, tôi đã quyết định chuyển giá trị bằng giao diện.

Bước 1: Tạo giao diện trên Hoạt động chính.

   public interface SelectedBundle {
    void onBundleSelect(Bundle bundle);
   }

Bước 2: Tạo tham chiếu được chọnBundle trên cùng một hoạt động

   SelectedBundle selectedBundle;

Bước 3: tạo Phương thức trong cùng Hoạt động

   public void setOnBundleSelected(SelectedBundle selectedBundle) {
       this.selectedBundle = selectedBundle;
   }

Bước 4: Cần khởi tạo tham chiếu ChọnBundle, tất cả các đoạn cần chức năng quay phim. Bạn đặt mã này vào onCreateView(..)phương thức phân đoạn của mình

    ((MainActivity)getActivity()).setOnBundleSelected(new MainActivity.SelectedBundle() {
          @Override
         public void onBundleSelect(Bundle bundle) {
            updateList(bundle);
        }
     });

Bước 5: Trường hợp của tôi, tôi cần chuyển hình ảnh Uri từ HomeActivity sang đoạn. Vì vậy, tôi đã sử dụng chức năng này trên phương thức onActivityResult.

onActivityResult từ MainActivity, chuyển các giá trị cho các đoạn bằng giao diện.

Lưu ý: Trường hợp của bạn có thể khác. bạn có thể gọi nó từ bất kỳ nơi nào từ HomeActivity của bạn.

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent  data) {
       selectedBundle.onBundleSelect(bundle);
  }

Đó là tất cả. Thực hiện mọi phân đoạn bạn cần trên FragmentClass. Bạn tuyệt lắm. bạn đã làm. Ôi ...


15

Ý tưởng cơ bản của việc sử dụng Fragment (F) là tạo ra các thành phần UI tự duy trì có thể tái sử dụng trong các ứng dụng Android. Các Đoạn này được chứa trong các hoạt động và có cách phổ biến (tốt nhất) để tạo các đường dẫn giao tiếp từ A -> F và FA, Đó là điều bắt buộc phải Giao tiếp giữa FF thông qua Hoạt động vì sau đó chỉ các Đoạn bị tách rời và tự duy trì.

Vì vậy, việc truyền dữ liệu từ A -> F sẽ giống như được giải thích bởi ρяσѕρєя K. Ngoài câu trả lời đó, Sau khi tạo các Đoạn trong một Hoạt động, chúng ta cũng có thể truyền dữ liệu cho các phương thức gọi các đoạn trong Đoạn.

Ví dụ:

    ArticleFragment articleFrag = (ArticleFragment)
                    getSupportFragmentManager().findFragmentById(R.id.article_fragment);
    articleFrag.updateArticleView(position);


15

Cách tiếp cận tốt nhất và thuận tiện là gọi ví dụ phân đoạn và gửi dữ liệu tại thời điểm đó. mỗi đoạn theo mặc định có phương thức cá thể

Ví dụ: nếu tên phân đoạn của bạn là MyFragment

vì vậy bạn sẽ gọi đoạn của bạn từ hoạt động như thế này:

getSupportFragmentManager().beginTransaction().add(R.id.container, MyFragment.newInstance("data1","data2"),"MyFragment").commit();

* R.id.container là id của FrameLayout của tôi

vì vậy trong MyFragment.newInstance ("data1", "data2") bạn có thể gửi dữ liệu tới đoạn và trong đoạn của bạn, bạn nhận được dữ liệu này trong MyFragment newInstance (Chuỗi param1, String param2)

public static MyFragment newInstance(String param1, String param2) {
        MyFragment fragment = new MyFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

và sau đó trong phương pháp phân đoạn onCreate, bạn sẽ nhận được dữ liệu:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

vì vậy bây giờ mParam1 có data1mParam2 có data2

bây giờ bạn có thể sử dụng mParam1mParam2 này trong đoạn của bạn.


R.id.container ở đây là gì? ý bạn là R.id.container_cản đây là một giá trị int.
shaurya uppal

@s * R.id.container là id của FrameLayout của tôi
Pre_hacker

Cho đến nay, lời giải thích tốt nhất mà tôi từng tìm thấy để truyền dữ liệu về thêm / thay thế đoạn bằng Trình quản lý mảnh. Hoạt động như đá quý! Cảm ơn!
sam

đã sử dụng R.id.nav_host_fragment thay vì R.id.container
Bahaa Hany

10

Tôi muốn thêm vào cho người mới bắt đầu rằng sự khác biệt giữa 2 câu trả lời được đánh giá cao nhất ở đây được đưa ra bằng cách sử dụng khác nhau của một đoạn.

Nếu bạn sử dụng đoạn trong lớp java nơi bạn có dữ liệu bạn muốn truyền, bạn có thể áp dụng câu trả lời đầu tiên để truyền dữ liệu:

Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);

Tuy nhiên, nếu bạn sử dụng ví dụ mã mặc định do Android Studio cung cấp cho các đoạn được gắn thẻ, mã này sẽ không hoạt động.

Nó sẽ không hoạt động ngay cả khi bạn thay thế PlaceholderFragment mặc định bằng FragmentClass của bạn và ngay cả khi bạn sửa FragmentPagerAd CHƯƠNG sang tình huống mới, thêm một công tắc cho getItem () và một công tắc khác cho getPageTitle () (như được hiển thị ở đây )

Cảnh báo: clip được đề cập ở trên có lỗi mã, tôi sẽ giải thích sau đây, nhưng rất hữu ích để xem cách bạn đi từ mã mặc định sang mã có thể chỉnh sửa cho các đoạn được gắn thẻ)! Phần còn lại của câu trả lời của tôi có ý nghĩa hơn nhiều nếu bạn xem xét các lớp java và tệp xml từ clip đó (đại diện cho lần đầu tiên sử dụng các đoạn được gắn thẻ theo kịch bản mới bắt đầu).

Lý do chính khiến câu trả lời được đánh giá cao nhất từ ​​trang này sẽ không hoạt động là trong mã mặc định đó cho các đoạn được gắn thẻ, các đoạn được sử dụng trong một lớp java khác: FragmentPagerAd CHƯƠNG!

Vì vậy, để gửi dữ liệu, bạn nên tạo một gói trong MotherActivity và chuyển nó trong FragmentPagerAd CHƯƠNG, sử dụng câu trả lời số 2.

Chỉ có điều đó là sai một lần nữa. ( Có lẽ bạn có thể làm điều đó như thế, nhưng đó chỉ là một sự phức tạp không thực sự cần thiết ).

Cách chính xác / dễ dàng hơn để làm điều đó, tôi nghĩ, là truyền dữ liệu trực tiếp đến đoạn được đề cập, sử dụng câu trả lời số 2. Có, sẽ có sự kết hợp chặt chẽ giữa Hoạt động và Mảnh vỡ, NHƯNG, đối với các mảnh được gắn thẻ, đó là loại dự kiến. Tôi thậm chí sẽ khuyên bạn nên tạo các đoạn được gắn thẻ bên trong lớp java MotherActivity (dưới dạng các lớp con, vì chúng sẽ không bao giờ được sử dụng bên ngoài MotherActivity) - thật dễ dàng, chỉ cần thêm vào bên trong lớp java MotherActivity như nhiều Đoạn như bạn cần như thế này:

 public static class Tab1 extends Fragment {

    public Tab1() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.your_layout_name_for_fragment_1, container, false);
        return rootView;
    }
}.

Vì vậy, để truyền dữ liệu từ MotherActivity sang một Fragment như vậy, bạn sẽ cần tạo các Chuỗi / Gói riêng tư bên trên onCreate của hoạt động Mẹ của bạn - mà bạn có thể điền dữ liệu bạn muốn truyền vào các đoạn đó và chuyển chúng qua phương thức được tạo sau onCreate (ở đây được gọi là getMyData ()).

public class MotherActivity extends Activity {

    private String out;
    private Bundle results;

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

       // for example get a value from the previous activity
        Intent intent = getIntent();
        out = intent.getExtras().getString("Key");

    }

    public Bundle getMyData() {
        Bundle hm = new Bundle();
        hm.putString("val1",out);
        return hm;
    }
}

Và sau đó trong lớp phân đoạn, bạn sử dụng getMyData:

public static class Tab1 extends Fragment {
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        public Tab1() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.your_layout_name_for_fragment_1, container, false);
            TextView output = (TextView)rootView.findViewById(R.id.your_id_for_a_text_view_within_the_layout);

            MotherActivity activity = (MotherActivity)getActivity();

            Bundle results = activity.getMyData();
            String value1 = results.getString("val1");

            output.setText(value1);
            return rootView;
        }
    }

Nếu bạn có các truy vấn cơ sở dữ liệu, tôi khuyên bạn nên thực hiện chúng trong MotherActivity (và chuyển kết quả của chúng dưới dạng Chuỗi / Số nguyên được gắn vào các khóa bên trong một gói như được hiển thị ở trên), vì bên trong các đoạn được gắn thẻ, cú pháp của bạn sẽ trở nên phức tạp hơn (điều này trở nên phức tạp hơn () chẳng hạn, và getIntent trở thành getActivity (). getIntent), nhưng bạn cũng có tùy chọn để làm như bạn muốn.

Lời khuyên của tôi cho người mới bắt đầu là tập trung vào các bước nhỏ. Trước tiên, hãy lấy ý định của bạn để mở một hoạt động được gắn thẻ rất đơn giản, mà không truyền bất kỳ dữ liệu nào. Nó có hoạt động không? Nó có mở các tab bạn mong đợi không? Nếu không, tại sao?

Bắt đầu từ đó, và bằng cách áp dụng các giải pháp như những giải pháp được trình bày trong clip này , hãy xem những gì còn thiếu. Đối với clip cụ thể đó, tệp mainactivity.xml không bao giờ được hiển thị. Điều đó chắc chắn sẽ làm bạn bối rối. Nhưng nếu bạn chú ý, bạn sẽ thấy ví dụ như bối cảnh (công cụ: bối cảnh) bị sai trong các tệp mảnh xml. Mỗi phân đoạn XML cần trỏ đến lớp phân đoạn chính xác (hoặc lớp con sử dụng dấu phân cách $).

Bạn cũng sẽ thấy rằng trong lớp java hoạt động chính, bạn cần thêm tabLayout.setupWithViewPager (mViewPager) - ngay sau dòng TabLayout tabLayout = (TabLayout) findViewById (R.id.tabs); không có dòng này, chế độ xem của bạn thực sự không được liên kết với các tệp XML của các đoạn, nhưng nó chỉ hiển thị tệp xml của hoạt động chính.

Ngoài dòng trong lớp java hoạt động chính, trong tệp XML hoạt động chính, bạn cần thay đổi các tab để phù hợp với tình huống của bạn (ví dụ: thêm hoặc xóa TabItems). Nếu bạn không có các tab trong XML hoạt động chính, thì có thể bạn đã không chọn loại hoạt động chính xác khi bạn tạo nó ở vị trí đầu tiên (hoạt động mới - hoạt động được gắn thẻ).

Xin lưu ý rằng trong 3 đoạn cuối tôi nói về video! Vì vậy, khi tôi nói XML hoạt động chính, đó là XML hoạt động chính trong video, trong tình huống của bạn là tệp XML MotherActivity.


8

Nếu bạn chuyển một tham chiếu đến đoạn (lớp con cụ thể) vào tác vụ không đồng bộ, thì bạn có thể truy cập trực tiếp vào đoạn đó.

Một số cách chuyển tham chiếu đoạn vào tác vụ async:

  • Nếu tác vụ không đồng bộ của bạn là một lớp hoàn chỉnh ( class FooTask extends AsyncTask), thì hãy chuyển đoạn của bạn vào hàm tạo.
  • Nếu tác vụ async của bạn là một lớp bên trong, chỉ cần khai báo một biến Fragment cuối cùng trong phạm vi thì tác vụ async được xác định hoặc là một trường của lớp bên ngoài. Bạn sẽ có thể truy cập từ lớp bên trong.

Câu trả lời của bạn có vẻ khá hợp pháp với tôi, Bạn có thể mở rộng thêm một chút bằng cách cung cấp một số mã ví dụ để làm không?
Leon Armstrong

6

Đôi khi bạn có thể nhận được ý định trong hoạt động của mình và bạn cần chuyển thông tin đến đoạn làm việc của mình.
Đưa ra câu trả lời là ổn nếu bạn cần bắt đầu phân đoạn nhưng nếu nó vẫn hoạt động, setArguments()không hữu ích lắm.
Một vấn đề khác xảy ra nếu thông tin được truyền sẽ gây ra tương tác với giao diện người dùng của bạn. Trong trường hợp đó, bạn không thể gọi một cái gì đó giống như myfragment.passData()bởi vì Android sẽ nhanh chóng nói rằng chỉ có luồng tạo ra khung nhìn mới có thể tương tác.

Vì vậy, đề xuất của tôi là sử dụng một người nhận. Bằng cách đó, bạn có thể gửi dữ liệu từ bất kỳ đâu, kể cả hoạt động, nhưng công việc sẽ được thực hiện trong bối cảnh của đoạn.

Trong đoạn của bạn onCreate():

protected DataReceiver dataReceiver;
public static final String REC_DATA = "REC_DATA";

@Override
public void onCreate(Bundle savedInstanceState) {


    data Receiver = new DataReceiver();
    intentFilter = new IntentFilter(REC_DATA);

    getActivity().registerReceiver(dataReceiver, intentFilter);
}

private class DataReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        int data= intent.getIntExtra("data", -1);

        // Do anything including interact with your UI
    }
}

Trong bạn hoạt động:

// somewhere
Intent retIntent = new Intent(RE_DATA);
retIntent.putExtra("data", myData);
sendBroadcast(retIntent);

5

Bài viết rất cũ, tôi vẫn dám thêm một lời giải thích có thể hữu ích cho tôi.

Về mặt kỹ thuật, bạn có thể trực tiếp thiết lập các thành viên thuộc bất kỳ loại nào trong một đoạn từ hoạt động.
Vậy tại sao lại là Bundle?
Lý do rất đơn giản - Gói cung cấp cách xử lý thống nhất:
- tạo / mở đoạn
- cấu hình lại (xoay màn hình) - chỉ cần thêm gói ban đầu / cập nhật vào outState trong onSaveInstanceState ()
- khôi phục ứng dụng sau khi được thu thập trong nền ( như với cấu hình lại).

Bạn có thể (nếu bạn thích thử nghiệm) tạo ra một cách giải quyết trong các tình huống đơn giản nhưng cách tiếp cận Bundle chỉ không thấy sự khác biệt giữa một mảnh và một nghìn trên backstack - nó vẫn đơn giản và dễ hiểu.
Đó là lý do tại sao câu trả lời của @Elenasys là giải pháp thanh lịch và phổ quát nhất.
Và đó là lý do tại sao câu trả lời được đưa ra bởi @Martinnhững cạm bẫy


4

cách tiếp cận tốt hơn để gửi dữ liệu từ lớp hoạt động đến đoạn được truyền qua các phương thức setter. Giống

FragmentClass fragmentClass = new FragmentClass();
fragmentClass.setMyList(mylist);
fragmentClass.setMyString(myString);
fragmentClass.setMyMap(myMap);

và có được những dữ liệu này từ lớp một cách dễ dàng.


Cách truyền dữ liệu từ đoạn này sang đoạn khác như stackoverflow.com/questions/32953477/pass-data-to-fragment
Hoo

Điều này không thuận tiện lắm khi bạn cũng đi ngang qua người khác, trước đó đã đặt Extra
Gerard

Nếu bạn cần dữ liệu đó được đặt thành một số trường trong đoạn của bạn và nó chưa hiển thị (được khởi tạo), bạn sẽ nhận được NPE.
yozhik


Tôi đã ngừng làm việc với Android 3 năm trước, những thứ này có thể không được dùng trong những ngày này.
ssi-anik

4

Từ Activitybạn gửi dữ liệu với Bundle như:

Bundle bundle = new Bundle();
bundle.putString("data", "Data you want to send");

// Your fragment
MyFragment obj = new MyFragment();
obj.setArguments(bundle);

Và trong Fragmentphương thức onCreateView lấy dữ liệu:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{
    String data = getArguments().getString("data");// data which sent from activity  
    return inflater.inflate(R.layout.myfragment, container, false);
}

3

Nếu một activitynhu cầu fragmentthực hiện một hành động sau khi khởi tạo, cách dễ nhất là bằng cách activitygọi một phương thức trên fragmentví dụ. Trong fragment, thêm một phương thức:

public class DemoFragment extends Fragment {
  public void doSomething(String param) {
      // do something in fragment
  }
}

và sau đó activity, truy cập vào fragmenttrình fragmentquản lý bằng cách sử dụng và gọi method:

public class MainActivity extends FragmentActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DemoFragment fragmentDemo = (DemoFragment) 
            getSupportFragmentManager().findFragmentById(R.id.fragmentDemo);
        fragmentDemo.doSomething("some param");
    }
}

và sau đó activitycó thể giao tiếp trực tiếp với fragmentbằng cách gọi này method.


1
Điều này thực sự tốt, theo nghĩa là bạn không muốn nhập vào onCreateViewphương thức trong đoạn. đã thực sự hữu ích
Young Emil

2

Sử dụng giao diện sau để liên lạc giữa hoạt động và phân đoạn

public interface BundleListener {
    void update(Bundle bundle);
    Bundle getBundle();
}

Hoặc sử dụng theo trình nghe chung này để giao tiếp hai chiều bằng giao diện

 /**
 * Created by Qamar4P on 10/11/2017.
 */
public interface GenericConnector<T,E> {
    T getData();
    void updateData(E data);
    void connect(GenericConnector<T,E> connector);
}

phương pháp hiển thị đoạn

public static void show(AppCompatActivity activity) {
        CustomValueDialogFragment dialog = new CustomValueDialogFragment();
        dialog.connector = (GenericConnector) activity;
        dialog.show(activity.getSupportFragmentManager(),"CustomValueDialogFragment");
    }

bạn có thể đặt bối cảnh của bạn GenericConnectorvàoonAttach(Context) quá

trong hoạt động của bạn

CustomValueDialogFragment.show(this);

trong mảnh của bạn

...
@Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        connector.connect(new GenericConnector() {
            @Override
            public Object getData() {
                return null;
            }

            @Override
            public void updateData(Object data) {

            }

            @Override
            public void connect(GenericConnector connector) {

            }
        });
    }
...
    public static void show(AppCompatActivity activity, GenericConnector connector) {
            CustomValueDialogFragment dialog = new CustomValueDialogFragment();
            dialog.connector = connector;
            dialog.show(activity.getSupportFragmentManager(),"CustomValueDialogFragment");
        }

Lưu ý: Không bao giờ sử dụng nó như "".toString().toString().toString();cách.


2

chỉ vấp phải câu hỏi này, trong khi hầu hết các phương pháp trên sẽ hoạt động. Tôi chỉ muốn thêm rằng bạn có thể sử dụng Thư viện xe buýt sự kiện , đặc biệt là trong các tình huống mà thành phần (Hoạt động hoặc phân đoạn) chưa được tạo, nó tốt cho tất cả các kích thước của các dự án Android và nhiều trường hợp sử dụng. Cá nhân tôi đã sử dụng nó trong một số dự án tôi có trên playstore.


1

Bạn có thể tạo phương thức tĩnh công khai trong đoạn mà bạn sẽ nhận được tham chiếu tĩnh của đoạn đó và sau đó chuyển dữ liệu đến hàm đó và đặt dữ liệu đó thành đối số trong cùng phương thức và nhận dữ liệu qua phương thức getArgument trên phương thức phân đoạn và đặt dữ liệu đó thành cục bộ biến.


1

Cách thông minh nhất đã thử và thử nghiệm để truyền dữ liệu giữa các đoạn và hoạt động là tạo một biến, ví dụ:

class StorageUtil {
  public static ArrayList<Employee> employees;
}

Sau đó, để truyền dữ liệu từ đoạn tới hoạt động, chúng tôi thực hiện theo phương pháp onActivityCreated:

//a field created in the sending fragment
ArrayList<Employee> employees;

@Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
         employees=new ArrayList();

       //java 7 and above syntax for arraylist else use employees=new ArrayList<Employee>() for java 6 and below

     //Adding first employee
        Employee employee=new Employee("1","Andrew","Sam","1984-04-10","Male","Ghanaian");
        employees.add(employee);

      //Adding second employee
       Employee employee=new Employee("1","Akuah","Morrison","1984-02-04","Female","Ghanaian");
         employees.add(employee);

        StorageUtil.employees=employees;
    }

Bây giờ bạn có thể nhận được giá trị của StorageUtil.emp NHÂN từ mọi nơi. Chúc may mắn!


0

Giải pháp của tôi là viết một phương thức tĩnh bên trong đoạn:

public TheFragment setData(TheData data) {
    TheFragment tf = new TheFragment();
    tf.data = data;
    return tf;
}

Bằng cách này, tôi chắc chắn rằng tất cả dữ liệu tôi cần đều nằm trong Fragment trước bất kỳ hoạt động nào khác có thể cần để làm việc với nó. Ngoài ra nó có vẻ sạch hơn theo ý kiến ​​của tôi.


1
Chà, nếu TheData không an toàn cho luồng, làm cho nó tĩnh sẽ không nhất thiết bảo vệ bạn khỏi các vấn đề về luồng. Cẩn thận với điều đó. Tĩnh không phải là chủ đề an toàn.
Martin Marconcini

0

Tôi gặp phải một vấn đề tương tự trong khi sử dụng thành phần kiến ​​trúc Điều hướng mới nhất. Đã thử tất cả các mã được đề cập ở trên với việc chuyển một gói từ hoạt động gọi của tôi sang Fragment.

Giải pháp tốt nhất, theo xu hướng phát triển mới nhất trong Android, là sử dụng View Model (một phần của Android Jetpack).

Tạo và khởi tạo một lớp ViewModel trong Hoạt động chính, Xin lưu ý rằng ViewModel này phải được chia sẻ giữa hoạt động và đoạn.

Bây giờ, Bên trong onViewCreated () của đoạn, Khởi tạo cùng ViewModel và thiết lập Trình quan sát để nghe các trường ViewModel.

Dưới đây là một hướng dẫn hữu ích, chuyên sâu nếu bạn cần.

https://medium.com/mindork/how-to-cransicate-b between-fragments-and-activivity-USE-viewmodel-ca733233a51c


-4

Trong hoạt động của bạn khai báo biến tĩnh

public static HashMap<String,ContactsModal> contactItems=new HashMap<String, ContactsModal>();

Sau đó, trong đoạn của bạn làm như làm theo

ActivityName.contactItems.put(Number,contactsModal);

Nó sẽ hoạt động nhưng KHÔNG ĐƯỢC KHUYẾN NGHỊ. Vì các thành viên tĩnh sẽ ở lại trong bộ nhớ trừ khi ứng dụng bị buộc đóng khỏi các ứng dụng gần đây. Vì vậy, trong trường hợp như thế này, bạn chỉ nên sử dụng thành viên tĩnh khi bạn cần nó trong nhiều hoạt động trong suốt ứng dụng.
M Shaban Ali
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.