将数据从片段传递到活动,然后传递到另一个片段

时间:2013-12-05 03:54:50

标签: android android-fragments android-fragmentactivity

我对片段通信很陌生,所以我真的需要你的帮助。我有一个片段活动和两个片段。

在我的片段A 中,我有一个 edittext (默认值为null),用户必须输入一个数字。因此,要捕获输入值,我使用addTextChangedListener执行此操作。捕获edittext的新值后, Fragment A 必须将该值(字符串)传递给容器活动,此活动现在已收到值(字符串)。此时此活动必须将值(字符串)传递给 Fragment B

到目前为止,这是我尝试过的

FragmentActivity:

  public String strDocNum;

  @Override
public void onDataPass(String data) {
    // TODO Auto-generated method stub
    Log.d("Document From", data);
    strDocNum = data;
}

片段A:

  OnDataPass dataPasser;

  private void getRecords() {
    // TODO getRecords

    // TODO To call methods from fragment to activity
    ((ReceivingStocks)getActivity()).dbConnect();

    strLastDocumentNumber = ((ReceivingStocks)getActivity()).dbHelper.getLastDocumentNumber();
    Log.d("Doc Num", "" + strLastDocumentNumber);
    etDocumentNumber.setText(strLastDocumentNumber);

    etDocumentFrom.addTextChangedListener(new TextWatcher() {
        @Override
        public void afterTextChanged(Editable s) {
            // TODO afterTextChanged

        }

        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            System.out.println("Before text changed " + new String(s.toString()));
        }

        public void onTextChanged(CharSequence s, int start, int before, int count) {

            System.out.println("Ontext changed " + new String(s.toString()));

            if(s.toString().isEmpty()){

            } else {
                strDocumentFrom = s.toString();
                strTransactionDate = 
                        ((ReceivingStocks)getActivity()).dbHelper.getTransactionDateByDocumentNumber(strDocumentFrom);
                strTotalAmount = 
                        ((ReceivingStocks)getActivity()).dbHelper.getTotalAmountByDocumentNumber(strDocumentFrom);
                strVan = 
                        ((ReceivingStocks)getActivity()).dbHelper.getVanByDocumentNumber(strDocumentFrom);

                etTransactionDate.setText(strTransactionDate);
                etTotalAmount.setText(strTotalAmount);
                Log.d("Van", "" + strVan);
                etVan.setText(strVan);

                // TODO TO PASS DATA FROM FRAGMENT TO ACTIVITY
                dataPasser.onDataPass(strDocumentFrom);

            }

        }     
    });
}


public interface OnDataPass {
    public void onDataPass(String data);
}

public void passData(String data) {
    dataPasser.onDataPass(data);
}

@Override
public void onAttach(Activity a) {
    super.onAttach(a);
    dataPasser = (OnDataPass) a;
}

片段B:

   private void getRecords() {
    // TODO getRecords

    // TODO To call methods from fragment to activity
    ((ReceivingStocks)getActivity()).dbConnect();
    String mLabel = ((ReceivingStocks)getActivity()).strDocNum;
    Log.d("Document Number From Header", "" + mLabel);
    strUnitOfMeasure = ((ReceivingStocks)getActivity()).dbHelper.getUnitOfMeasureByDocumentNumber(mLabel);
    strQTY = ((ReceivingStocks)getActivity()).dbHelper.getQTYByDocumentNumber(mLabel);
    strUnitPrice = ((ReceivingStocks)getActivity()).dbHelper.getUnitPriceByDocumentNumber(mLabel);
    strAmount = ((ReceivingStocks)getActivity()).dbHelper.getAmountByDocumentNumber(mLabel);

    try{

        if(mLabel.isEmpty()){

        } else {
            String str = ((ReceivingStocks)getActivity()).dbHelper.getItemCodeByDocumentNumber(mLabel);
            Log.d("Item Code", "" + str);
            etItemCode.setText(str);
            etUnitOfMeasure.setText(strUnitOfMeasure);
            etQuantity.setText(strQTY);
            etUnitPrice.setText(strUnitPrice);
            etAmount.setText(strAmount);
        } 


    } catch(SQLiteException e){
        Log.d("Error", "" + e);
    }


}

到目前为止,我已成功将数据从 Fragment A 传递到Activity。但是从Activity到 Fragment B ,它传递的是默认值null,因此我的logcat会抛出NullPointerException。有任何想法吗?我真的迷失了。我真的很感激你的帮助。感谢。

5 个答案:

答案 0 :(得分:1)

如果您的要求是将值从一个片段传递到另一个片段,请尝试使用bundle

例如:

TalkDetail fragment = new TalkDetail();
                        Bundle bundle = new Bundle();

                        bundle.putString("title", title);
                        bundle.putString("largeimg", largeimg);
                        bundle.putString("excert", excert);
                        bundle.putString("description",description);
                        bundle.putString("cat", cat);
                        bundle.putString("header_title", "Talk");
                        //bundle.putInt("postid", postid);

                        fragment.setArguments(bundle);
                        ((BaseContainerFragment)getParentFragment()).replaceFragment(fragment, true);

这是你的BaseContainerFragment.java类,它将有助于获得更好的回溯和其他好东西

public class BaseContainerFragment extends Fragment {

    public void replaceFragment(Fragment fragment, boolean addToBackStack) {
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        if (addToBackStack) {
            transaction.addToBackStack(null);
        }
        transaction.replace(R.id.container_framelayout, fragment);
        transaction.commit();
        getChildFragmentManager().executePendingTransactions();
    }

    public boolean popFragment() {
        Log.e("test", "pop fragment: " + getChildFragmentManager().getBackStackEntryCount());
        boolean isPop = false;
        if (getChildFragmentManager().getBackStackEntryCount() > 0) {
            isPop = true;
            getChildFragmentManager().popBackStack();
        }
        return isPop;
    }

}

答案 1 :(得分:0)

我建议你看一下这篇文章:http://www.vogella.com/articles/AndroidFragments/article.html

它解释了如何使用Listener模式将数据从片段传递到活动以及如何将数据从活动传递到另一个片段。

根据您的描述和本文,您的代码应如下所示:

FragmentB fragment = (FragmentB) getFragmentManager().findFragmentById(R.id.fragmentb);
if (fragment != null && fragment.isInLayout()) {
    fragment.passData(data);
} 

答案 2 :(得分:0)

试试这个:

public class FragmentA extends Fragment{
private Callbacks mCallbacks = sCallbacks;

public interface Callbacks {
    public void onSelected();//Add arguments if you wants
}

private static Callbacks sCallbacks = new Callbacks() {
    @Override
    public void onSelected() {
    }
};

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.your_fragment_layout,container, false);
    Button btn=(Button)rootView.findViewById(R.id.btn);
    btn.setOnClickListener(new OnClickListenet{
        public void onClick(View v){
            mCallbacks.onSelected()
        }
    });
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    if (!(activity instanceof Callbacks)) {
        throw new IllegalStateException(
                "Activity must implement fragment's callbacks.");
    }

    mCallbacks = (Callbacks) activity;
}

@Override
public void onDetach() {
    super.onDetach();
    mCallbacks = sCallbacks;
}

}

public class YourFragmentActivity extends FragmentActivity 
implements FragmentA.Callbacks{
FragmentB fragB;

    @Override
    public void onSelected() {
    // Handle fragmentA's btn click event here
    // you can call any function of fragmentB using its instance 'fragB'
    }

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_screen);
    FragmentTransaction ft =getSupportFragmentManager().beginTransaction();
    fragB = new FragmentB();
    /* //Pass values to FragmentB
    Bundle arguments = new Bundle();
    arguments.putSString("MyString", "your string comes here");
    fragB.setArguments(arguments); 
    */
    ft.replace(R.id.fragB_container, fragB).commit();
}       

}

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_alignParentLeft="true"
    android:baselineAligned="false" >

     <FrameLayout
        android:id="@+id/fragA_container"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <FrameLayout
        android:id="@+id/fragB_container"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />
</LinearLayout>

答案 3 :(得分:0)

在片段中定义一个接口,让您的活动实现该接口,并从您的片段调用这些接口方法,以将数据传递给活动。

从活动中调用片段的公共方法,将数据传递给该片段。

两个片段不应该直接通信。

这里详细解释:http://developer.android.com/training/basics/fragments/communicating.html

答案 4 :(得分:0)

在Fragment to Fragment之间传输数据的智能方法是通过Interface。这里片段不能直接相互通信。但你可以通过Activity来做到这一点。活动将扮演中间人的角色。

在这种情况下,您需要两个界面。 Activity的一个界面和FragmentB的另一个界面。

FragmentA通过Activity Interface将EditTextValue发送到Activity,获取此值后,Activity将使用FragmentB接口将该值传递给FragmentB。

以下是示例代码:

Activity将实现此接口:

public interface IActivityTest {
    public void getValueFromFragmentA(String value);
}

FragmentB将实现此接口:

 public interface IFragmentB {
    public void getValueFromEditTextInFragmentA(String value);
    } 

在FragmentA中更改edittext值后,它将调用此活动getValueFromFragmentA方法。

(IActivityTest)getActivity()).getValueFromFragmentA("YOUR_EDITTEXT_NEW_VALUE");

获取此值后,Activity将使用以下方式将此值传递给FragmentB-- 之后,Activity将在此处获取此EditText值

@Override
public void getValueFromFragmentA(String value) {

    YourFragmentBInstance.getValueFromEditTextInFragmentA(value);
}

现在这个值将在这个方法中传递给FragmentB:

@Override
public void getValueFromEditTextInFragmentA(String value){
 // Here value is your desired value.
}

我的答案中的完整源代码和相关答案为here

谢谢:)