Fragment implements OnClickListener - android

I've got an application that I'm modernizing. One step of this process is changing to a Fragment based layout (using the Fragments from the support library).
I converted my Activities into Fragments, and got the layout working nicely (using a ViewPager, cool stuff!)
I was having my Activities implement OnClickListener for all of my button-pressing needs. I have the new Fragment incarnations doing the same thing of course, but it looks like "onClick" is never getting hit. Is there something special about Fragments that prevents them from working this way?

Just do one this
public class fragmentOne extends Fragment implements OnClickListener {
Button myButton;
#Override
public View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedinstanceState) {
View myView = inflater.inflate(R.layout.fragment_1, container, false);
myButton = (Button) myView.findViewById(R.id.myButton);
myButton.setOnClickListener(this);
return myView;
}
#Override
public void onClick(View v) {
// implements your things
}
}
very simple

I will Focus to use the OnClick action for global access, You have to do like this is your project, Must Implement the View.OnClickListener, then Override the Method
OnClick(), In OnCreateView() have to do like this button_submit.setOnClickListener(this); for the Views you need,
Please see the below code for Clear Answer,Thankyou.
public class New_Project extends Fragment implements View.OnClickListener{
private View mView;
private Button button_submit;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_newproject, container,false);
button_submit=(Button)mView.findViewById(R.id.button_submit);
button_submit.setOnClickListener(this);
return mView;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_submit:
//do your stuff
break;
}
}
}

I want to comment on Abhijit Chakra answer but it seems that I need to have 50 reps for that. For those who are wondering if you can't use Abhijit's answer, it is because of:
public void OnClick(View v) {
// implements your things
}
You need to make sure that it is onClick, NOT OnClick. Thankfully Android Studio internal error message come to rescue.

view.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
switch (v.getId()) {
case R.id.imgView1:
Toast.makeText(getActivity(), "Long pressing", Toast.LENGTH_SHORT).show();
updateImage();
break;
case R.id.imgView2:
Toast.makeText(getActivity(), "Long pressing", Toast.LENGTH_SHORT).show();
updateImage();
break;
case R.id.imgView3:
Toast.makeText(getActivity(), "Long pressing", Toast.LENGTH_SHORT).show();
updateImage();
break;
default:
break;
}

Related

How to create a button inside a Fragment?

I am creating a fragment where if I click on the button it should show a Toast message
This is my code:
public class Aboutus extends Fragment implements View.OnClickListener{
Button ps,fb;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.about_layout, container, false);
ps = (Button) view.findViewById(R.id.ps_btn);
fb = (Button) view.findViewById(R.id.fb_btn);
try {
ps.setOnClickListener(this);
}catch (ActivityNotFoundException exception) {
}
//fb.setOnClickListener(this);
return view;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.fb_btn:
Toast.makeText(getActivity(), "This is my Toast message!", Toast.LENGTH_LONG).show();
break;
case R.id.ps_btn:
Toast.makeText(getActivity(), "This is my Toast message!", Toast.LENGTH_LONG).show();
break;
}
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//you can set the title for your toolbar here for different fragments different titles
getActivity().setTitle("ABOUT US");
}
}
My app stops working when I open the fragment.
It does't seem like having issue with button. There may be a problem with implementing fragment inside activity. Once Watchout Fragment implementation. Thanks.

I have a checkbox inside a fragment and i want to it respond on click of a button this button is inside my main activity?

i am just working with fragments for the 1st time, i have a checkbox inside a fragment and a submit button inside my main activity. what i want to do is when i press submit button i want to toast a message whether the checkbox item is checked or not?
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Spinner Dspinner;
private Button Subbtn;
ArrayAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Subbtn = (Button)findViewById(R.id.button);
adapter = ArrayAdapter.createFromResource(this, R.array.spinner_options, android.R.layout.simple_spinner_item);
spinnerListner();
}
public void spinnerListner(){
Dspinner = (Spinner)findViewById(R.id.spinner);
Dspinner.setAdapter(adapter);
Dspinner.setOnItemSelectedListener(
new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (position){
case 0:
getSupportFragmentManager().beginTransaction().replace(R.id.frag, BlankFragment.newInstance()).addToBackStack(null).commit();
break;
case 1:
getSupportFragmentManager().beginTransaction().replace(R.id.frag, BlankFragment2.newInstance()).addToBackStack(null).commit();
break;
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
);
}
}
BlankFragment.java
public class BlankFragment extends Fragment {
public BlankFragment(){
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false);
}
public static Fragment newInstance() {
BlankFragment fragment = new BlankFragment();
return fragment;
}
}
BlankFragment2.java
public class BlankFragment2 extends Fragment {
public BlankFragment2(){
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank_2, container, false);
}
public static Fragment newInstance() {
BlankFragment2 fragment = new BlankFragment2();
return fragment;
}
}
You can use interface to communicate back to MainActivity.
Create a interface and implement it on MainActivity.
Pass the implemented interface to fragment and store it in the fragment
Then When your checkbox state change check that the stored interface is null or not if not null then call the implemented method
of the interface, which is actually implemented in MainActivity.
This way you can communicate back to MainActivity. In MainActivity store your checkbox state and do what you want to do in button press.
Interface
public interface OnStateChanged {
public void onChange(int state);
}
Implement it on MainActivity like
MainActivity implements OnStateChanged {
#Override
public void onChange(int state){
// store your data here
}
Create a variable for OnStateChanged interface and function in Fragment that will pass the interface
In Fragment:
OnStateChanged mListener;
public void setOnStateChangeListener(OnStateChanged listener){
mLinstener = listener;
}
When checkbox state change call the interface function
In Fragment:
//...if state change...
if(mListener!= null) {
mListener.onChange(/*your value*/);
}
Pass the implemented interface instance in MainActivity to fragment
In MainActivity:
fragment.setOnStateChangeListener(this);
There are several ways to realize this function. The easiest way is Defining an interface in your Activity, and let the Fragment implements it.(Or you can define a interface individually and let the Activity implements it, it's the similar solution)
For more solutions you can Google "Fragment and Activity Interaction".
I just can offer you some fragmentary code since I cannot find specific variable names.
First, defining a Interface in your Activity like this:
public static class MainActivity extends AppCompatActivity{
...
//Container Activity must implement this interface
public interface CheckBoxStateCallback{
public Boolean getTheState();
}
...
Second, let your fragments implements it:
public class BlankFragment extends Fragment implements CheckBoxStateCallback{
public BlankFragment(){
}
#Override
public Boolean getTheState(){
//return your checkbox state
}
...
Last, you need to add a click listener onto your Button in Activity:
...
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Boolean b = BlankFragment.newInstance().getTheState();
//then you can make a toast
}
});
...
In MainActivity you would implement an interface CheckboxStatusObserver which we define with a method checkBoxChanged.
public class MainActivity extends AppCompatActivity implements CheckboxStatusObserver{
// other methods
void checkBoxChanged(boolean checkedStatus){
Toast.makeText(getContext(), "status " + checkedStatus, Toast.LENGTH_LONG).show();
}
public interface CheckboxStatusObserver{
void checkBoxChanged(boolean checkedStatus);
}
}
In the Fragment, we would get a reference to the CheckboxStatusObserver as the parent Activity. Then while inflating the contents of the Fragment, we can set up a listener to detect the on change of the checkbox(s). Then we would call the observer.checkBoxChanged(checkedStatus); and pass it the checked status of the checkbox.
public class BlankFragment extends Fragment {
private CheckboxStatusObserver observer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
observer = (CheckboxStatusObserver) getActivity();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_blank, container, false);
// Find the checkbox instace using view.findViewById();
// Setup change listener on checkbox instance and notify the observer
{
observer.checkBoxChanged(checkedStatus);
}
return view;
}
}
Whenever the checkbox status changes, the method in the MainActivity will get invoked.
See below links for more information:
https://stackoverflow.com/a/25392549/592025
https://developer.android.com/training/basics/fragments/communicating.html
To allow a Fragment to communicate up to its Activity, you can define an interface in the Fragment class and implement it within the Activity. The Fragment captures the interface implementation during its onAttach() lifecycle method and can then call the Interface methods in order to communicate with the Activity.
Create an Interface in Your MainActivity and click listeners as below
try {
((OnClick) this).onSubmitClicked();
} catch (ClassCastException cce) {
cce.printStackTrace();
}
public interface OnClick {
public void onSubmitClicked();
}
Now implement listeners in your Fragment thus you will get onSubmitClicked implemented method as below Enjoy!
public class BlankFragment extends Fragment implements MainActivity.OnClick{
#Override
public void onSubmitClicked() {
//do something here
}
}
This is yet another way different from what i commented that day this might meet your need
In Main Activty
Blank1Fragment fragment1 = new Blank1Fragment();
Blank2Fragment fragment2 = new Blank2Fragment();
Subbtn..setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(position==0)
fragment1.function();
else if(position==1)
fragment2.function();
}
);
in OnitemClick of spinner
switch (position){
case 0:
position=0;
getSupportFragmentManager().beginTransaction().replace(R.id.frag, fragment1).addToBackStack(null).commit();
break;
case 1:
position=1;
getSupportFragmentManager().beginTransaction().replace(R.id.frag, fragment2).addToBackStack(null).commit();
break;
}
}
Each fragment will have
public class Blank1Fragment extends Fragment {
....
public void function(){
//check which checkbox selected and toast;
}
}
public class Blank2Fragment extends Fragment {
....
public void function(){
//check which checkbox selected and toast;
}
}

Android Programming - Fragments and Listeners

I am following a tutorial on the internet and I have to make a listener for my buttons. The tutorial I am watching is very different from my code even though the video was posted not even a year ago. The video I am watching has no "fragment" code in it. In my code there is a fragment in my MainActivity.java. What is a fragment? In my mainactivity.java towards the end I get this:
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
button1 = (Button)rootView.findViewById(R.id.button1);
button2 = (Button)rootView.findViewById(R.id.button2);
button3 = (Button)rootView.findViewById(R.id.button3);
button1.setOnClickListener(listener);
button2.setOnClickListener(listener);
button3.setOnClickListener(listener);
return rootView;
}
}
could anyone explain to me what a place holder fragment is? heres my code. I am getting an error here:
ERROR: "Toast.makeText(MainActivity.this, "toast", Toast.LENGTH_SHORT);"
Message: "No enclosing instance of the type MainActivity is accessible in scope"
.
private static OnClickListener listener = new OnClickListener()
{
#Override
public void onClick(View v) {
int id = v.getId();
switch(id)
{
case R.id.button1:
Toast.makeText(MainActivity.this, "toast", Toast.LENGTH_SHORT);
break;
case R.id.button2:
break;
case R.id.button3:
break;
default:
break;
}
}
};
HERES MY FULL CODE ( MainActivity.java ):
package com.example.androiddevelopmentonline_part2_1;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
import android.os.Build;
public class MainActivity extends ActionBarActivity {
private static Button button1, button2, button3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private static OnClickListener listener = new OnClickListener()
{
#Override
public void onClick(View v) {
int id = v.getId();
switch(id)
{
case R.id.button1:
Toast.makeText(MainActivity.this, "toast", Toast.LENGTH_SHORT);
break;
case R.id.button2:
break;
case R.id.button3:
break;
default:
break;
}
}
};
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
button1 = (Button)rootView.findViewById(R.id.button1);
button2 = (Button)rootView.findViewById(R.id.button2);
button3 = (Button)rootView.findViewById(R.id.button3);
button1.setOnClickListener(listener);
button2.setOnClickListener(listener);
button3.setOnClickListener(listener);
return rootView;
}
}
}
Probably the best explanation is in the Developer Docs (here: https://developer.android.com/guide/components/fragments.html)
Here's something from the "QuickView"
Fragments decompose application functionality and UI into reusable modules
Add multiple fragments to a screen to avoid switching activities
Fragments have their own lifecycle, state, and back stack
Fragments require API Level 11 or greater
The way I paraphrase it, is that its a reusable component of the UI with it's own lifecycle. It is used to decompose your UI into (multiple), more self contained, and logical "sections".
In your case, I think your IDE has auto generated the code for you and generated the PlaceholderFragment. It is as it says, an autogenerated placeholder. You can get rid of it if you're only working with Activities for now. But its best to look up Fragment tutorials later as they are used quite frequently with newer versions of android (Fragments are not necessary, but they're sorta 'better practice', depending on your application architecture).
The reason you're getting an error with:
ERROR: "Toast.makeText(MainActivity.this, "toast", Toast.LENGTH_SHORT);"
Message: "No enclosing instance of the type MainActivity is accessible in scope"
is actually explained in the message. You've declared your OnClickListener into an anonymous, static, attribute. Because it is static, it cannot access the current instance of the class (it is "not in scope", it has no access to the non-static methods and attributes). To fix it, just remove the static keyword:
private OnClickListener listener = new OnClickListener() //... etc
For an explanation about the static keyword in Java, look here: http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html or What does the 'static' keyword do in a class?
EDIT (A neater way of implementing OnClickListener)
A better idea would be to put your OnClickListener within your PlaceholderFragment (since that's where it's used), or have your PlaceholderFragment implement View.OnClickListener (I prefer this way, less anonymous types, it code formats better, but its a matter of preference). An example (look for the comments):
// note, doesn't matter if it is static
// I got rid of the OnClickListener attribute and made PlaceholderFragment implement OnClickListener like so
public static class PlaceholderFragment extends Fragment implements OnClickListener
{
// No need to provide a constructor. Fragments by default should have an empty constructor. If you want to add data to it, you need to create a "newInstance" method which calls fragment.setArguments (SomeBundleWithValuesInIt)
# Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View rootView = inflater.inflate (R.layout.fragment_main, container, false);
button1 = (Button) rootView.findViewById (R.id.button1);
button2 = (Button) rootView.findViewById (R.id.button2);
button3 = (Button) rootView.findViewById (R.id.button3);
// I set the OnClickListener to the PlaceholderFragment itself, because it implements OnClickListener (which is an interface), you can use it this way.
button1.setOnClickListener (this);
button2.setOnClickListener (this);
button3.setOnClickListener (this);
return rootView;
}
// OnClickListener.onClick(View) moved here.
# Override
public void onClick(View v)
{
int id = v.getId ();
switch (id) {
case R.id.button1 :
// getActivity() can be used instead of Context (Activity is one of the subclasses of Context), but only within a Fragment in this case
Toast.makeText (getActivity (), "toast", Toast.LENGTH_SHORT);
break;
case R.id.button2 :
break;
case R.id.button3 :
break;
default :
break;
}
}
}

New Activity created every time Button is pressed

I am making an app that will has three activities. The user can navigate to a new activity pressing buttons (home, graph, and write). This part works fine, but I only want three activities to be created max. Right now if I push the buttons 10 times I get 10 separate activities. Is there a way to prevent this and have the button call an activity if it has already been created instead of creating a new one each time?
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button_toGraph = (Button) findViewById(R.id.home_to_graph);
button_toGraph.setOnClickListener(goToSecondListener);
Button button_toWrite = (Button) findViewById(R.id.home_to_write);
button_toWrite.setOnClickListener(goToThirdListener);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private OnClickListener goToSecondListener = new OnClickListener(){
#Override
public void onClick(View arg0) {
doButton();
}};
private void doButton()
{
startActivity(new Intent(this, GraphScreen.class));
}
private OnClickListener goToThirdListener = new OnClickListener(){
#Override
public void onClick(View v) {
doBacktoThird();
}
private void doBacktoThird() {
startActivity(new Intent(MainActivity.this, WriteScreen.class));
}
};
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
return rootView;
}
}
Any help will be greatly appreciated! Thank you!
create three Boolean Variables.
if suppose button_toGraph is clicked .. make the
Boolean button_toGraph_IsCreated = true;
and when Activity is Finished ( YourActivity.finish ) make it Again false.
make a check on the button by using these variable like
if(button_toGraph_IsCreated) // if the variable is true
{
// do nothing as already activity created
}
else
{
doBacktoThird();
}
if you are using database then it should not be hard to get the values to main activity.

onClick inside fragment called on Activity

i am encapsulating stuff into a fragment at the moment and run into a problem that is hard to google.
Inside my fragment are some buttons with onClick attributes but they are called on the Activity rather the fragment from the android system - this makes encapsulating a bit clumsy. Is there a way to have the reflection stuff from onClick to call on the fragment? The only solution to this I see at the moment is not to use onClick in the xml and set click-listeners inside the fragment via code.
I spoke to some googlers # #adl2011 - they recognize the problem and perhaps there will be a fix of that in the future. Until then - one should use .setOnClick in the Fragment.
The problem is that when layout's are inflated it is still the hosting Activity that is receiving the button clicks, not the individual Fragments.
I prefer using the following solution for handling onClick events. This works for Activity and Fragments as well.
public class StartFragment extends Fragment implements OnClickListener{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_start, container, false);
Button b = (Button) v.findViewById(R.id.StartButton);
b.setOnClickListener(this);
return v;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.StartButton:
...
break;
}
}
}
Then problem is gone.
It works for me
Add import:
import android.view.View.OnClickListener;
Fragment.java
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = (ViewGroup) inflater.inflate(R.layout.fragment, container, false);
Button mButton = (Button) rootView.findViewById(R.id.button);
mButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
}
});
return rootView;
}
ISSUE:
1.In XML onClick attribute will call activity's public method.
2.Fragment's public method not called.
3.Fragment reusability.
SOLUTION:
In Fragment's layout add this to the View.
android:onClick="onFragmentViewClick"
In each activity the fragment may belong..
public void onFragmentViewClick(View v) {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.container);
if (fragment != null && fragment.isVisible()) {
if (fragment instanceof SomeFragment) {
((SomeFragment) fragment).onViewClicked(v);
}
}
}
In the Fragment include this method..
public void onViewClicked(View v) {
switch (v.getId()) {
case R.id.view_id:
Log.e("onViewClicked", "yehhh!!");
break;
}
}
You could have the listener that is being called in the activity forward the call onto a listener in the fragment. You should have a reference to the fragment inside of the FragmentActivity to pass the call on. You will have to cast to call the method or have your fragment implement an interface you define. I know that isn't the best solution but it will work. You could also use the tag of a button to specify the method name to call if you wanted. Hope this helps a bit.
Try this...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.activity_ipadditional_users, container, false);
FloatingActionButton button7 = (FloatingActionButton) rootView.findViewById(R.id.fab_ip_additional_user);
button7.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(), IPAdditionalUsersEdit.class);
startActivity(intent);
}
});
return rootView;

Categories

Resources