简体   繁体   中英

Get Value of different field in fragment from the parent Activity

I've an addActivity hosting 5 fragments, on each fragments I've some fields to fill.
I want to get the value of those fields from the addActivity . I tried something like that :
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 public class OtherFragment extends Fragment { Button 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;
    }
}

Updated
The problem that I get always EditText (and the others field to get ) equals to null If they are Located In the Fragment 1 or 2 or 3. Else I get The right Value

Hello Chlebta You need to set pager.setOffscreenPageLimit(5); . When you swipe between fragments the fragment can get destroy. that is why you getting null.

Alternatively an easy solution would be that you set

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

                }
            });

You could try to add a text changed listener to your edit text fields on each fragment and make a String field you set equal to the value of the edittext view when ever a user changes the text. Then save each instance of the fragment in your FragPagerAdapter and create a public method that will return all of the strings from each individual fragment in an array or how ever you want. Call that method from the Activity.

You are most likely experience this issue because you are not obtaining XML elements from the proper view or the view you are attempting to get data from gets destroyed before you attempt to access it.

However, I am not sure why exactly you are experiencing this issue but I do have a work-around solution do suggest:

Each time the user enters a field, you can store it in either SharedPreferences or a static class that will serve as a storage unit.

I am not sure how all the data is being inputed by the user but you can use different listeners (such as OnClickListener ) to track when the user inputs a certain data field.

Then you can store the data using one of the two approaches i just mentioned above. Here is an example of using a static storage class.

Somewhere in your application you make:

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

Then once the user, to use the example you have in the question, stops entering information into the EditText for dateFilled (they focus out of it), you store this information:

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();
    }
   }
});

You could also use some sort of a Button as the trigger to store information:

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

Then you can use the stored data like:

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

If you want to use SharedPreferences instead, here is a good example .

Do the following:

Create interface for communicating fragment to activity:

import android.widget.EditText;

public interface FormInterface {

    public void returnEditedEditText(EditText editText);

}

The create a base fragment that instantiates the interface and overrides method for communicating when the EditText has been modified. Make sure the Fragment also implements 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;
    }

 }

Then in make your other fragments extend the base fragment:

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

Then make sure your activity implements the custom interface:

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;
            ...
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM