2016-11-18 84 views
0

我試圖從AFragment傳遞MyData(Parcelable對象,包括ArrayList)到BFragment。 當然,它工作。但是,ArrayList的引用是相同的。在調用值的片段之間傳遞數據不參考

我看過關於Parcelable的各種文章,最後我發現只有當兩個對象在不同的​​任務中時,Parcelable纔會重新創建實例。

如何傳遞數據與原始類型不參考類型?

我寫了如下代碼。

邁德特

public class MyData implements Parcelable { 

public List<String> mList = new ArrayList<>(0); 

@Override 
public int describeContents() { 
    return 0; 
} 

@Override 
public void writeToParcel(Parcel out, int flags) { 
    out.writeStringList(mList); 
} 

public static final Parcelable.Creator<MyData> CREATOR = new Parcelable.Creator<MyData>() { 
    public MyData createFromParcel(Parcel in) { 
     return new MyData(in); 
    } 

    public MyData[] newArray(int size) { 
     return new MyData[size]; 
    } 
}; 

private MyData(Parcel in) { 
    in.writeStringList(mList); 
} 

public MyData() { 
} 
} 

MainActivity

public class MainActivity extends AppCompatActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    SampleFragment sampleFragment = new SampleFragment(); 
    replaceFragment(sampleFragment); 
} 

public void replaceFragment(Fragment fragment) { 
    FragmentManager manager = getSupportFragmentManager(); 

    if (manager.findFragmentByTag(fragment.getClass().getCanonicalName()) != null) { 
     return; 
    } 
    FragmentTransaction transaction = manager.beginTransaction(); 
    transaction.replace(R.id.container_layout, fragment, fragment.getClass().getCanonicalName()); 
    transaction.addToBackStack(null); 
    transaction.commit(); 
} 
} 

AFragment

public class SampleFragment extends Fragment implements View.OnClickListener { 

MainActivity mActivity; 

@Override 
public void onAttach(Context context) { 
    super.onAttach(context); 
    mActivity = (MainActivity) context; 
} 

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

@Nullable 
@Override 
public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.sample1, container, false); 
    view.findViewById(R.id.button).setOnClickListener(this); 
    return view; 
} 

@Override 
public void onClick(View v) { 
    int id = v.getId(); 
    if (id == R.id.button) { 
     List<String> list = new ArrayList<>(0); 
     list.add("sample1"); 
     list.add("sample2"); 
     list.add("sample3"); 
     HogeData data = new HogeData(); 
     data.mList = list; 
     SampleFragment2 sampleFragment2 = new SampleFragment2(); 
     Bundle bundle = new Bundle(); 
     bundle.putParcelable(sampleFragment2.getClass().getCanonicalName(), data); 
     sampleFragment2.setArguments(bundle); 
     mActivity.replaceFragment(sampleFragment2); 
    } 
} 
} 

BFragment

public class SampleFragment2 extends Fragment { 

MainActivity mActivity; 
HogeData mData; 

@Override 
public void onAttach(Context context) { 
    super.onAttach(context); 
    mActivity = (MainActivity) context; 
} 

@Override 
public void onCreate(@Nullable final Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Bundle bundle = getArguments(); 
    mData = bundle.getParcelable(getClass().getCanonicalName()); 
} 

@Nullable 
@Override 
public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) { 
    return inflater.inflate(R.layout.sample2, container, false); 
} 

的問題是,當我通過從AFragment數據(邁德特)至BFragment,數組列表的(mList)參考是相同的。這導致當我改變BFragment中mList的值時,AFragment中mList的值也會改變。 我不知道要解決這個問題。

+1

您需要創建一個新的MyData作爲副本,並將其發送到BFragment – cokceken

回答

0
Fragment fragmentGet1 = new FragmentGet1(); 
Fragment fragmentGet2 = new FragmentGet2(); 
Fragment fragmentGet2 = new FragmentGet3(); 

fragmentGet1.setArguments(bundle); 
fragmentGet2.setArguments(bundle); 
fragmentGet3.setArguments(bundle); 

您可以創建所有3個碎片的實例,但只能使用FragmentGet1的實例。其他的不用。之後,當你創建這些碎片的任何一個的另一個實例時,它將不會有args,因爲它是一個完全獨立的對象。

您需要的是每次創建新片段時都向前傳遞包。如果你想從已創建的片段中創建它,它看起來有點像這樣:

public void showNextFragment() { 

    FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); 
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 

    Fragment fragmentGet2 = new FragmentGet2(); 

    if(this.getArguments() != null) 
     fragmentGet2.setArguments(this.getArguments()); 

    fragmentTransaction.replace(R.id.frame_container, fragmentGet2); 
    fragmentTransaction.addToBackStack(null); 
    fragmentTransaction.commit(); 

} 

要通過學生對象的活動,只是做這樣的事情:

Student s = //get it here 
Bundle b = new Bundle(); 
b.putParcelable("student", s); 

Intent i = new Intent(getActivity(), ThatOtherActivity.class); 
i.putExtra("extraWithStudent", b); 
startActivity(i); 

然後在活動中讀取數據:

Intent incomingIntent = getIntent(); 
Bundle b = incomingIntent.getBundleExtra("extraWithStudent"); 
Student s = (Student) b.getParcelable("student"); 
s 
2

從谷歌網站Developers

通常你會想要一個片段與另一個通信, 例如更改基於用戶事件的內容。全部 片段與片段之間的通信通過關聯的 活動完成。兩個碎片不應該直接通信。

一個好的做法是通過接口將數據發送到Activity。活動將接收數據,並且應該能夠通過方法將數據發送到第二個片段。

請閱讀thisthis