Cách chuyển giá trị giữa các phân đoạn


109

Tôi khá mới sử dụng Fragment.

Tôi chỉ đang cố gắng xây dựng một ứng dụng mẫu đơn giản sử dụng Fragment. Kịch bản của tôi là, tôi có hai hoạt động với một phần bên trong mỗi hoạt động. Đoạn đầu tiên có một văn bản chỉnh sửa và một nút. Phân đoạn thứ hai có một chế độ xem văn bản. Khi tôi nhập tên vào văn bản chỉnh sửa và nhấp vào nút, chế độ xem văn bản trong phân đoạn thứ hai sẽ hiển thị tên đã nhập trong văn bản chỉnh sửa của phân đoạn đầu tiên.

Tôi đã có thể gửi giá trị từ phân đoạn đầu tiên đến hoạt động của nó và sau đó từ hoạt động đó sang hoạt động thứ hai. Bây giờ làm cách nào để sử dụng giá trị này bên trong phân đoạn thứ hai.

Đây là mã Java :::

package com.example.fragmentexample;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class Fragment_1 extends Fragment{

    OnFragmentChangedListener mCallback;

    // Container Activity must implement this interface
    public interface OnFragmentChangedListener {
        public void onButtonClicked(String name);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (OnFragmentChangedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnHeadlineSelectedListener");
        }
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub      

        View view = inflater.inflate(R.layout.fragment_fragment_1, container, false);

        final EditText edtxtPersonName_Fragment = (EditText) view.findViewById(R.id.edtxtPersonName);
        Button btnSayHi_Fragment = (Button) view.findViewById(R.id.btnSayHi);

        btnSayHi_Fragment.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                String name = edtxtPersonName_Fragment.getText().toString();

                FragmentManager fm = getFragmentManager();
                Fragment_2 f2 = (Fragment_2) fm.findFragmentById(R.id.fragment_content_2);

                Activity activity = getActivity();

                if(activity != null)
                {
                    Toast.makeText(activity, "Say&ing Hi in Progress...", Toast.LENGTH_LONG).show();
                }


                if(f2 != null && f2.isInLayout())
                {
                    f2.setName(name);
                }
                else
                {
                    mCallback.onButtonClicked(name);
                }
            }
        });

        return view;


    }

}

MainActivity.Java

package com.example.fragmentexample;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;

import android.view.Choreographer.FrameCallback;
import android.view.Menu;

public class MainActivity extends Activity implements Fragment_1.OnFragmentChangedListener {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    public void onButtonClicked(String name) {
        // TODO Auto-generated method stub

        Intent i = new Intent(this, SecondActivity.class);
        i.putExtra("", name);
        startActivity(i);
    }

}

SecondActivity.Java

package com.example.fragmentexample;

import android.app.Activity;
import android.os.Bundle;

public class SecondActivity extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_second);

        Bundle b = getIntent().getExtras();

        Fragment_2 f2 = new Fragment_2();
        f2.setArguments(b);
    }
}

Fragment_2.Java

package com.example.fragmentexample;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class Fragment_2 extends Fragment{

    View view;
    TextView txtName;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub

        view = inflater.inflate(R.layout.fragment_fragment_2, container, false);

            // Exception at this line
        String name = getArguments().getString("message");
        txtName = (TextView) view.findViewById(R.id.txtViewResult);
        txtName.setText(name);

        return view;
    }

    @Override
    public void onAttach(Activity activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);       
    }

    public void setName(String name)
    {   
        txtName.setText("Hi " + name);
    }

}

Tôi nhận được ngoại lệ sau :::

04-16 18:10:24.573: E/AndroidRuntime(713): FATAL EXCEPTION: main
04-16 18:10:24.573: E/AndroidRuntime(713): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fragmentexample/com.example.fragmentexample.SecondActivity}: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1815)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.access$500(ActivityThread.java:122)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1024)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.os.Handler.dispatchMessage(Handler.java:99)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.os.Looper.loop(Looper.java:132)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.main(ActivityThread.java:4123)
04-16 18:10:24.573: E/AndroidRuntime(713):  at java.lang.reflect.Method.invokeNative(Native Method)
04-16 18:10:24.573: E/AndroidRuntime(713):  at java.lang.reflect.Method.invoke(Method.java:491)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
04-16 18:10:24.573: E/AndroidRuntime(713):  at dalvik.system.NativeStart.main(Native Method)
04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:688)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:724)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.inflate(LayoutInflater.java:391)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.inflate(LayoutInflater.java:347)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:223)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Activity.setContentView(Activity.java:1786)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.example.fragmentexample.SecondActivity.onCreate(SecondActivity.java:13)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Activity.performCreate(Activity.java:4397)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1779)
04-16 18:10:24.573: E/AndroidRuntime(713):  ... 11 more
04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: java.lang.NullPointerException
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.example.fragmentexample.Fragment_2.onCreateView(Fragment_2.java:24)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:754)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:956)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1035)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Activity.onCreateView(Activity.java:4177)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:664)
04-16 18:10:24.573: E/AndroidRuntime(713):  ... 21 more

Làm cách nào để lấy giá trị từ gói trong SecondActivity.java sang Fragment_2.Java?


Hãy làm nổi bật phần nơi ru nhận được vấn đề
Nikhil Agrawal

giải pháp làm việc một cách dễ dàng: stackoverflow.com/a/59332751/10201722
Adil Siddiqui

Câu trả lời:


203

bước 1. để gửi dữ liệu từ phân mảnh đến hoạt động

Intent intent = new Intent(getActivity().getBaseContext(),
                        TargetActivity.class);
                intent.putExtra("message", message);
                getActivity().startActivity(intent);

bước 2. để nhận dữ liệu này trong Hoạt động:

Intent intent = getIntent();
String message = intent.getStringExtra("message");

bước 3 . để gửi dữ liệu từ hoạt động này sang hoạt động khác theo cách tiếp cận thông thường

Intent intent = new Intent(MainActivity.this,
                        TargetActivity.class);
                intent.putExtra("message", message);
                startActivity(intent);

bước 4 để nhận dữ liệu này trong hoạt động

     Intent intent = getIntent();
  String message = intent.getStringExtra("message");

Bước 5. Từ Activity, bạn có thể gửi dữ liệu đến Fragment với mục đích như sau:

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

và nhận trong phân đoạn trong phương thức onCreateView Fragment:

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

    return inflater.inflate(R.layout.fragment, container, false);
    }

2
Tôi đã thử bước 5, Đó là tôi đang gọi danh sách từ phân đoạn và sau khi chọn mục từ hoạt động đó, tôi muốn quay lại phân đoạn với tên tệp đã chọn. Nhưng nó không hoạt động, nó cho tôi Nullpointer Exception tại onCreateView. Bất kỳ giải pháp này xin vui lòng? Đây là câu hỏi của tôi stackoverflow.com/questions/18208771/…
OnkarDhane

làm cách nào để đặt POJO ở đây? bundle.putString("message", "From Activity");
jeet.chanchawat

31
Có ai phẫn nộ như thế nào phức tạp làm một cái gì đó như thế này là
Ed Lee

1
Chính xác là Eddie, đây không phải là cách chính xác. Họ nên sử dụng các giao diện để giao tiếp giữa các phân đoạn thông qua hoạt động vùng chứa.
Kaveesh Kanwal

Về việc sử dụng các giao diện để giao tiếp giữa các phân đoạn: developer.android.com/training/basics/fragment/…
Andre L Torres

49

Như đã lưu ý tại trang web của nhà phát triển

Thường thì bạn sẽ muốn một Fragment giao tiếp với một Fragment khác, chẳng hạn như để thay đổi nội dung dựa trên một sự kiện của người dùng. Tất cả các giao tiếp từ Fragment-to-Fragment được thực hiện thông qua Activity liên kết. Hai mảnh vỡ không bao giờ được giao tiếp trực tiếp.

giao tiếp giữa các phân đoạn nên được thực hiện thông qua Hoạt động liên kết.

Hãy có các thành phần sau:

Một hoạt động lưu trữ các phân đoạn và cho phép giao tiếp các phân đoạn

Phân mảnh Một phân mảnh đầu tiên sẽ gửi dữ liệu

FragmentB phân đoạn thứ hai sẽ nhận dữ liệu từ FragmentA

Cách triển khai của FragmentA là:

public class FragmentA extends Fragment 
{
    DataPassListener mCallback;
    
    public interface DataPassListener{
        public void passData(String data);
    }

    @Override
    public void onAttach(Context context) 
    {
        super.onAttach(context);
        // This makes sure that the host activity has implemented the callback interface
        // If not, it throws an exception
        try 
        {
            mCallback = (OnImageClickListener) context;
        }
        catch (ClassCastException e) 
        {
            throw new ClassCastException(context.toString()+ " must implement OnImageClickListener");
        }
    }
    
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) 
    {
        // Suppose that when a button clicked second FragmentB will be inflated
        // some data on FragmentA will pass FragmentB
        // Button passDataButton = (Button).........
        
        passDataButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (view.getId() == R.id.passDataButton) {
                    mCallback.passData("Text to pass FragmentB");
                }
            }
        });
    }
}

Triển khai MainActivity là:

public class MainActivity extends ActionBarActivity implements DataPassListener{
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        if (findViewById(R.id.container) != null) {
            if (savedInstanceState != null) {
                return;
            }
            getFragmentManager().beginTransaction()
                    .add(R.id.container, new FragmentA()).commit();
        }
    }
    
    @Override
    public void passData(String data) {
        FragmentB fragmentB = new FragmentB ();
        Bundle args = new Bundle();
        args.putString(FragmentB.DATA_RECEIVE, data);
        fragmentB .setArguments(args);
        getFragmentManager().beginTransaction()
            .replace(R.id.container, fragmentB )
            .commit();
    }
}

Triển khai FragmentB là:

public class FragmentB extends Fragment{
    final static String DATA_RECEIVE = "data_receive";
    TextView showReceivedData;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_B, container, false);
        showReceivedData = (TextView) view.findViewById(R.id.showReceivedData);
    }
    
    @Override
    public void onStart() {
        super.onStart();
        Bundle args = getArguments();
        if (args != null) {
            showReceivedData.setText(args.getString(DATA_RECEIVE));
        }
    }
}

Hy vọng điều này có thể giúp cho bạn..


4
OnImageClickListener ở đây là gì? và nó được truyền tới một biến DataPassListener như thế nào?
Harsha

Tôi thấy đó là "DataPassListener". Tôi đã làm cho nó hoạt động, nhưng chỉ để tìm do mỗi khi nút được nhấp vào, dữ liệu được gửi đi. Khi nó được gửi đi, nó sẽ thay thế phân mảnh. Điều đó có nghĩa là danh sách này luôn được gia hạn. Do đó, không giữ danh sách các mục trong bộ nhớ.
wesley franks

44

// Trong Fragment_1.java

Bundle bundle = new Bundle();
bundle.putString("key","abc"); // Put anything what you want

Fragment_2 fragment2 = new Fragment_2();
fragment2.setArguments(bundle);

getFragmentManager()
      .beginTransaction()
      .replace(R.id.content, fragment2)
      .commit();

// Trong Fragment_2.java

Bundle bundle = this.getArguments();

if(bundle != null){
     // handle your code here.
}

Hy vọng điều này sẽ giúp bạn.


1
Câu trả lời rõ ràng để chỉ ra điểm chính. sử dụng putString(hoặc putInt) là câu trả lời!
Mehdi Dehghani,

22

Từ trang web Nhà phát triển :

Thường thì bạn sẽ muốn một Fragment giao tiếp với một Fragment khác, chẳng hạn như để thay đổi nội dung dựa trên sự kiện của người dùng. Tất cả các giao tiếp từ Fragment-to-Fragment được thực hiện thông qua Activity được liên kết. Hai mảnh vỡ không bao giờ được giao tiếp trực tiếp.

Bạn có thể giao tiếp giữa các mảnh với sự trợ giúp của Hoạt động của nó. Bạn có thể giao tiếp giữa các hoạt động và phân đoạn bằng cách sử dụng phương pháp này .

Vui lòng kiểm tra liên kết này .


Liên kết thứ hai mà bạn đã đưa ra, cho thấy cách giao tiếp giữa các phân đoạn khi chúng ở trong cùng một hoạt động. Làm cách nào để giao tiếp khi cả hai đang hoạt động khác nhau?
Vamsi Challa

5

Đầu tiên tất cả các câu trả lời đều đúng, bạn có thể chuyển dữ liệu ngoại trừ các đối tượng tùy chỉnh bằng cách sử dụng Intent. Nếu bạn muốn chuyển các đối tượng tùy chỉnh, bạn phải triển khai SerialazablehoặcParcelable đến lớp đối tượng tùy chỉnh của mình. Tôi nghĩ nó quá phức tạp ...

Vì vậy, nếu dự án của bạn đơn giản, hãy thử sử dụng DataCache. Điều đó cung cấp một cách siêu đơn giản để truyền dữ liệu. Tham khảo: Dự án Github CachePot

1- Đặt cài đặt này thành Chế độ xem hoặc Hoạt động hoặc Phân đoạn sẽ gửi dữ liệu

DataCache.getInstance().push(obj);

2- Nhận dữ liệu ở mọi nơi như bên dưới

public class MainFragment extends Fragment
{
    private YourObject obj;

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

        obj = DataCache.getInstance().pop(YourObject.class);

    }//end onCreate()
}//end class MainFragment

Sẽ dễ dàng hơn nếu sử dụng một lớp bổ sung với các giá trị tĩnh bên trong? Sau đó, các giá trị này có thể được truy cập bởi cả hai phân đoạn, vì vậy không cần sử dụng thêm thư viện để lưu vào bộ đệm các đối tượng tùy chỉnh.
Neph

4

Giải pháp mới nhất để truyền dữ liệu giữa các phân đoạn có thể được thực hiện bằng cách sử dụng các thành phần kiến ​​trúc android như ViewModel và LiveData. Với giải pháp này, bạn không cần phải xác định giao diện cho giao tiếp và có thể nhận được những lợi thế của việc sử dụng mô hình xem như sự tồn tại của dữ liệu do thay đổi cấu hình.

Trong giải pháp này, các đoạn liên quan đến giao tiếp chia sẻ cùng một đối tượng view model được gắn với vòng đời hoạt động của chúng. Đối tượng mô hình khung nhìn chứa đối tượng liveata. Một phân đoạn thiết lập dữ liệu được truyền trên đối tượng liveata và phân đoạn thứ hai quan sát các thay đổi của liveata và nhận dữ liệu.

Đây là ví dụ đầy đủ http://www.zoftino.com/passing-data-between-android-fragment-using-viewmodel


3

Truyền đối số giữa các đoạn. Đây là một câu hỏi khá muộn để trả lời nhưng nó có thể giúp ích cho ai đó! Fragment_1.java

Bundle i = new Bundle(); 
            i.putString("name", "Emmanuel");

            Fragment_1 frag = new Fragment_1();
            frag.setArguments(i);
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction()
                    .replace(R.id.content_frame
                            , new Fragment_2())
                    .commit();

Sau đó, Fragment_2.javabạn có thể lấy paramaters bình thường trong onActivityCreated ví dụ của bạn

 Intent intent = getActivity().getIntent();
    if (intent.getExtras() != null) {
        String name =intent.getStringExtra("name");
    }

3

Tôi nghĩ một cách tốt để giải quyết vấn đề này là sử dụng giao diện tùy chỉnh.

Giả sử bạn có hai phân đoạn (A và B) nằm trong cùng một hoạt động và bạn muốn gửi dữ liệu từ A đến B.

Giao diện:

public interface OnDataSentListener{
    void onDataSent(Object data);
}

Hoạt động:

    public class MyActivity extends AppCompatActivity{

            private OnDataSentListener onDataSentListener;

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

                FragmentTransaction trans = getFragmentManager().beginTransaction();

                FragmentA fa = new FragmentA();
                FragmentB fb = new FragmentB();

               fa.setOnDataSentListener(new Listeners.OnDataSentListener() {
                    @Override
                    public void onDataSent(Object data) {
                         if(onDataSentListener != null)  onDataSentListener.onDataSent(data);
                    }
               });

                transaction.add(R.id.frame_a, fa);
                transaction.add(R.id.frame_b, fb);

                transaction.commit();
            }

            public void setOnDataSentListener(OnDataSentListener listener){
                this.onDataSentListener = listener;
            }
        }

Phân đoạn A:

public class FragmentA extends Fragment{

    private OnDataSentListener onDataSentListener;

    private void sendDataToFragmentB(Object data){
        if(onDataSentListener != null) onDataSentListener.onDataSent(data);
    }

    public void setOnDataSentListener(OnDataSentListener listener){
        this.onDataSentListener = listener;
    }
}

Phân đoạn B:

public class FragmentB extends Fragment{

    private void initReceiver(){
        ((MyActivity) getActivity()).setOnDataSentListener(new OnDataSentListener() {
            @Override
            public void onDataSent(Object data) {
                //Here you receive the data from fragment A
            }
        });
    }
}

2

Giao tiếp giữa các đoạn khá phức tạp (tôi thấy khái niệm người nghe hơi khó thực hiện).

Thông thường người ta sử dụng 'Xe buýt sự kiện' để tóm tắt các thông tin liên lạc này. Đây là thư viện của bên thứ 3 đảm nhiệm việc liên lạc này cho bạn.

'Otto' là một công cụ thường được sử dụng để làm điều này và có thể đáng xem: http://square.github.io/otto/


2

Truyền dữ liệu từ Fragment sang Fragment khác

  • Từ mảnh đầu tiên

    // Set data to pass
    MyFragment fragment = new MyFragment(); //Your Fragment
    Bundle bundle = new Bundle();
    bundle.putInt("year", 2017)  // Key, value
    fragment.setArguments(bundle); 
    // Pass data to other Fragment
    getFragmentManager()
     .beginTransaction()
     .replace(R.id.content, fragment)
     .commit(); 
  • Trên phân mảnh thứ hai

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
    
         Bundle bundle = this.getArguments();
         if (bundle != null) {
             Int receivedYear = bundle.getInt("year", ""); // Key, default value
         } 
    }

1

Việc triển khai đơn giản này giúp truyền dữ liệu giữa các đoạn một cách đơn giản. Nghĩ rằng bạn muốn chuyển dữ liệu từ 'Frgment1' sang 'Fragment2'

Trong Fragment1 (Đặt dữ liệu để gửi)

 Bundle bundle = new Bundle();
 bundle.putString("key","Jhon Doe"); // set your parameteres

 Fragment2 nextFragment = new Fragment2();
 nextFragment.setArguments(bundle);

 FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
 fragmentManager.beginTransaction().replace(R.id.content_drawer, nextFragment).commit();

Trong phương thức onCreateView của Fragment2 (Lấy tham số)

String value = this.getArguments().getString("key");//get your parameters
Toast.makeText(getActivity(), value+" ", Toast.LENGTH_LONG).show();//show data in tost

Trong ứng dụng của tôi, tôi đang cố gắng làm cho điều này hoạt động nhưng bằng cách nào đó, mặc dù giá trị đang được truyền nhưng nó không được hiển thị trên mảnh2, tôi nghĩ rằng tôi đang mắc lỗi khi đặt R.id.content_drawer. Ai đó có thể hướng dẫn tôi những gì có thể là định danh phù hợp cho R.id.content_drawer với ví dụ .xml.
falcon

1

Kotlin cách

Sử dụng một SharedViewModelđề xuất tại tài liệu ViewModel chính thức

Rất phổ biến khi hai hoặc nhiều đoạn trong một hoạt động cần giao tiếp với nhau. Hãy tưởng tượng một trường hợp phổ biến của các phân đoạn chi tiết chính, trong đó bạn có một phân đoạn trong đó người dùng chọn một mục từ danh sách và một phân đoạn khác hiển thị nội dung của mục đã chọn. Trường hợp này không bao giờ là quan trọng vì cả hai phân đoạn đều cần xác định một số mô tả giao diện và hoạt động của chủ sở hữu phải liên kết cả hai lại với nhau. Ngoài ra, cả hai phân đoạn phải xử lý tình huống mà phân đoạn kia chưa được tạo hoặc hiển thị.

Điểm đau chung này có thể được giải quyết bằng cách sử dụng các đối tượng ViewModel. Các đoạn này có thể chia sẻ một ViewModel bằng cách sử dụng phạm vi hoạt động của chúng để xử lý giao tiếp này

Đầu tiên hãy triển khai phân mảnh-ktx để khởi tạo mô hình xem của bạn dễ dàng hơn

dependencies {
    implementation "androidx.fragment:fragment-ktx:1.2.2"
} 

Sau đó, bạn chỉ cần đưa vào bên trong mô hình xem dữ liệu mà bạn sẽ chia sẻ với phân đoạn khác

class SharedViewModel : ViewModel() {
    val selected = MutableLiveData<Item>()

    fun select(item: Item) {
        selected.value = item
    }
}

Sau đó, để kết thúc, chỉ cần khởi tạo viewModel của bạn trong từng phân đoạn và đặt giá trị của selected từ phân đoạn bạn muốn đặt dữ liệu

Phân mảnh A

class MasterFragment : Fragment() {

    private val model: SharedViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        itemSelector.setOnClickListener { item ->
        model.select(item)
      }

    }
}

Và sau đó, chỉ cần lắng nghe giá trị này tại đích Fragment của bạn

Phân đoạn B

 class DetailFragment : Fragment() {

        private val model: SharedViewModel by activityViewModels()

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            model.selected.observe(viewLifecycleOwner, Observer<Item> { item ->
                // Update the UI
            })
        }
    }

Bạn cũng có thể làm theo cách ngược lại


0

Giải pháp làm việc 100%: (nếu giúp bạn thì đừng quên nhấn upvote)

Trong Phân đoạn đầu tiên của bạn, hãy đặt đoạn mã này:

    editprofile.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    Fragment_editprofile Fragment = new Fragment_editprofile();
.
.
.
.
.


                Fragment.getintentdetails(tv_name.getText().toString(),
                            tv_mob.getText().toString(), tv_email.getText().toString(), tv_dob.getText().toString(),
                            tv_gender.getText().toString(), photointent);

                }
            });

Trong Phân đoạn thứ hai, hãy tạo phương thức như sau:

public void getintentdetails(String name, String mobile, String email, String dob, String gender,
                                 String photointent) {

        this.name_str= name;
        this.mob_str= mobile;
        this.email_str= email;
        this.dob_str= dob;
        this.gender_str= gender;
        this.photo_str= photointent;

    }

sau đó xác định một biến ở cấp độ lớp:

String name_str, mob_str, dob_str, photo_str, email_str, gender_str;

sau đó tạo một phương thức khác trong phân đoạn thứ hai để đặt giá trị:

  setexistingdetails();


private void setexistingdetails() {

        if(!name_str.equalsIgnoreCase(""))
            (et_name).setText(name_str);
        if(!mob_str.equalsIgnoreCase(""))
            et_mobile.setText(mob_str);
        if(!email_str.equalsIgnoreCase(""))
            email_et.setText(email_str);
        if(!dob_str.equalsIgnoreCase(""))
            dob_et.setText(dob_str);
        if(!gender_str.equalsIgnoreCase("")){
            if (gender_str.equalsIgnoreCase("m")){
                male_radio.setChecked(true);
            }else {
                female_radio.setChecked(true);
            }
        }
        if(!photo_str.equalsIgnoreCase("")){
            try {
                Picasso.get().load(Const.BASE_PATH+"include/sub-domain/GENIUS/"+photo_str).into(adminpropic_edit);
            } catch (Exception e) {            }
        }
    }

0

Bạn có thể đạt được mục tiêu của mình bằng ViewModelLive Data được Arnav Rao xóa . Bây giờ tôi đặt một ví dụ để xóa nó gọn gàng hơn.

Đầu tiên, giả định ViewModelđược đặt tên SharedViewModel.java.

public class SharedViewModel extends ViewModel {
    private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

    public void select(Item item) {
        selected.setValue(item);
    }
    public LiveData<Item> getSelected() {
        return selected;
    }
}

Sau đó, phân đoạn nguồnMasterFragment.javanơi chúng ta muốn gửi dữ liệu.

public class MasterFragment extends Fragment {
    private SharedViewModel model;

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> {

            // Data is sent

            model.select(item);
        });
    }
}

Và cuối cùng, phân đoạn đíchDetailFragment.javanơi chúng ta muốn nhận dữ liệu.

public class DetailFragment extends Fragment {

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        model.getSelected().observe(getViewLifecycleOwner(), { item ->

           // Data is received 

        });
    }
}

0

Được rồi, sau rất nhiều lần tìm hiểu ở đây, tôi đã tìm thấy một giải pháp đơn giản, thực sự bạn không bao giờ nên chuyển dữ liệu từ phân mảnh sang phân mảnh luôn là một ý tưởng tồi, bạn có thể chuyển dữ liệu từ phân đoạn A sang hoạt động và lấy dữ liệu từ hoạt động trong phân đoạn B.

For Example
//fragment A
//your method that will be called in Main Activity for getting data from this fragment
public List<customDataModel> getlist(){
return mlist; //your custom list 
}
buttonopen.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //before calling  your new fragment, send a Broadcast signal to your main activity
 mContext.sendBroadcast(new Intent("call.myfragment.action"));
//here you are now changing the fragment
Fragment fragment1 = new VolunteerListDetailsFragment();

            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.replace(R.id.content_frame, fragment1);
            ft.commit();
        }
    });

// trong Hoạt động chính

this.registerReceiver(mBroadcastReceiver, new IntentFilter("call.myfragment.action"));//this line should be in your onCreate method
   BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
//init the fragment A
FragmenA fragment =
                (FragmentA) getSupportFragmentManager().findFragmentById(R.id.content_frame);
        mlistdetails = fragment.getlist();//this is my method in fragmentA which is retuning me a custom list, init this list type in top of on create fragment


    }
};
//here you are creating method that is returning the list that you just recieved From fragmentA
public List<customDataModel> getcustomlist(){
return mlistdetails; //you are returning the same list that you recived from fragmentA
}

// bây giờ trong FragmentB

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

    View rootView = (View) inflater.inflate(R.layout.vol_listdetails, container, false);

    mlistdetails=((MainActivity)getActivity()).getcustomlist();//here you are calling the method that you have created in Main Activity

    Toast.makeText(getActivity().getApplicationContext(), mlistdetails.get(0).getItemqty(), Toast.LENGTH_SHORT).show();
    return rootView;

}

-2

tôi đã tạo ra một cái gì đó thực sự dễ dàng cho những người ăn xin như tôi .. tôi đã tạo một textview trong activity_main.xml của mình và đặt

id=index
visibility=invisible

sau đó tôi nhận được chế độ xem văn bản này từ phân đoạn đầu tiên

index= (Textview) getActivity().findviewbyid(R.id.index)
index.setText("fill me with the value")

và sau đó trong phân đoạn thứ hai tôi nhận được giá trị

index= (Textview) getActivity().findviewbyid(R.id.index)
String get_the_value= index.getText().toString();

hy vọng nó giúp!


Câu trả lời không liên quan đến câu hỏi được hỏi
Kanagalingam
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.