Android - Calling a function from a fragment - java

I'm trying to make a tabbed activity with 3 fragments. One of my fragments has got a button with is calling a function onClick:
<Button
android:text="Start meeting"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="58dp"
android:id="#+id/sp_live_meeting"
android:layout_below="#+id/live_cost"
android:layout_centerHorizontal="true"
android:onClick="sp_timer" />
The fragment is created in the coresponding class file:
public class LiveMeeting_meeting_fragment extends Fragment {
Button sp;
Button stop;
Chronometer chrono;
int cnt = 0;
long timeStop;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.livemeeting_meeting_fragment, container, false);
sp = (Button) rootView.findViewById(R.id.sp_live_meeting);
stop = (Button) rootView.findViewById(R.id.stop_live_meeting);
chrono = (Chronometer) rootView.findViewById(R.id.live_timer);
return rootView;
}
public void sp_timer(View view){
if(cnt == 0){
sp.setText("Pause meeting");
chrono.setBase(SystemClock.elapsedRealtime() + timeStop);
chrono.start();
cnt = 1;
} else if (cnt == 1){
sp.setText("Continue meeting");
chrono.stop();
timeStop = chrono.getBase() - SystemClock.elapsedRealtime();
cnt = 0;
}
}
}
My problem is now, that I'm not able to call the function because it's telling me that it can't find the function:
java.lang.IllegalStateException: Could not find method sp_timer(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'sp_live_meeting'
How can I solve this?

Delete your onClick attribute from XML and instead use onClickListener.
Code:
Button btn = (Button) findViewById(R.id.mybutton);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//write your sp_timer method here
}
});
Android looks for the onClick method sp_timer() only in the current Activity. This is important to remember if you are using fragments, since even if you add the XML above using a fragment, Android will not look for the onClick method in the .java file of the fragment used to add the XML.

Related

References in code moved from Activity to Fragment no longer resolve

I'm quite new working with Android/Java, so please bear with me.
I moved code from LoginActivity > onCreate into a fragment I created FragmentLogin to method onCreate where many classes no longer resolve, such as findViewById. I'm assuming that somewhere I didn't pass the context of the container Activity properly.
Or some other newbie mistake...
Here is LoginActivity.java [relevant parts copied]
public class LoginActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initialize Fragments //
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
setContentView(R.layout.fragment_login);
}
}
and FragmentLogin.java:
public class FragmentLogin extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_login, container, false);
final ValidationManager Check = new ValidationManager();
final SessionManager Session = new SessionManager(this);
final EditText textEmail = (EditText) findViewById(R.id.login_email);
final EditText textPassword = (EditText) findViewById(R.id.login_pass);
final Button buttonLogIn = (Button) findViewById(R.id.button_login);
final Button buttonSignup = (Button) findViewById(R.id.button_signup);
// Listen for FORGOTTEN PASSWORD click event, open ForgottenPassword Fragment //
final Button forgottenPassword = (Button) findViewById(R.id.button_lost_pass);
forgottenPassword.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setContentView(R.layout.fragment_forgotten_password);
}
});
... more code ...
}
}
The variables/methods that were working when the second block of code was residing in the onCreate method of the Activity but no longer resolve after I moved the code to onCreateView of the FragmentLogin fragment class:
findViewById, setContentView
Basically, this is a login form where the default fragment should be login, and a button on that page (Button forgottenPassword) would open another fragment (FragmentForgottenPassword).
Can anyone tell me what I'm doing wrong?
In your activity layout xml file, add something similar to this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment android:name="your.package.FragmentLogin"
android:id="#+id/fragment_login"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
In your LoginActivity: remove the fragment manager stuff. You don't need it yet.
public class LoginActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_login);
}
}
In your FragmentLogin, move the return statement to the end and use the inflated view to find your views by id:
public class FragmentLogin extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final view view = inflater.inflate(R.layout.fragment_login, container, false);
final ValidationManager Check = new ValidationManager();
final SessionManager Session = new SessionManager(this);
final EditText textEmail = (EditText) view.findViewById(R.id.login_email);
final EditText textPassword = (EditText) view.findViewById(R.id.login_pass);
final Button buttonLogIn = (Button) view.findViewById(R.id.button_login);
final Button buttonSignup = (Button) view.findViewById(R.id.button_signup);
// Listen for FORGOTTEN PASSWORD click event, open ForgottenPassword Fragment //
final Button forgottenPassword = (Button) view.findViewById(R.id.button_lost_pass);
forgottenPassword.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setContentView(R.layout.fragment_forgotten_password);
}
});
... more code ...
return view;
}
}
You should get subviews from layout while it's being inflated. The layout usually inflated in OnCreateView method.
View layout = inflater.inflate( R.layout.fragment_login, null );
final EditText textEmail = (EditText) layout.findViewById(R.id.login_email);
final EditText textPassword = (EditText) layout.findViewById(R.id.login_pass);
...
return layout;
I am guessing you want to the fragment to be shown within the activity. Try this:
public class LoginActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//put the setContentView() before the fragment initialization also, I noticed your activity layout is the same as your fragment layout,this should not be so, hence I changed that
setContentView(R.layout.activity_login);
// Initialize Fragments //
//you did not initialize the fragments completely, it should be like
//this
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction().replace(R.id.fragment_container, new FragmentLogin()).commit();
}}
then in the Login fragment, it should be like this:
public class FragmentLogin extends Fragment {#Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_login, container, false);
final ValidationManager Check = new ValidationManager();
final SessionManager Session = new SessionManager(this);
final EditText textEmail = (EditText) view.findViewById(R.id.login_email);
final EditText textPassword = (EditText) view.findViewById(R.id.login_pass);
final Button buttonLogIn = (Button) view.findViewById(R.id.button_login);
final Button buttonSignup = (Button) view.findViewById(R.id.button_signup);
// Listen for FORGOTTEN PASSWORD click event, open ForgottenPassword Fragment //
final Button forgottenPassword = (Button) view.findViewById(R.id.button_lost_pass);
forgottenPassword.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//you cant call setContentView in a fragment
}
});
... more code ...
}}
I am not totally sure I caught all your mistakes but I think you should read these: one and two; they are online tutorials on fragments, you can also browse for more. I think it is a good starting point. All the best

How to implement a ClickListener for a button from a custom layout to use in a FragmentDialog

I'm try to set the action for ImageButton. When the DialgoFragment is called and is shown on screen, I want to preess the button and get an action. When I put my action inside that onClick in the code below it didn't work. I'm sure that's not the right way of doing it.
I'm using this class as fragment:
public class GeneralDialogFragment extends DialogFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout to use as dialog or embedded fragment
View v = inflater.inflate(R.layout.activity_dialog, container, false);
ImageButton mImageButton = (ImageButton) v.findViewById(R.id.image_button);
mImageButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
String name = "";
SharedPreferences prefs = getActivity().getSharedPreferences("MY_PREFS_NAME", Context.MODE_PRIVATE);
String yourmessage = prefs.getString("msg", null);
if (yourmessage != null) {
name = prefs.getString("msg", "No name defined");//"No name defined" is the default value.
}
ScrollTextView txt = (ScrollTextView) v.findViewById(R.id.scroll_text);
txt.setText(name);
txt.setTextSize(220);
txt.startScroll();
}
});
return v;
}
And in this activity_dialog layout I have an ImageButton:
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/image_button"
android:src="#drawable/ic_image_500px"/>
Edited: Now the action is in the class above. The error actually is in the action. I have the MainActivity where I press this send button:
public void send(View view){
EditText mEditText = (EditText)findViewById(R.id.text_msg);
String MESSAGE = mEditText.getText().toString();
SharedPreferences.Editor editor = getSharedPreferences("MY_PREFS_NAME", MODE_PRIVATE).edit();
editor.putString("msg", MESSAGE );
editor.commit();
Intent intent = new Intent(this, MessageActivity.class );
startActivity(intent);
}
It calls the MessageActivity where I call the GeneralDialogFragment class which shows the ImageButton with this code:
DialogFragment mDialog = new GeneralDialogFragment();
mDialog.show(getSupportFragmentManager(), "Dialog TAG");
Because of v which you've added it before, it's working without any errors:
View v = inflater.inflate(R.layout.activity_dialog, container, false);
ImageButton mImageButton = (ImageButton) v.findViewById(R.id.image_button);

changing the setText value in a fragment from main activity

I've been trying to change my textViews text in a fragmentActivity based on whether or not user has clicked the button in the first main activity. I have 2 xml files and 2 .java files and the code at the moment crashes when the app starts.
This is the button code
public void getNum(View view) {
buttonCheck = 1;
}
And this is the code from FragmentTab
public class FragmentTab extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_layout, container, false);
TextView tv = (TextView) v.findViewById(R.id.text);
tv.setText("nothing has been input yet");
if (FirstActivity.buttonCheck == 1){
tv = (TextView) v.findViewById(R.id.text);
tv.setText("value");}
FirstActivity.buttonCheck = 0;
return v;
}
The first error i get from my code from logcat is: "java.lang.NullPointerException
at com.ezentertainment.dietabialkowa.FragmentTab.onCreateView(FragmentTab.java:23)" and line 23 is tv.setText("nothing has been input yet");
any help at all is greatly appreciated, I have been fighting with this issue for quite some time now..
tl;dr how to change fragment value based upon input from mainActivity?
edit: here is the fragment_layout.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#eaecee">
<TextView
android:id="#+id/textResult"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="value"
android:textAppearance="?android:attr/textAppearanceMedium" />
Your textview id is
android:id="#+id/textResult"
So, that's why you're getting a null pointer exception.
Also, it's probably a good idea to do a null check when finding a view by ID, just in case something isn't instantiated yet, so it doesn't kill your app. Something like:
TextView tv = (TextView) v.findViewById(R.id.textResult);
if (tv != null){
tv.setText("nothing has been input yet");
} else {
// log something if you want.
}
How about using setArguement:
In Activity:
Bundle bundle = new Bundle();
bundle.putString("email", email);
FragmentA fragment = new FragmentA();
fragment.setArguments(bundle);
getSupportFragmentManager().beginTransaction().add(container, fragment, tag).addToBackStack(tag).commit(); //please input container and tag yourself
In FragmentA:
String email;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle arguments = getArguments();
if (arguments != null)
email = bundle.getString("email");
...
}

Android how to save all views in Fragment when user click on next and prev button

i use fragment for my application,they are : Fragment A, Fragment B and Fragment C.
to move from one fragment to another fragment, I use two buttons, the first button is used to move to the next fragment, and the second button is used to return to the previous fragment.
the problems when I move from one fragment to another fragment (such as from A to B and back to A and to B again and to C). all entries in the EditText that is in a fragment is lost and look back empty,it when I go back to the previous fragment, or when I want to go back to the next fragment. I've been using code addToBackStack () when switching to another fragment, indeed EditText that I made not lost when I press the back button on my phone, but it does not affect the buttons (Next And Prev) that I've created. this is Fragment A:
public class AFragment extends Fragment {
EditText text,text2;
public AFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_a, container, false);
ImageView next=(ImageView)rootView.findViewById(R.id.next);
text=(EditText)rootView.findViewById(R.id.text);
text2=(EditText)rootView.findViewById(R.id.text1);
next.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
getFragmentManager().beginTransaction().replace(R.id.frame_container, new BFragment()).addToBackStack(null).commit();
}
});
return rootView;
}
this is Fragment B:
public class BFragment extends Fragment {
EditText cut,cut2;
public BFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View Fragment B = inflater.inflate(R.layout.fragment_c, container, false);
ImageView next=(ImageView)rootView.findViewById(R.id.next);
ImageView prev=(ImageView)rootView.findViewById(R.id.prev);
cut=(EditText)rootView.findViewById(R.id.cut);
cut2=(EditText)rootView.findViewById(R.id.cut2);
next.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
getFragmentManager().beginTransaction().replace(R.id.frame_container, new CFragment()).addToBackStack(null).commit();
}
});
prev.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
getFragmentManager().beginTransaction().replace(R.id.frame_container, new AFragment()).addToBackStack(null).commit();
}
});
return Fragment B;
}
my question is how can i save view in Fragment when user click on next and prev button in my application? is there something missing in my code? i hope someone can help me to solve my problem. thank you very much.
Each fragments have various life cycle methods, you can use onDestroy method and save the required edit text view value calling Activity. For this expose some methods in the calling activity which can be access via fragment. Also else create a singleton class or use Shared Prefences.
I hope this helps.
try to change:
getFragmentManager().beginTransaction().replace(R.id.frame_container, new BFragment()).addToBackStack(null).commit();
to:
getFragmentManager().beginTransaction().add(R.id.frame_container, new BFragment()).addToBackStack(null).commit();

Bind to Button in dynamic view

I try to code in java/android the first time and I am a bit frustrated that my years of c# knowledge do not seem to help me very much.
Currently I try to create a buttonclick-event that should be bound to a button that is inside a view that is loaded dynamicly.
Part of my activity:
private Button myButton;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
String selectedMenu=getArguments().getString(ARG_SECTION_NUMBER);
if (selectedMenu==getString(R.string.title_test)) {
View rootView = inflater.inflate(R.layout.fragment_test, container, false);
myButton=rootView.findViewById("#+id/buttonTest"); // ERROR?
myButton.setOnClickListener(this);
return rootView;
}
return null;
}
public void onClick(View v) {
if (v==myButton) {
// magic stuff
}
}
And my button definition:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test starten"
android:id="#+id/buttonTest"
android:layout_gravity="center_horizontal"
android:onClick="TestSoap_OnClick" />
In the line "ERROR" I try to get the Button from the View. How can I access it?
And just for my understanding: As a button seems to be a view: Is "View" in Java about the same as "Control" in C# WinForms?
Replace
myButton = rootView.findViewById("#+id/buttonTest"); with myButton = (Button) rootView.findViewById(R.id.buttonTest);
The int that is expected is the id of the view that has been created which is referenced in R.id.
Try creating a function that will handle your onClick: in your case something like:
public void TestSoap_OnClick(View view){
doSomething();
}
Then when your button is pressed it will automatically call this function since you have:
android:onClick="TestSoap_OnClick"
try to remove the line android:onClick="TestSoap_OnClick" from your xml
and also replace myButton.setOnClickListener(this);
with myButton.setOnClickListener(onClick)

Categories