Callback inside anonymous functions, not getting the syntax propely - java

I am trying to implement a void method callback inside an anonymous class and I am a bit lost with the syntax since I working on a large android code-base. I have set a listener to and image button like so:
MyImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
OnFollowingClick click;
click = new OnMyClick(param1, param2); // irrelevant for this thread
click.onClick(view); // irrelevant for this thread
// my problem is here!
click.setCallback( what do I pass in here? and where can define my callback?);
}
});
Here is the OnMyClick class and the void callback interface I defined:
public interface CallbackInterface {
public void Callback();
}
public class OnMyClick implements View.OnClickListener {
// I added this
CallbackInterface mCallBack;
public void setCallback(CallbackInterface callback) {
this.mCallBack = callback;
}
// Please call my callback
public void onFollowingChanged() {
if (mCallBack != null) {
mCallBack.Callback();
}
}
// a bunch of code in here that does not matter
// ...
I have to create callback somewhere, so I am guessing I need something like:
public class SomeClass implements CallbackInterface {
#Override
public void Callback() {
System.out.println("Hey, you called.");
}
}
The problem is that listener is an anonymous function, so I don't want to define a separate class somewhere just to serve as a callback.
I looked at this thread but did not give me much info:
How can an anonymous class use "extends" or "implements"?
is there a way to make the anonymous function implement my interface inside the scope, like:
MyImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void Callback() {
// please call me!
}
Not sure if it made sense, buy any help is greatly appreciated.
thx!

Just define the callback anonymously like you are already doing with the View.OnClickListener.
MyImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
OnFollowingClick click;
click = new OnMyClick(param1, param2); // irrelevant for this thread
click.onClick(view); // irrelevant for this thread
// your solution is here!
click.setCallback(new CallbackInterface() {
#Override
public void Callback() {
System.out.println("Hey, you called.");
}
});
}
});
If this is not what you meant then please clarify and I will try and help further.

Related

method call from adapter class to activity

Adapter:
check_list_item.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
JPrequirements.prepareSelection(v, getAdapterPosition());
}
});
JPrequirements is the activity. and prepareSelection is non-static method inside activity. I cannot access it from adapter.
ERROR:
non static method cannot be referenced from a static context
Which is right. that's why I tried with:
JPrequirements().prepareSelection(v, getAdapterPosition()); // Creating an instance...
But, the problem is I lost all activity component here. eg. layout components and other supporting variables. I don't want that. What is the best way to deal with this? How can I get updated value from adapter to activity? So, I can display it real-time.
Thanks.
You can achieve this via interface. Firstly, define an interface class as:
public interface ActivityAdapterInterface {
public void prepareSelection(View v, int position);
}
Now, implement the interface in your Activity as:
public class JPrequirements extends AppCompatActivity implements ActivityAdapterInterface {
...
public void prepareSelection(View v, int position) {
// cool stuff here
}
...
}
Make sure you pass this interface reference to your Adapter via its constructor. Then finally call it on click as:
check_list_item.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mActivityAdapterInterface.prepareSelection(v, getAdapterPosition());
}
});
[EDIT]
To provide the interface to your Adapter provide it the constructor.
public class YourAdapter ... {
private ActivityAdapterInterface mActivityAdapterInterface;
public YourAdapter(..., ActivityAdapterInterface activityAdapterInterface) {
activityAdapterInterface = mActivityAdapterInterface;
}
}

View.OnClickListener, can you explain?

Sorry if this question might be stupid for you, but I'm new to Android programming and I can't wrap my head around Java syntax.
Can you explain what is happening with this line of code step by step?
View.OnClickListener ourOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View v){
ourMessage.setText(“The button got tapped”);
}
};
There is an interface declared inside View class, and it's OnClickListener, it looks like this in View.java source:
/**
* Interface definition for a callback to be invoked when a view is clicked.
*/
public interface OnClickListener {
/**
* Called when a view has been clicked.
*
* #param v The view that was clicked.
*/
void onClick(View v);
}
Normally you would create a class, and have it implement this interface:
public void MyClass implements View.OnClickListener {
#Override
public void onClick(View view) {
// do stuff
}
}
But sometimes you don't need this class in a separate file. Instead, you can create anonymous inner class, it's like creating new class, which only methods are the one from the interface specified:
new View.OnClickListener() {
#Override
public void onClick(View v){
ourMessage.setText(“The button got tapped”);
}
}
You can then use instance of this class everywhere the View.OnClickListener interface is needed.
What's also worth mentioning is that anonymous inner class will hold a reference to the class in which you're creating it. So this will be legal and valid:
public class MyClass {
private int clicksCount = 0;
private View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View view) {
clicksCount += 1;
}
}
}
Here you can access clicksCount field, which is field of MyClass even from the inner class that implements OnClickListener. Side note - if you want to access a variable, you need to add final modifier to it:
public void testMethod(final int canAccess, int cantAccess) {
final String test = otherView.getText().toString();
myView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Cannot access cantAccess, because it's not final
if (test.length == 0) { // can access
// do something
}
}
}

Android - How to pass interface to AsyncTask

I'm trying to figure out how to create an AsyncTask that runs my php API code in the background then alerts my MainActivity once it completes. I've been reading tutorials and trying things for hours now and I'm just frustrated at this point as I can't find anywhere that answers my question.
I create the AsyncTask and it runs successfully and I can log the returned information from my API in the onPostExecute but I cannot figure out how to alert the MainActivity that the task was completed. I do not know what to pass into the creation of the APICall. Every tutorial I read shows that the AsyncTask constructor takes the interface as an argument as shown in my code below, but how do you pass an interface as an argument?
MainActivity.java (implements OnTaskCompleted)
myButton4.setOnClickListener(new OnClickListener(){
public void onClick(View v){
APICall api = new APICall( ???What do I put here?? );
api.execute("users");
}});
....
#Override
public void onTaskCompleted() {
Log.v("Play","Main Activity ON Task completed!");
OnTaskCompleted.java
public interface OnTaskCompleted {
public void onTaskCompleted();
}
APICall.java (extends AsyncTask)
public APICall(OnTaskCompleted listener){
this.listener = listener;
}
....
protected void onPostExecute(JSONObject j)
{
listener.onTaskCompleted();
}
You should pass the reference of your listener to the APICall class:
APICall api = new APICall(MainActivity.this);
Simple you can use anonymous interface instance like this.
myButton4.setOnClickListener(new OnClickListener(){
public void onClick(View v){
APICall api = new APICall(new OnTaskCompleted() {
#Override
public void onTaskCompleted() {
}
});
api.execute("users");
}});
OR you can Implement interface at class level like this
public class MainActivity extends Activity implements MainActivity.OnTaskCompleted {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myButton4.setOnClickListener(new OnClickListener(){
public void onClick(View v){
APICall api = new APICall(MainActivity.this);
api.execute("users");
}});
}
#Override
public void onTaskCompleted() {
// Do your code on task complete
}
}
APICall api = new APICall( ???What do I put here?? );
What do I put here??
The one that implements your listener in this case your MainActivity
APICall api = new APICall(MainActivity.this);

How to call member functions from onClickListeners

Consider the below piece of code (which works fine by the way) from an Activity:
class ParentActivity extends Activity {
...
#Override
public void btnOK_onClick(final View view) {
// do stuff
}
}
class ChildActivity extends ParentActivity {
...
public void superClick(View view) {
super.btnOK_onClick(view);
}
#Override
public void btnOK_onClick(final View view) {
final BarcodePickActivity me = this;
if (confirmation_needed == true) {
new AlertDialog.Builder(this)
.setTitle(R.string.are_you_sure_)
.setMessage(R.string.are_you_sure_you_want_to_continue)
.setNegativeButton(R.string.no, null)
.setPositiveButton(R.string.yes, new OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
me.superClick(view);
}
}).create().show();
} else {
super.btnOK_onClick(view);
}
}
}
In the layout that is used, there is a Button with an onClick set:
<Button
android:id="#+id/btnOK"
android:onClick="btnOK_onClick"
android:text="#string/ok" />
as you see, I have to jump through quite some hoops to get this working:
define a final variable to have this available in the OnClickListener of the AlertDialog,
define an extra method to be able to call super.btnOk_onClick.
As I said, it works fine, but it doesn't look pretty. Is there a way to do this nicer?
Use classname.this from the inner class. So if you class is MySuperClass you can reference MySuperClass.this from an instance inner class.
There is no reason you need to define superClick as you could always just call super.btnOK_onClick(view);.
So all told, you should be able to do something like MySuperClass.super.btnOK_onClick()

How to call function from one file class to another file with onClick?

This is probably a duplicate, but i can't find any thing on this so here goes.
I want to call a function in a class from file B.java into A.java with the onClick. Problem is, i get an error every time I add the line in. Here is my code and I'll give the error at the bottom.
A.java
import com.example.app.B;
public class MainService extends Service
{
private CallFunc callFunc;
private Button btn;
public void onCreate()
{
callFunc = new CallFunc();
btn = new Button(this);
//Code for setOnClickListener
#Override
public void onClick(View v)
{
callFunc();
}
}
}
B.java
public class CallFunc
{
public CallFunc()
{
//Stuff to do
}
}
Error I get
The method callFunc() is undefined for the type new View.OnClickListener(){}
//you are not calling your function:
import com.example.app.B;
public class MainService extends Service
{
private CallFunc callFunc;
private Button btn;
public void onCreate()
{
callFunc = new CallFunc();
btn = new Button(this);
//Code for setOnClickListener
#Override
public void onClick(View v)
{
callFunc.callFunc();//It is a good idea to use better method names. it looks like you are calling your constructor, not a method.
}
}
}
In your CallFunc class,
public CallFunc()
{
//Stuff to do
}
means it's constructor. It get called when you create it. In here callFunc = new CallFunc();.
You can include it to onClick method.
#Override
public void onClick(View v)
{
callFunc = new CallFunc();
}
Better way is to do this is add a method to CallFunc class because method means you do something. You do your stuff in that method. Class means a object like a car. Car can be drive. so it should have dirve() method. Then car.drive() means you drive the car. :)
#Override
public void onClick(View v)
{
callFunc.someMethod();
}
What you have in your B.java is a constructor not a method. A constructor is a special case method that gets invoked when an instance of that class is created. It is used to correctly initialise and populate new instances of a class.
What you were probably trying to do is:
public class CallFunc
{
public CallFunc()
{
// this is the constructor
// initialise the class instance here
}
public void someMethod()
{
// a method you can call
// perform actions here
}
}
Then in the onCreate() of your MainService you should:
#Override
public void onClick(View v)
{
callFunc.someMethod();
}
However, you are extending Service and using UI components (Button and onClick) when a Service does not have a UI. Are you sure you didn't want to use an Activity?

Categories