Callback from (List)Adapter to Activity - android

I have an Actvivity with a ListView, I set an adapter
MyAdapter extends BaseAdapter
that adapter has a callback interface
OnPdfClickedListener callback;
public interface OnPdfClickedListener {
public void onPdfClicked();
}
and in the Activity
MyActvivity implements MyAdapter.OnPdfClickedListener
and
#Override
public void onPdfClicked() {
Log.d("TEST", "PDF CLICKED in ACTVIIVTY");
}
This is pretty much the same as described here, which works like charm for fragments.
When trying the same from the adapter the callback object is null.
I also tried instantiating like
OnPdfClickedListener callback = new OnPdfClickedListener() {
#Override
public void onPdfClicked() {
// TODO Auto-generated method stub
}
};
I have no errors then but the respective method in the Activity is never called.
My question is 1. why isn't the callback object null when used in a fragment, it's never instantiated
and 2. how can I callback to an Activity from an adapter?

why isn't the callback object null when used in a fragment, it's never instantiated
Your Activity most likely isn't registered as a listener, with the callback variable you created(which has nothing to do with the Activity) an instance of OnPdfClickedListener and (probably) used that when the event happened.
how can I callback to an Activity from an adapter?
Pass a reference to the Activity to your MyAdapter class, cast it to OnPdfClickedListener and use that to call onPdfClicked instead of the current callback variable.

Try adding this:
In your Activity which implements the interface:
new MyAdapter(this,....);
In your Adapter:
MyAdapter(Context context, ...){
callback = (OnPdfClickedListener)context;
}

Related

Android how to put data from fragment to main activity

For Fragment(put data to activity)
m=(MainActivity)getActivity();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent in=new Intent(getActivity(),MainActivity.class)
in.putExtra("test",test);
startActivty(in)
}
},10);
For Activity (get data from fragment )
{
String get_data=getIntent.getStringExtra("test");
}
//it will return always null...any body help me?
startActivty(in) will start the same activity.
Instead of this, you can make use of Interface. It's the easiest way to pass the data.
in your fragment, you can have an interface like,
SubmitData mSubmitData;
public interface SubmitData{
void DataListener(String s);
}
mSubmitData.DataListener("data to be sent");
In your activity, implement the SubmitData interface. It will make you override the DataListener method, where you can get the data.
public class MyActivity extends AppCompatActivity implements YourFragment.SubmitData{
#Override
public void DataListener(String s) {
// Data from the fragment
}
This questions has been asked and answered multiple times. You can find a valid reply here https://stackoverflow.com/a/9977370/5828132
Basically, it consists of creating an interface in the Fragment (for example) including a simple method. The Fragment has to declare a field of that type, and the Activity hosting the Fragment has to implement (implements) that interface. Both entities are usually connected using a explicit cast, in the onAttach() callback of the Fragment life-cycle, i.e.:
#Override
public void onAttach(Context context) {
super.onAttach(context);
// fragmentField_interfaceType = (interfaceType) context;
}
Hope it helps!

Is there any way to Detect userInterations in Android fragments?

Could any one help me out with this situation.
I have implemented OnUserInteraction() method for Android Activity it is working fine for me.
But I want it for Fragments too.How can i able call OnUserInteraction() or is there any another way to identify userInteraction with the UI.
#Sunil's answer causes java.lang.StackOverflowError so I corrected it. Below code works smoothly
Create a java class in your app named UserInterationListener and put below code there
public interface UserInteractionListener {
void onUserInteraction();
}
Then create an instance variable in your activity, for this interface as below
private UserInteractionListener userInteractionListener;
Then implement a setter method for this variable, in your activity.
public void setUserInteractionListener(UserInteractionListener userInteractionListener) {
this.userInteractionListener = userInteractionListener;
}
Now override the onUserInteraction method of your activity and if the listener variable is not null, invoke the interface method.
#Override
public void onUserInteraction() {
super.onUserInteraction();
if (userInteractionListener != null)
userInteractionListener.onUserInteraction();
}
Now, in your fragment class, implement UserInteractionListener as below
public myFragment extends Fragment implements UserInteractionListener
also override interface's method
#Override
public void onUserInteraction(){
//TODO://do your work on user interaction
}
then in your fragment invoke your activity's userinteraction setter method like below
((YourActivity) getActivity()).setUserInteractionListener(this);
this last part is important.
There is another way around.
Create a listener in your activity as below
public interface UserInteractionListener {
void onUserInteraction();
}
Then create an instance variable in your activity, for this interface as below
private UserInteractionListener userInteractionListener;
Then implement a setter method for this variable, in your activity. (You can even keep a List of eventlistener objects, if you want to pass same userinteraction to multiple consumers)
public void setUserInteractionListener(UserInteractionListener userInteractionListener) {
this.userInteractionListener = userInteractionListener;
}
Now override the onUserInteraction method of your activity and if the listener variable is not null, invoke the interface method.
#Override
public void onUserInteraction() {
super.onUserInteraction();
if (userInteractionListener != null)
userInteractionListener.onUserInteraction();
}
Now, in your fragment class, register for events as below
((YourActivity) getActivity()).setUserInteractionListener(new YourActivity.UserInteractionListener() {
#Override
public void onUserInteraction() {
// Do whatever you want here, during user interaction
}
});

How to get activity instance from startActivity() or precisely how to call a method in an activity that we create?

Im trying to figure a way how to call an activity that an adapter has started. Is there a way to get the instance of the activity from startactivity and make a method call into the activity ?
I'ved got an adapter that has a list
public class LanguageDownloadRVAdapter extends RecyclerView.Adapter<LanguageDownloadRVAdapter.DownloadViewHolder>{
And in this adapter, it starts a particular activity called MainActivity
context.startActivity(new Intent(context, MainActivity.class));
((Activity)context).finish();
Here is the MainActivity that it starts
public class MainActivity extends AppCompatActivity implements IabBroadcastListener{
How can I make a call from the adapter to a method in the MainActivity. (im just trying to perform inapp purchase which is implemented in the MainActivity). so how can i do something like this.
mainactivity.perform_inapp_purchase();
Try to use EventBus for passing data between activity and list adapter. You can do it in the same way for passing data between activity and fragment.
This work the same way as storing data in global variable (in a fancier way)
In the adapter:
Add a new Field private Context mContext;
In the adapter Constructor add one more parameter as below, and assign it into class level variable:
public LanguageDownloadRVAdapter(......,Context context){
//your code.
this.mContext=context;
}
In the Adapter where you want to call Activity's perform_inapp_purchase() method:
if(mContext instanceof MainActivity){
((MainActivity) mContext).perform_inapp_purchase();
}
More Generalized Approach:
If you need to use this same adapter for more than one activity then :
Create an Interface
public interface InAppPerchaceInterface{
void perform_inapp_purchase();
}
Implement this interface in activities
Then in Adapter, call like below:
if(mContext instanceof InAppPerchaceInterface){
((InAppPerchaceInterface) mContext).perform_inapp_purchase();
}
You can store the instance in the application class, but you should be careful about the memory leaks.
In the onCreate of your activity
protected void onCreate(Bundle savedInstanceState)
{
// get the instance using this and store it in the application class or in the place that you want to call from it
}
From where will you call your method?
I didn't understand the situation.

Receiving data from a DialogFragment if you're calling from an Activity vs a Fragment?

I call my DialogFragment like so:
If I am in an Activity:
MyDialogFragment dialogfragment = new MyDialogFragment();
dialogfragment.show(getFragmentManager(), "");
If I am already in a Fragment:
MyDialogFragment dialogfragment = new MyDialogFragment();
dialogfragment.show(getActivity().getFragmentManager(), "");
In MyDialogFragment, which inflates an XML and allows the user to input some values to EditTexts and so forth, I want to be able to return those values back to wherever I called the dialog from.
For the sake of the question let's say my dialog class wants to return some private variables String mName and int mValue.
Is there a proper way to do this without knowing where the dialog is being called from (either an Activity or a Fragment)? How do I pass the values back / how do I receive them?
If you want to send data to activity from fragment. You can do that by calling public method of activity by:
((MainActivity)getActivity()).sendData(Object object);
You can't do the same for sending data to a fragment.
As doc says:
All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.
What you should do is:
Define an Interface in the fragment.
Implement that Interface in the activity
Deliver data to the activity
then activity will deliver data to some other fragment.
BTW, you can also use this practice to send data to activity (upto point 3).
Reference and example
Defining an interface:
public interface DataListener {
public void onDataReceived(Object obj);
}
inside the fragment:
public class MyFragment extends Fragment {
DataListener callback;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
callback = (DataListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement DataListener");
}
}
}
Sending data from fragment;
callback.onDataReceived(object); // some object data
Receiving data in activity:
public static class MainActivity extends AppCompatActivity
implements DataListener{
public void onDataReceived(Object object) {
// Do something here with object data
}
}
Now if you want, you can send this data to any other fragment.
Sending data from activity to some other fragment:
AnotherFragment anotherFrag = (AnotherFragment)
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (anotherFrag != null) {
anotherFrag.receiveDataInFrag(object);
}else{
// create a new instance of the fragment and pass data to it.
}
Create a callback interface and have pass it into your dialogfragment
interface DialogValuesCallback {
void callThisFunctionWhenUserClicksOnOkInDialog(String passinmName,int passinmValue);
}
You can have your Activity or Fragment implement this interface.
Have a constructor in your MyDialogFragment which accepts the interface and assigns it to an member variable.
MyDialogFragment(DialogValuesCallback activityOrFragmentWhichImplementsThis){
mInterfaceCallbackObjectRef = activityOrFragmentWhichImplementsThis;
}
#Rohit Arya this is what you should know first that fragments needs to declare an interface that must be implemented by every activity that uses that fragment so you can pass data from the fragment to the activity(s)... and must cast the activity displaying the fragment currently into this interface like this in your onAttach method
//#param Listener is the declared interface in your fragment class
public class MyFragment extends Fragment {
Listener mInterface;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mInterface = (Listener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()`
+ " must implement DataListener");
}
}
public interface Listener{
//#param type = data type, cont = variable
public void sendData(type cont, type2 cont2)
;
}
}
make sure the interface declared in your fragment get implemented in your baseActivity then what ever data you pass to the interface using
mInterface.sendData(value, value1);
you can get it in the base activity like
public class baseActivity extends Activity implements MyFragment.Listener{
//#param cont & cont2 are data sent from MyFragment
#Override
public void sendData(type cont, type cont2){
//do what ever with your values here
}
}
got it now?

How to call a method from one tab to another?

i have a tabActivity that hold 3 tabs.
from one tab i want to open another tab and run a method that refresh the data.
i use this method to switch tabs
public void switchTabInActivity(int indexTabToSwitchTo) {
MyTabsActivity ParentActivity;
ParentActivity = (MyTabsActivity) this.getParent();
ParentActivity.switchTab(indexTabToSwitchTo);
}
to open the tab but i cant' call the method.
any ideas?
According to me, I believe what you are doing here is correct, but still you are not doing the entire flow. Let me explain,
Calling the above method will redirect you to that particular tab. But what you actually have to do is to execute some method in that class. But were are you calling that method.
Consider a Activity with onCreate(),
you could have called that method in your onCreate(). But now when you execute your
public void switchTabInActivity(int indexTabToSwitchTo) {
MyTabsActivity ParentActivity;
ParentActivity = (MyTabsActivity) this.getParent();
ParentActivity.switchTab(indexTabToSwitchTo);
}
method, this will call the onResume() of that activity. So my suggestion would be to override the onResume method of your particular activity which has that method..
you can simply create a static method which can be easily call by using ClassName.methodName();
see example,
public class myAnotherClass
{
public static void accessFromAnotherClass()
{
System.out.println ( "I am accessed publically" );
}
}
// Now Accessing above class method from another class file
public class myFirstClass
{
private void myClassMethod()
{
myAnotherClass.accessFromAnotherClass(); // called from another class. in your case , another tab.
}
}

Categories

Resources