Java 从父活动获取片段中不同字段的值
我有一个Java 从父活动获取片段中不同字段的值,java,android,android-fragments,Java,Android,Android Fragments,我有一个addActivity托管了5个片段,每个片段上都有一些字段要填充。我想从addActivity获取这些字段的值。我试过这样的方法: AddActivity.java public class AddActivity extends FragmentActivity { ViewPager vp; ProgressDialog dialog; @Override protected void onCreate(Bundle savedInstanceSt
addActivity
托管了5个片段,每个片段上都有一些字段要填充。我想从
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
...}
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; }
FragpageAdapter.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
...}
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扩展了片段{
按钮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。
否则我会得到正确的值您可以尝试在每个片段的编辑文本字段中添加一个文本更改侦听器,并在用户更改文本时使您设置的字符串字段等于edittext视图的值。然后将片段的每个实例保存在FragpageAdapter中,并创建一个公共方法,该方法将返回所有从数组中的每个片段或您想要的方式调用。从“活动”调用该方法。您很可能遇到此问题,因为您没有从正确的视图中获取XML元素,或者您试图从中获取数据的视图在尝试访问它之前被破坏 但是,我不确定您遇到此问题的确切原因,但我有一个解决方案,建议: 每次用户输入字段时,您都可以将其存储在一个或一个
静态
类中,该类将用作存储单元
我不确定用户是如何输入所有数据的,但您可以使用不同的侦听器(例如OnClickListener
)来跟踪用户何时输入某个数据字段
然后您可以使用我刚才提到的两种方法之一来存储数据
您在应用程序中的某个地方:
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();
}
}
});
myBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Storage.dateFilled = editText.getText().toString();
}
}
您还可以使用某种类型的按钮
作为存储信息的触发器:
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();
}
}
});
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);
// ...
}
如果您想使用共享引用
,.请执行以下操作:
创建用于将片段与活动进行通信的接口:
import android.widget.EditText;
public interface FormInterface {
public void returnEditedEditText(EditText editText);
}
创建一个基本片段,该片段实例化接口,并在修改EditText时重写用于通信的方法。请确保该片段还实现了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;
...
}
}
}
您好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
}
});
pager.setOnPageChangeListener(新的OnPageChangeListener(){
@凌驾
已选择页面上的公共无效(int arg0){
//现在你得到你的碎片对象。
//要获取片段对象,需要将它们存储在FragPagerAdapter类的ArrayList中。
//创建一个“getMyFraggment”方法,该方法从Arraylist返回片段。
//现在在每个片段中创建一个返回EditText值的方法。在这里,您可以使用HashMap存储值。
//在这里,您使用switch cases来获取片段对象,我刚才在这里写了1
MyFragment f=((FragPagerAdapter)pager.getAdapter()).getMyFragment(arg0);
HashMap HashMap=f.getValuesFromFragment();
myValues.putAll(hashMap);//myValues是活动中的全局hashMap。
//现在,您可以在全局HashMap中获得所有值。但请记住,如果用户滑动片段超过1次,您可以获得重复值。您应该在此处执行逻辑以删除重复值。
}
@凌驾
已滚动页面上的公共void(int arg0、float arg1、int arg2){
//TODO自动生成的方法存根
}
@凌驾
公共无效onPageScrollStateChanged(int arg0){
//TODO自动生成的方法存根
}
});
在哪里调用getValueOfFields()
?在最后一个片段中,我有一个发送按钮(在不同片段中填充不同字段后,用户有一个发送按钮),它调用getValueOfFields()父活动的void
,以及EditText
Activity
或特定的Fragment
?EditText的XML代码在片段XML文件中,但EditText EditText=(EditText)findViewById(R.id.visitDateField);
在活动中它没有真正的帮助,因为我有超过30个字段。我认为问题是每次都要创建片段的新实例,所以一旦您获得项目,它就是一个新实例,而不是原始实例(已填写)一向FragmentPagerAdapter添加一个片段数组字段。在FragmentPagerAdapter的构造函数中,为片段数组提供每个片段的一个新实例。然后在获取项中返回fragmentArray[索引]不是一个新的片段,甚至使用array one,我得到了我必须使用新实例的项目!!你能举个例子吗?我已经更新了我的问题,你能再次检查一下吗?使用listener并不是很有帮助,因为我有30多个字段需要设置,如果你有一个特定的用户输入顺序,它会减慢我的应用程序的速度如果没有这些信息,那么每个XML元素类型只能有一个侦听器(1L