从父Activity获取片段中不同字段的Value



我有一个承载5个片段的addActivity,在每个片段上我都有一些字段要填充
我想从addActivity中获取这些字段的值。我试过这样的方法:
AddActivity.java

public class AddActivity extends FragmentActivity {
    ViewPager vp;
    ProgressDialog dialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add);
        vp = (ViewPager) findViewById(R.id.pager);
        PagerAdapter pa = new FragPagerAdapter(getSupportFragmentManager());
        vp.setAdapter(pa);}
    public class getValueOfFields() {
  //here I'm trying to get the value of differents fields in the different fragments but I get 
always "editText == Null" If the editText is in The fragment 1 or 2 or 3 it will get null
     EditText editTextFromFrag1 = (EditText) findViewById(R.id.visitDateFiled); // this == null
// If the EditText is in Fragment 4 or 5 it will get the value normaly without any issue

             ...}

FragPagerAdapter.java

public class FragPagerAdapter extends FragmentPagerAdapter {
    public FragPagerAdapter(FragmentManager fm) {
        super(fm);}
    @Override
    public Fragment getItem(int index) {
        switch (index) {
            case 0:
                return new FirstFragment();
            case 1:
                return new SecondFragment();
            case 2:
                return new HousingFragment();
            case 3:
                return new FeedingFragment();
            case 4:
                return new OtherFragment();
        }
        return null;
    }
    @Override
    public int getCount() {
        return 5; }

OtherFragment.java公共类OtherFragment扩展Fragment{按钮btn;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_other, container, false);
    btn = (Button) view.findViewById(R.id.send);
    btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
//Call the getValueOfFields (After filling the differnts fields the user click the send button) 
                ((AddActivity) getActivity()).getValueOfFields();
            }
        });
        return view;
    }
}

更新
如果它们位于片段1、2或3中,那么我得到的问题总是EditText(以及要得到的其他字段)等于null。否则我会得到正确的值

你好,Chlebta你需要设置pager.setOffscreenPageLimit(5);。当你在碎片之间滑动时,碎片可能会被摧毁。这就是为什么你会变成null。

或者,一个简单的解决方案是设置

pager.setOnPageChangeListener(new OnPageChangeListener() {
                @Override
                public void onPageSelected(int arg0) {
                    // Now here you get your fragment object. 
                   // To get the Fragment Object you need to store them in an ArrayList in your FragPagerAdapter class.
                  //  create a method `getMyFraggment ` which return your Fragment from Arraylist.
                 //   Now create a method in your each Fragment which return your EditText values. Here you can use HashMap to store the values.
                // Here you use switch cases to get your Fragment Object I just wrote 1 here                        
                MyFragment f =  ((FragPagerAdapter)pager.getAdapter()).getMyFraggment(arg0);
                HashMap <String, String> hashMap = f.getValuesFromFragment();
                myValues.putAll(hashMap);    // myValues is global hashmap in your Activity. 
               // Now you get All values in your Global HashMap. But remember here you can get duplicate values if user swipe a fragment more than 1 time. You should do a logic here to remove duplicate values.
                }
                @Override
                public void onPageScrolled(int arg0, float arg1, int arg2) {
                    // TODO Auto-generated method stub
                }
                @Override
                public void onPageScrollStateChanged(int arg0) {
                    // TODO Auto-generated method stub
                }
            });

您可以尝试在每个片段的编辑文本字段中添加一个文本更改侦听器,并在用户更改文本时使您设置的String字段等于edittext视图的值。然后将片段的每个实例保存在FragPagerAdapter中,并创建一个公共方法,该方法将返回数组中每个片段的所有字符串,或者按您的意愿返回。从"活动"中调用该方法。

您很可能会遇到此问题,因为您没有从正确的视图中获取XML元素,或者您试图从中获取数据的视图在尝试访问之前就被破坏了。

然而,我不确定为什么你会遇到这个问题,但我确实有一个变通的解决方案,建议:

每次用户输入字段时,都可以将其存储在SharedPreferences或用作存储单元的static类中。

我不确定用户是如何输入所有数据的,但您可以使用不同的侦听器(如OnClickListener)来跟踪用户何时输入某个数据字段。

然后,您可以使用我上面提到的两种方法之一来存储数据。以下是使用static存储类的示例。

在您的应用程序中的某个位置:

class Storage {
    public static String dateFilled;
    // ... rest of your data
}

然后,使用您在问题中的示例,一旦用户停止在EditText中输入dateFilled的信息(他们将焦点放在它之外),就可以存储以下信息:

editText.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
    if(hasFocus){
        // user is still typing so we do nothing
    }else {
        // user finished typing and moved on so we store the data
        Storage.dateFilled = editText.getText().toString();
    }
   }
});

您也可以使用某种Button作为触发器来存储信息:

myBtn.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        Storage.dateFilled = editText.getText().toString(); 
    }
}

然后您可以使用存储的数据,如:

public class getValueOfFields() {
    Toast.makeText(getApplicationContext(), Storage.dateFilled, Toast.LENGTH_LONG);
    // ...
}

如果您想使用SharedPreferences,这里有一个很好的例子。

执行以下操作:

创建用于将片段通信到活动的接口:

import android.widget.EditText;
public interface FormInterface {
    public void returnEditedEditText(EditText editText);
}

创建一个基本片段,该片段实例化接口并在修改EditText时重写用于通信的方法。确保Fragment还实现了OnEditorActionListener:

import android.app.Activity;
import android.app.Fragment;
import android.util.Log;
import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
public class FormFragment extends Fragment implements OnEditorActionListener {
    protected final String FRAGMENT_NAME = getClass().getName();
    protected FormInterface formInterface;
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        //ensure activity implements interface
        try {
            formInterface = (FormInterface) activity;
        } catch (ClassCastException ex) {
            String errorString = activity.toString() + " must implement FormInterface";
            Log.e(FRAGMENT_NAME, errorString);
            throw new ClassCastException(errorString);
        }
    }
    @Override
    public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
        if(actionId == EditorInfo.IME_ACTION_DONE)
            formInterface.returnEditedEditText((EditText) view);
        return true;
    }
 }

然后在使你的其他片段扩展基础片段:

YOURFRAGMENT extends FormFragment {
    //FOR EACH EDIT TEXT DO THE FOLLOWING
    EDITTEXT.setOnEditorActionListener(this);
}

然后确保您的活动实现了自定义界面:

import android.app.Activity;
import android.widget.EditText;
public class FormActivity extends Activity implements FormInterface {
    @Override
    public void returnEditedEditText(EditText editText) {
        String input = editText.getEditableText().toString();
        switch(editText.getId()) {
            case R.id.editText_FirstName:
                mFirstName = input;
                break;
            ...
        }
    }
}

最新更新