Подтвердить что ты не робот

Как передать значения между фрагментами

Я новичок в использовании фрагментов.

Я просто пытаюсь создать простую примерную программу, в которой используются фрагменты. Мой сценарий: у меня есть два действия с одним фрагментом внутри каждого действия. Первый фрагмент имеет edittext и кнопку. Второй фрагмент имеет текстовое представление. Когда я вводим имя в edittext и нажимаю кнопку, текстовое представление во втором фрагменте должно отображать имя, введенное в edittext первого фрагмента.

Мне удалось отправить значение от первого фрагмента к его активности, а затем от этого действия до второго действия. Теперь, как использовать это значение во втором фрагменте.

Вот код 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);
    }

}

Я получаю следующее исключение:

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

Как получить значение из пакета в SecondActivity.java в Fragment_2.Java?

4b9b3361

Ответ 1

шаг 1. Чтобы отправить данные из фрагмента в действие

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

шаг 2.получать эти данные в Управлении:

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

шаг 3. для передачи данных из активности в другую деятельность следует нормальный подход

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

шаг 4, чтобы получать эти данные в действии

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

Шаг 5. Из операции вы можете отправить данные в Фрагмент с намерением как:

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

и получить в фрагменте метод Fragment onCreateView:

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

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

Ответ 2

Как отмечено на сайте разработчика

Часто вам нужно, чтобы один фрагмент связывался с другим, например, чтобы изменить контент на основе пользовательского события. Вся связь между фрагментами и фрагментами осуществляется через связанную с ней активность. Два фрагмента никогда не должны связываться напрямую.

связь между фрагментами должна выполняться посредством связанной с ней деятельности.

Пусть имеют следующие компоненты:

Операция содержит фрагменты и позволяет передавать фрагменты

FragmentA первый фрагмент, который отправит данные

FragmentB второй фрагмент, который будет получать данные из FragmentA

Реализация FragmentA:

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

Реализация MainActivity:

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

Реализация FragmentB:

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

Надеюсь, это поможет..

Ответ 3

От разработчиков:

Часто вам нужно, чтобы один фрагмент связывался с другим, например, чтобы изменить контент на основе пользовательского события. Вся связь между фрагментами и фрагментами осуществляется через связанную с ней активность. Два фрагмента никогда не должны связываться напрямую.

Вы можете общаться между фрагментами с помощью своей деятельности. Вы можете взаимодействовать между активностью и фрагментом, используя этот подход.

Также проверьте эту ссылку.

Ответ 4

//В 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();

//В Fragment_2.java

Bundle bundle = this.getArguments();

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

Надеюсь, что это поможет вам.

Ответ 5

Сначала все ответы правильные, вы можете передавать данные, кроме настраиваемых объектов, с помощью Intent. Если вы хотите передать пользовательские объекты, вы должны реализовать Serialazable или Pacelable в свой собственный класс объектов. Я думал, что это слишком сложно, поэтому, если ваш проект прост, попробуйте использовать этот DataCache. Это обеспечивает простой способ передачи данных. ref: https://github.com/kimkevin/AndroidDataCache

1 Установите это для просмотра или действия или фрагмента, которые будут отправлять данные

DataCache.getInstance().push(obj);

2 Получить данные в любом месте ниже

public class MainFragment extends Fragment {
    private YourObject obj;

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

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

Ответ 6

Общение между фрагментами довольно сложно (я считаю, что концепция слушателей немного сложна для реализации).

Для абстрактной передачи этих сообщений используется "Event Bus". Это сторонняя библиотека, которая заботится об этом сообщении для вас.

"Отто" - это тот, который часто используется для этого, и, возможно, стоит обратить внимание на: http://square.github.io/otto/

Ответ 7

Передача аргументов между фрагментами. Это довольно поздно, чтобы ответить на этот вопрос, но это может помочь кому-то! 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();

Затем в вашем Fragment_2.java вы можете получить параметры, обычно в пределах onActivityCreated например,

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

Ответ 8

Передача данных из фрагмента в другой фрагмент

  • От первого фрагмента

    // 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(); 
    
  • Во втором фрагменте

    @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
         } 
    }
    

Ответ 9

Я сделал что-то действительно легкое для начинающих вроде меня.. я сделал textview в свой Activity_main.xml и поместил

id=index
visibility=invisible

тогда я получаю это текстовое представление из первого фрагмента

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

а затем во втором фрагменте я получаю значение

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

надеюсь, что это поможет!

Ответ 10

Эта простая реализация помогает легко передавать данные между фрагментами. Думайте, что хотите передать данные с 'Frgment1' в 'Fragment2'

В Fragment1 (Установить данные для отправки)

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

В Fragment2 onCreateView метод (Получить параметры)

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

Ответ 11

Я думаю, что хороший способ решить эту проблему - использовать пользовательский интерфейс.

Допустим, у вас есть два фрагмента (A и B), которые находятся внутри одного и того же действия, и вы хотите отправить данные с A на B.

Интерфейс:

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

Активность:

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

Фрагмент 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;
    }
}

Фрагмент 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
            }
        });
    }
}