INTRODUCTION
I have a bluetooth app that consists on an Activity which has 3 buttons that do:
- Set visibility on and create a server connection
- Find devices and create a client connection
- Send something
I have the following classes:
- Main activity: where I have all the methods, and the button listeners
- 3 different classes with the Threads: ClientConnection, ServerConnection and ConnectedThread
Now I have to change the desing a little bit and instead of having one activity with all this, using Tabs on the ActionBar I need to create 2 fragments: Server and client.
So, basically, I have to define the Server and send buttons in the Server fragment, and the client button in the Client fragment, and set their listeners.
QUESTION
From each fragment, when using one button, I should call its corresponding method ubicated in the main Activity. I would like to do it this way, instead of copying all the methods and interfaces in each fragment, just to have it simplier.
I tried setting the methods as static, but there are some definitions inside the methods that can't be called with static references. Example:
public class ServerFragment extends Fragment {
//...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.server_layout, container, false);
btnServer = (Button) view.findViewById(R.id.buttonServer);
btnServer.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onClickServer();
}
});
//...
_
public class BluetoothActivity extends Activity {
//...
public void onClickServer() {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);
startActivityForResult(discoverableIntent, REQUEST_DISCOVERABLE);
}
If I set onClickServer()
as static, I have to set REQUEST_DISCOVERABLE
too as static, and the startActivityForResult()
doesn't let me use a static variable there.
How could I do this?
UPDATE -- Throwing NullpointerException
I have created new class called ClickInterface as suggestions, and there i have defined the 2 interfaces, one for the server and the other for the client.
No, from the fragment, I'm trying to call the method in the onClick method, but is throwing an NPE just in the line where i do the call to the callback's method:
public class ServerFragment extends Fragment implements OnClickListener {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.server_layout, container, false);
btnServer = (Button) view.findViewById(R.id.buttonServer);
btnServer.setOnClickListener(this);
return view;
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.buttonServer:
serverFragCallback.onServer(); //HERE I RECEIVE THE NPE
break;
}
}
This is the logcat's output:
03-20 16:33:57.581: E/AndroidRuntime(24884): FATAL EXCEPTION: main
03-20 16:33:57.581: E/AndroidRuntime(24884): Process: com.uax.bluetoothconnection, PID: 24884
03-20 16:33:57.581: E/AndroidRuntime(24884): java.lang.NullPointerException
03-20 16:33:57.581: E/AndroidRuntime(24884): at com.uax.bluetoothconnection.ServerFragment.onClick(ServerFragment.java:43)
03-20 16:33:57.581: E/AndroidRuntime(24884): at android.view.View.performClick(View.java:4633)
03-20 16:33:57.581: E/AndroidRuntime(24884): at android.view.View$PerformClick.run(View.java:19330)
03-20 16:33:57.581: E/AndroidRuntime(24884): at android.os.Handler.handleCallback(Handler.java:733)
03-20 16:33:57.581: E/AndroidRuntime(24884): at android.os.Handler.dispatchMessage(Handler.java:95)
03-20 16:33:57.581: E/AndroidRuntime(24884): at android.os.Looper.loop(Looper.java:157)
03-20 16:33:57.581: E/AndroidRuntime(24884): at android.app.ActivityThread.main(ActivityThread.java:5356)
03-20 16:33:57.581: E/AndroidRuntime(24884): at java.lang.reflect.Method.invokeNative(Native Method)
03-20 16:33:57.581: E/AndroidRuntime(24884): at java.lang.reflect.Method.invoke(Method.java:515)
03-20 16:33:57.581: E/AndroidRuntime(24884): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
03-20 16:33:57.581: E/AndroidRuntime(24884): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
03-20 16:33:57.581: E/AndroidRuntime(24884): at dalvik.system.NativeStart.main(Native Method
Use interface to call method from Activity from any fragment page, for example:
And in Activity:
And now in fragment you can use this:
ENJOY!
as Chris said, you have tu let your activity implement an interface, let's say ClickInterface:
the interface would be like this:
and this is your fragment:
So, you're calling "onClickServer()" method on mCallback object, and this method would be called in the activity because it implements the interface
Making everything static is the wrong way to go on this. Do this:
getActivity()
to your interface and call the methods. (Remember to check beforehand, i.e.if (getActivity() instanceof MyInterface) ...
What you want is a callback interface for the communication from a Fragment to an Activity. The docs already provide a good example for this.
Define an Interface which your Activity implements:
In your Fragment use this interface if one of the Buttons are clicked.
With this approach you can leave your logic in the Activity and handle the UI events in the Fragment. Through the events in the Fragment you can invoke the methods in your Activity.