method call from adapter class to activity - java

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;
}
}

Related

How can we use new View.OnClickListener directly when OnCLickListener is not static

I was wondering one thing today. Whenever we are setting up a ClickListener, we run this code.
tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
I Opened the View Class and saw the OnClickListener interface and found that it is not static. The method is like this:
public interface OnClickListener {
/**
* Called when a view has been clicked.
*
* #param v The view that was clicked.
*/
void onClick(View v);
}
Then how are we able to access OnClickListener method directly by using class name?
For java, "A nested interface is implicitly static." jls (9.1.1.3)
You can implement class View.OnClickListener and then you will able to Override its method just like shown below :
public class YourActivity implements View.OnClickListener {
#Override
public void onClick(View v) {
}
}

Callback inside anonymous functions, not getting the syntax propely

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.

Communicate from Activity to Fragment using Interface

I have searched SO for this problem but was not able to find anything which would solve my problem. My problem is, I have a activity which contains FrameLayout which is constantly updated with different fragments. The top view and bottom view are going to remain same hence they are in the layout of the
activity.
As you can see bottom view has a button on click of that i want to make changes in the fragments which will be present in the FrameLayout.
I have created a interface
public interface ShowFormula {
void showFormula(boolean show);
}
which i will use to implement in the fragment.
Now the main problem in my MainActivity class i am trying to initialize the interface but not able to as i am getting class cast exception
showFormula = (ShowFormula) this;//yes i know this is wrong
How should i initialize this in order to communicate with the fragment.
Main goal is to toggle the view in fragments on click of the button in activity.
Thanks in advance.
You don't need to use an interface to make calls from an Activity to a Fragment. Just keep a reference to the current Fragment, and call into a public method in the Fragment from the Activity.
If you have multiple Fragments and you don't want to keep a reference for each one, you can create a Fragment base class, declare the common method in the base class, and then implement that method override in all of your Fragments that inherit from the base Fragment. Then, keep one reference of the base Fragment type, and always have it set to the Fragment that is shown currently.
Activity ---> Fragment
Communication from Activity to Fragment is pretty straightforward. You
really don't need a listener.
Let's say you have a method inside Fragment share()
public class MyFragment extends Fragment{
public static MyFragment getInstance()
{
return new MyFragment();
}
........
public void share()
{
// do something
}
}
How to call share() method from an Activity?
Get the reference of the Fragment and call the method. Simple!
MyFragment myFragment = MyFragment.getInstance();
myFragment.share();
You can see the full working code for Fragment to Fragment Communication
Just to add to Daniel Nugent's brilliant answer, here are snippets from my working code for delegating calls from Activity to Fragment.
I have a MVP architecture and I have defined the error handling method showError on the BaseView class and the code below demonstrates how to handle the UI on a TargetFragment class. I, specifically needed to hide my progress spinner on the fragment upon any error scenario. Here's the code snippets for the base classes:
public interface BaseView {
void showError(ErrorResponse errorResponse);
}
public abstract class BaseActivity implements BaseView {
#Override
public void showError(ErrorResponse errorResponse) {
// Check error condition or whatever
// ...
MaterialDialog dialog = new MaterialDialog.Builder(this)
.title(R.string.dialog_error_title)
.content(R.string.error_no_internet)
.positiveText(R.string.dialog_action_ok)
.build();
dialog.show();
}
}
public abstract class BaseFragment implements BaseView {
#Override
public void showError(ErrorResponse errorResponse) {
((BaseView) getActivity()).showError(errorResponse);
}
}
And, this is how I handle UI inside my TargetFragment class:
public final class TargetFragment extends BaseFragment implements TargetView {
#Override
public void showError(ErrorResponse errorResponse) {
super.showError(errorResponse);
hideSpinner();
// Do other UI stuff
// ...
}
private void hideSpinner() {
spinner.setVisibility(View.INVISIBLE);
}
}
a clean solution:
public interface ShowFormula {
public void showFormula(boolean show);
}
public class MyActivity implements ShowFormula {
...
#Override
public void showFormula(boolean show) {
/** Your Code **/
}
...
}
public class MyFragment {
private ShowFormula listener;
...
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (ShowFormula) activity;
// listener.showFormula(show?);
} catch (ClassCastException castException) {
/** The activity does not implement the listener. **/
}
}
...
}
simple thing make public method in fragments then call it on from your activity.
e.g
MyFragment fragment = new MyFragment();
fragment.doSomeThing();
doSomeThing() is a public method in MyFragment.
Activity to Fragment Communication via Interface:
public class MyActivity {
private ShowFormula showFormulaListener;
public interface ShowFormula {
public void showFormula(boolean show);
}
public void setListener(MyFragment myFragment) {
try {
showFormulaListener = myFragment;
} catch(ClassCastException e) {
}
}
}
public class MyFragment implements ShowFormula{
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
((MyActivity) activity).setListener(this);
} catch (ClassCastException e) {
Log.e(TAG, e.toString());
}
}
#Override
public void showFormula(boolean show) {
/** Your Code **/
}
}
Once you are done setting this, you can call 'showFormulaListener.showFormula(boolVal)'

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
}
}
}

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()

Categories