Get data from EditText from Fragment to Activity - java

I need to pass String data from EditTexts from Fragment to Activity, I know that I have to use interface. But I still have the same error (Null Object). Can you tell me how to fix it? Here is my code:
Main Activity
public class IntroActivity extends AppCompatActivity implements fragment_intro_activity_2.OnDataPass {
Button button_intro;
EditText et;
boolean showingFirst;
String wynik;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_intro);
button_intro = findViewById(R.id.button_intro);
et = findViewById(R.id.edOperetka);
FullScreencall();
getSupportFragmentManager().beginTransaction().replace(R.id.frame_contrainer_intro,
new fragment_intro_activity_1()).commit();
showingFirst = true;
button_intro.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(showingFirst==true){
getSupportFragmentManager().beginTransaction().replace(R.id.frame_contrainer_intro,
new fragment_intro_activity_2()).commit();
showingFirst = false;
}else {
//
// Toast.makeText(IntroActivity.this, "123123", Toast.LENGTH_SHORT).show();
wynik = et.getText().toString();
onDataPass(wynik);
}
}
});
}
Fragment
public class fragment_intro_activity_2 extends Fragment {
View v;
OnDataPass dataPasser;
public fragment_intro_activity_2() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
v = inflater.inflate(R.layout.fragment_fragment_intro_activity_2, container, false);
return v;
}
public interface OnDataPass {
void onDataPass(String data);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
dataPasser = (OnDataPass) context;
}
public void passData(String data) {
dataPasser.onDataPass(data);
}
}
Logcat
Process: com.example.wynagrodzeniedodatkowe, PID: 32263
java.lang.NullPointerException: Attempt to invoke virtual method 'android.text.Editable android.widget.EditText.getText()' on a null object reference
at com.example.wynagrodzeniedodatkowe.IntroActivity$1.onClick(IntroActivity.java:54
And this 54 line is this: wynik = et.getText().toString();

Looking at the logcat message, it tells me that the following line
findViewById(R.id.edOperetka)
Returns null so make sure that the ID is created correctly in the XML and references correctly from the code (that it's the same ID).
If you wan't to retrieve the EditText inside your fragment you can do the following.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
v = inflater.inflate(R.layout.fragment_fragment_intro_activity_2, container, false);
EditText et = v.findViewById(R.id.edOperetka);
return v;
}
Now you can retrieve the text from as you did before.

Related

Change the fragment to another fragment within a setOnclick

I have a simple block code and i wish pass this fragment to another fragment with a click in a button.
If anyone could help me I would appreciate it
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_inicio,container,false);
linearLayout = view.findViewById(R.id.clientea);
linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(),"Teste",Toast.LENGTH_SHORT).show();
}
});
return view;
}
I will show a simple way with code.
There are one Activity and two Fragments in the code.
First , the MainActivity contains the FragmentOne.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().beginTransaction().add(R.id.container, new FragmentOne(), "")
.addToBackStack(null)
.commit();
}}
Then FragmentOne, there is a button in it, which will jump FragmentTwo when click.
public class FragmentOne extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_one, container, false);
Button btnClick = view.findViewById(R.id.btn);
btnClick.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.container, new FragmentTwo())
.addToBackStack(null)
.commit();
}
});
return view;
}}
The last is the FragmentTwo:
public class FragmentTwo extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_two, container, false);
return view;
}
}
I could give the xml if you want.
From my experience with Android development, the approach that is taken to this problem is to create a functional interface, implement the interface in the Activity that the fragments are managed by and then do the fragment swapping inside the method provided by the interface.
So first create an interface, let's call it IFragmentToSwap.
public interface IFragmentToSwap{
void OnButtonClicked();
}
Then in the Activity that controls fragment transactions you need to implement this interface.
public class MainActivity extends AppCompatActivity implements IFragmentToSwap {
#Override
public void OnButtonClicked()
{
//Swap fragment here
}
}
Now in your fragment in the OnAttach override method you should do the following:
private IFragmentToSwap mListener;
#Override
public void onAttach(Context context)
{
super.onAttach(context);
if (context instanceof IFragmentToSwap)
{
mListener = (MainActivity) context;
}
else
{
throw new RuntimeException(context.toString()
+ " must implement IFragmentToSwap");
}
}
And in the method you provided that is contained inside your fragment you would call the method on the functional interface when a click happens, like this:
#Override
public View onCreateView(final LayoutInflater inflater, final
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_inicio,container,false);
linearLayout = view.findViewById(R.id.clientea);
linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mListener.OnButtonClicked();
Toast.makeText(getActivity(),"Teste",Toast.LENGTH_SHORT).show();
}
});
return view;
}
And don't forget to detach the listener in the OnDetach override:
public void onDetach()
{
super.onDetach();
mListener = null;
}
This is the most common approach I have seen to swapping fragments on Android.

First Click in button does not get the text in the EditText object

The problem is that when i click in the button the first time no text is in the EditText object, in the second click it works but does not replace the frame.
I Have one activity with a container for a fragment that has a editText and a button, when click the button i replace the fragment in the container with another fragment to display the text in the edit text.
I'm following this tutorial:
https://www.youtube.com/watch?v=OLbsiE42JvE&list=PLshdtb5UWjSrOJfpFOE-u55s3SnY2EO9v&index=14
i'm in video "Android tutorial (2018) - 14 - Fragment to Fragment Communication".
The diference from this tutorial from my app is that my activity is the third in the same project, and i'm working in that activity as it was my main.
public class FinalActivity extends AppCompatActivity implements HeadLineFragment.OnMessageListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_final);
if(findViewById(R.id.final_activity_fragment)!= null) {
if (savedInstanceState != null) {
return;
}
HeadLineFragment headLineFragment = new HeadLineFragment();
getSupportFragmentManager().beginTransaction().add(R.id.final_activity_fragment, headLineFragment, null).commit();
}
}
#Override
public void onMessageSend(String message) {
ArticleFragment articleFragment = new ArticleFragment();
Bundle bundle = new Bundle();
bundle.putString("message",message);
articleFragment.setArguments(bundle);
getSupportFragmentManager().beginTransaction().replace(R.id.final_activity_fragment, articleFragment,null).addToBackStack(null).commit();
}
}
public class HeadLineFragment extends Fragment {
OnMessageListener onMessageListener;
private Button button;
private EditText editText;
public interface OnMessageListener{
public void onMessageSend(String message);
}
public HeadLineFragment(){
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.headline_fragment, container, false);
button = view.findViewById(R.id.bfrag);
editText = view.findViewById(R.id.editText21);
button.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
String message = editText.getText().toString();
String s = editText.getText().toString();
onMessageListener.onMessageSend(message);
}
});
return view;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
Activity activity = (Activity) context;
try {
onMessageListener = (OnMessageListener) activity;
}catch (ClassCastException e){
throw new ClassCastException(activity.toString() + " must implement OnMessageListener....");
}
}
#Override
public void onResume() {
super.onResume();
editText.setText("");
}
}
public class ArticleFragment extends Fragment {
private TextView textView;
public ArticleFragment(){}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(
R.layout.article_fragment,container, false);
textView = view.findViewById(R.id.txt_message_display);
Bundle bundle = getArguments();
String message = bundle.getString("message");
textView.setText(message);
return view;
}
}
I expect that the functionality has the same behavior as in the video of the tutorial
I eventually solved my own problem, the layout of the Activity had a fragment instead of a frame layout. By changing that the problem was solved.

communication between two fragments . I am not using any already defined view for any of the fragments. I am just adding fragments at runtime

I have two fragments MyFragment and MyFragment2 , an interface defined within MyFragment2.
code for MyFragment2:
public class MyFragment2 extends android.support.v4.app.Fragment implements View.OnClickListener {
public interface MyInterface2
{
public void respond(String s);
}
EditText editText;
Button sendData;
MyInterface2 comm;
View v=getView();
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
v = inflater.inflate(R.layout.my_fragment_2,container,false);
return v;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
this.comm = (MyInterface2)getActivity();
editText = (EditText)getActivity().findViewById(R.id.text);
sendData =(Button)getActivity().findViewById(R.id.sendData);
sendData.setOnClickListener(this);
}
#Override
public void onClick(View v) {
try {
String s = editText.getText().toString();
comm.respond(s);
}
catch(Exception e)
{
Toast.makeText(getActivity(),"error:"+e,Toast.LENGTH_LONG).show();
}
}
}
I am trying to send the content of editText from MyFragment2 to the fragment MyFragment by pressing the button (Myfragment2 initially set on the main activity's view using the Java code)
The main activity's code is as follows*(my_layout is the id of layout in which I am putting the fragments)*:
public class MainActivity extends AppCompatActivity implements MyFragment2.MyInterface2 {
//String data;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyFragment2 fragment2= new MyFragment2();
FragmentManager fManager= getSupportFragmentManager();
FragmentTransaction transaction= fManager.beginTransaction();
transaction.add(R.id.my_layout,fragment2,"MyFragment2");
transaction.commit();
}
public void respond(String s)
{
MyFragment fragment = new MyFragment();
FragmentManager fManager =getSupportFragmentManager();
FragmentTransaction transaction = fManager.beginTransaction();
transaction.replace(R.id.my_layout,fragment);
transaction.commit();
fragment.getData(s);
}
}
when I click the sendData button in fragment MyFragment2 , MyFragment2 gets replaced with fragment Myfragment but no data change occurs in the MyFragmnet's textView and an error is also shown which I have catched in a try catch block from fragment MyFragment2(here is the image for that).
code for MyFragment :
public class MyFragment extends android.support.v4.app.Fragment {
TextView textView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v= inflater.inflate(R.layout.my_fragment,container,false);
//textView =(TextView)v.findViewById(R.id.getText);
return v;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
textView =(TextView)getActivity().findViewById(R.id.getText);
}
public void getData(String data)
{
textView.setText(data);
}
}
You can easily pass data between fragments using a callback or passing the arguments via a bundle.
Check out this article:
https://developer.android.com/training/basics/fragments/communicating.html
onActivityCreated is no need. Uncomment ur text view initiation statement in onCreateView block.
Ensure you have text view in your respective layout file with same id you have passed

How can I find the null pointer error in this Android Code involving Fragments

I have been trying for 2 hours now to find the null pointer in my code and am having no luck. I am hoping one of you far smarter individuals than I can figure it out. First off, I am following the tutorial here: http://youtu.be/Y2liEQV3tbQ?list=PLonJJ3BVjZW4lMlpHgL7UNQSGMERcDzHo by slideNerd.
Here is what is baffling me: When in horizontal mode, the code executes perfectly and the displays are updated with correct information. This means that the horizontal portion of the if statement is working. When it is in portrait however and I click a list view icon, it immediately force closes with null pointer. The error comes from the line that reads:
f2b.changeTextView(index);
If I remove that line, the second activity opens without a problem. I am simply at a loss as to what has been causing me so much trouble.
Here are my classes:
MainActivity:
public class MainActivity extends Activity implements FragmentA.Communicator{
private FragmentA f1a;
private FragmentB f2b;
private FragmentManager manager;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
manager=getFragmentManager();
f1a = (FragmentA) manager.findFragmentById(R.id.fragment1a);
f1a.setCommunicator(this); //the respond method that is implemented from Fragment a
f2b = (FragmentB) manager.findFragmentById(R.id.fragment2b);
}
#Override
public void respond(int index) {
//Check if portrait mode
if (f2b != null && f2b.isVisible()){ //Horizontal
f2b.changeTextView(index);
} else { //Vertical
Intent intent = new Intent(this, Activity2.class);
intent.putExtra("index", index);
startActivity(intent);
}
}
}
Fragment A:
public class FragmentA extends Fragment implements AdapterView.OnItemClickListener {
ListView listView;
Communicator comm;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a, container, false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
listView = (ListView) getActivity().findViewById(R.id.fragment_a_list_view);
ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(), R.array.chapters, android.R.layout.simple_list_item_1);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
comm.respond(position);
}
public void setCommunicator(Communicator communicator){
this.comm = communicator;
}
//Interface to allow access between fragments
public interface Communicator{
public void respond(int index);
}
}
Fragment B:
public class FragmentB extends Fragment {
TextView textView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_b, container, false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
textView = (TextView) getActivity().findViewById(R.id.fragment_b_text_view);
}
public void changeTextView(int position){
String [] descriptions = getResources().getStringArray(R.array.descriptions);
textView.setText(descriptions[position]);
}
}
Activity2:
public class Activity2 extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity2);
Intent intent = getIntent();
int index = intent.getIntExtra("index", 0);
//reference the fragment
FragmentB f2b = (FragmentB) getFragmentManager().findFragmentById(R.id.fragment2b);
if (f2b != null){
f2b.changeTextView(index);
}
}
}
And Here is the error code in the logcat:
Caused by: java.lang.NullPointerException
at com.pgmacdesign.fragmentexamples3_flexibleui.FragmentB.changeTextView(FragmentB.java:42)
at com.pgmacdesign.fragmentexamples3_flexibleui.Activity2.onCreate(Activity2.java:25)
I have already confirmed that the index/ position variable is passing correctly. If anyone has any suggestions as to how to find the null pointer error, I would love the assistance.
In your Fragment B,
Try to replace textView = (TextView) getActivity().findViewById(R.id.fragment_b_text_view) by textView = (TextView) view.findViewById(R.id.fragment_b_text_view) and move it from onActivityCreated() to onCreateView().
Hope this helps.
I think your problem is when you can try to find the ID.
Try this textView = (TextView) view.findViewById(R.id.fragment_b_texT_view) where this view is your View view = inflater.inflate(R.layout.fragment_b, container, false);.

communicating between fragments when only one of them is visible

I have a problem with comuunicating between fragments that are chnged dynamicaly, i mannaged to use the interface system to cimmunicate if the fragments are all viewble but when i am viewing them sepretly i can't use a their actions since they dont have a tag yet, any thoughts?
main activty
public class MainActivity extends FragmentActivity implements OnClickListener, Communicator {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (isSingleFragment()) {
Button btn_color = (Button) findViewById(R.id.button_color);
Button btn_text = (Button) findViewById(R.id.button_text);
Button btn_list = (Button) findViewById(R.id.button_list);
btn_color.setOnClickListener(this);
btn_list.setOnClickListener(this);
btn_text.setOnClickListener(this);
singleFragActions();
} else {
doubleFragActions();
}
// some more stuff happens
#Override
public void apply(String data) {
Log.d("data", data+"");
FragmentManager fm = getSupportFragmentManager();
Frag_list frag_list = (Frag_list) fm.findFragmentByTag("list");
//i cannot use id because the fragment in
//MainActivity are in a layout and are enterd dynamicaly
frag_list.addItem(data);
}
three fragments here, when on small screen, on is shown and three button on the top change them arrounf, if on tablet, all three are displyed, this is the interface
public interface Communicator {
public void apply(String data);
}
frag_text (first fragment)
public class Frag_text extends Fragment implements OnClickListener{
Communicator comm;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// stuff
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
comm = (Communicator) getActivity();
}
#Override
public void onClick(View v) {
EditText input = (EditText) getView().findViewById(R.id.frag_text_edit);
TextView output = (TextView) getView().findViewById(R.id.frag_text_show);
String text_get = input.getText().toString();
output.setText("hello "+text_get+" how are you today?");
comm.apply(text_get);
}
}
frag_list (other fragment)
public class Frag_list extends Fragment{
ArrayList<String> list;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_list, container, false);
list = new ArrayList<String>();
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, list);
ListView lv = (ListView) view.findViewById(R.id.list_frag);
lv.setAdapter(adapter);
return view;
}
public void addItem(String data){
list.add(data);
}
}
how to i access the other fragment if it doesnt have a tag yet?
If you happen to know what fragment you will be calling then FragmentActivity could act as a mediator in this case, as it is a mere "host". You already have this Communicator interface. Have it communicate to a given fragment:
public interface Communicator {
public void apply(String data, String tag);
}
And the override:
#Override
public void apply(String data, String tag) {
FragmentManager fm = getSupportFragmentManager();
Frag_list frag_list = (Frag_list) fm.findFragmentByTag(tag);
//Fallback plan in case the fragment has not been created.
if(frag_list == null) {
frag_list = new Frag_list();
//Include the fragment for future reference.
//This fragment has no view
fm.beginTransaction().add(frag_list, tag);
}
frag_list.addItem(data);
}
And modify the fragment to always have the list available:
public class Frag_list extends Fragment{
ArrayList<String> list = new ArrayList<String>();
//...
public void addItem(String data){
//Add check to avoid problems
if(list != null) {
list.add(data);
}
}
}

Categories