How to send Object value from fragment to fragment in Serializable?

别等时光非礼了梦想. 提交于 2019-12-12 04:23:08

问题


My condition is that i have three fragments A、B、C , i set the value in Afragment and get the value in Cfragment.

I want change layout into Bfragment when in Afragment.

Compile the project shows Bundle.getSerializable(java.lang.String)' on a null object reference that i change layout into Cfragment when in Bfragment.

I want to use Serializable that can let me get the value in Cfragment.

How do i finish it ? Any help would be greatly appreciated.

My Serializable bean:

public class Book implements Serializable {
    String name;

    public Book(){

    }

    public Book(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

My MainActivity:

public class MainActivity extends AppCompatActivity {

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

        A a=new A();
        switchFragment(a);
    }

    public void switchFragment(Fragment fragment) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        transaction.replace(R.id.main_frameLayout, fragment, null);
        transaction.addToBackStack(null);
        transaction.commit();
    }
}

Afragment:

public class A extends Fragment {

    B b=new B();

    public A() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view=inflater.inflate(R.layout.fragment_a, container, false);

        Book book=new Book();
        book.setName("Jerry");
        //try to send the value to Cfragment
        C c=new C();
        Bundle bundle=new Bundle();
        bundle.putSerializable("name",book);
        c.setArguments(bundle);


        //change layout into Bfragment
        Button button=(Button)view.findViewById(R.id.buttonA);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                switchFragment(b);
            }
        });

        return view;
    }

    public void switchFragment(Fragment fragment) {
        FragmentManager manager = getFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        transaction.replace(R.id.main_frameLayout, fragment, null);
        transaction.addToBackStack(null);
        transaction.commit();
    }

}

Bfragment:

public class B extends Fragment {

    C c=new C();

    public B() {
        // Required empty public constructor
    }


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

        View view=inflater.inflate(R.layout.fragment_b, container, false);
        //change layout into Cfragment
        Button button=(Button)view.findViewById(R.id.buttonB);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                switchFragment(c);
            }
        });

        return view;
    }

    public void switchFragment(Fragment fragment) {
        FragmentManager manager = getFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        transaction.replace(R.id.main_frameLayout, fragment, null);
        transaction.addToBackStack(null);
        transaction.commit();
    }
}

Cfragment:

public class C extends Fragment {

    Book book;

    public C() {
        // Required empty public constructor
    }


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

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

        TextView textView=(TextView)view.findViewById(R.id.textC);
        //try to get the setting value from Aframent 
        Bundle bundle=getArguments();
        book=(Book) bundle.getSerializable("name");
        textView.setText(book.getName());

        return view;
    }

}

According to CoDFather respond that i change like this :

public static C newInstance(String param1) {
        C fragment = new C();
        Bundle args = new Bundle();
        Book book=new Book();
        book.setName(param1);
        args.putSerializable("name", book);  // in your case it is serializable
        fragment.setArguments(args);
        return fragment;
    }

in A:

C.newInstance("Jerry");

in C onCreate:

Book book=(Book) getArguments().getSerializable("name");
        textView.setText(book.getName());

When B to C : it shows Serializable android.os.Bundle.getSerializable(java.lang.String)' on a null object reference in return fragment


回答1:


In Fragment A you are doing that

C c=new C();
Bundle bundle=new Bundle();
bundle.putSerializable("name",book);
c.setArguments(bundle);

But you did not used this c object from your C fragment.

Instead in your Fragment B you defined C c=new C(); which is a completely new object of your C fragment then you switched to this new c without setting arguments.

Simply, You are setting arguments on an object and then you use another one! That is why getArguments() returen null

If you want to pass the arugments from A to C you need to get it from A into B first the pass it again to C

in B in onCreateView

c.setArguments(getArguments());

Then you can switch to this c




回答2:


In your fragment A do this

    B b=new B();
    Bundle bundle=new Bundle();
    bundle.putSerializable("name",book);
    b.setArguments(bundle);

in fragment B

    C c=new C();
    c.setArguments(getArguments());

and use switchFragment(c);

The reason why getArguments() return null is, you are setting arguments to one and using the other.

But it is not recommended way to do it. use newInstance instead.

public static C newInstance(String param1, String param2) {
        C fragment = new C();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);  // in your case it is serializable
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

and in on create

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

and use C.newInstance(params1,params) . In your case replace it with bundle.




回答3:


I find a solution to save my issue , it is about singleton:

I use it for my Book class like this:

public static Book book=null;

    public static Book getBook(){
        if (book==null){
            book=new Book();
            return book;
        }else {
            return book;
        }
    }

in A:

Book book=Book.getBook();
book.setName("Jerry");

in C:

Book book=Book.getBook();
textView.setText(book.getName());

then my issue is over , i have to give up Serializable on my condition.



来源:https://stackoverflow.com/questions/42240479/how-to-send-object-value-from-fragment-to-fragment-in-serializable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!