Getting the Activity inside Adapter in Android - java

I am trying to access the activity on which my Imageview is, so I can use the URL of an Image of type SVG and display it to the user using the GlideToVectorYou library.
GlideToVectorYou.justLoadImage(activity, IMAGE_URI, targetImageView)
But when I try to get access to the activity using R.layout.activityname, a syntax error appears.
this is the code that I'm using
Uri myurl = Uri.parse(match.getFlag());
GlideToVectorYou.justLoadImage(R.layout.item_basketball, myurl, iv_location);
Thank you!

R.layout.item_basketball is just an integer ID for your activity layout - not the activity instance itself. If you want the activity in your adapter you would need to pass it in when you construct the adapter and save it as a class member (example below), or check if your adapter base class already can provide it via getActivity() or getContext() or a similar method.
class MyAdapter(private val activity: Activity) : BaseAdapter() {
fun someMethod() {
// then you can access "activity" in your adapter methods
GlideToVectorYou.justLoadImage(activity, IMAGE_URI, targetImageView)
}
}
and when you create it in your Activity, you would just do something like this
val adapter = MyAdapter(this)

You need a activity reference. R.layout.somethinghere is the layout reference.
On your adapter constructor add a activity parameter and use it inside the adapter.
If you call adapter constructor from an activity, just pass "this" as parameter. If call from a fragment, use "requireActivity" (if using kotlin) or analogous method (getActivity, for example) if using Java

Related

Passing data between Parent fragment and Child fragment

I'm struggling with a communication between 2 or more fragments
My application architecture looks like this:
MainActivity (Menu Drawer)
----> MealsFragment
----> ProfileFragment
----> StatsFragment
----> SportFragment
----> ContactUsFragment
(By clicking on menu drawer main_container is replaced with selected Fragment)
Earlier, I had single activities instead of fragments but I have read that I need to convert them into Fragments to correctly implement menu drawer (so I did it).
The problem is each of the activities had its own child-activities which were communicating with parents with using onActivityResult. Now I don't know how to do it with fragments.
The scenario is like this:
Open MealsFragment from MainActivity (it works)
Open AddMealFragment from MealsFragment (with data from MealsFragment), fill the form and then return all information provided there by user to MealsFragment
Use received data for further actions
I have already seen posts recommending using settargetFragment() and getTargetFragment() but I don't know how to do it and - what is more important - I don't know how to receive the data afterwards
I hope you are aware of how to do Fragment transactions, i.e. using Fragment Manager class to add or remove fragments from the backstack. If you don't know then it's a good idea to learn that first.
Now that you know how to add or remove fragments, passing data among them is a simple thing of all of that in fragment's Bundle that you can access in the receiver fragment. Here's an example:
class ConversationFragment : Fragment() {
companion object {
const val JOB_REQUEST_ID = "jobRequestId"
#JvmStatic
fun newInstance(jobRequestId: String) =
ConversationFragment().apply {
arguments = Bundle().apply { putString(JOB_REQUEST_ID, jobRequestId) }
}
}
}
In order to create ConversationFragment, I expose a newInstance method that the FragmentManager or any other entity can use to create one. However, they would need to pass a JOB_REQUEST_ID in order to create one. I simply put this id in a Bundle and pass it on to the fragment as its argument. On the receiver side(fragment), you can get a handle to this bundle and retrive the value:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
jobRequestId = it.getString(JOB_REQUEST_ID)
}
}

Can't call a method from MainActivity

Basically i need to call a method, which refreshes the username in my NavigationBar. I try to call it from another activity SettingsActivity.java, where the user changes his name.
SettingsActivity.java:
// ...
MainActivity tempActivity = new MainActivity();
tempActivity.refreshNBName();
// ...
When i do this i get this exception:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference
I've tried to do this another way:
((MainActivity)getApplicationContext()).refreshNBName();
But this throws another exception:
java.lang.ClassCastException: com.justnothing.nisser.debbie.GlobalVariables cannot be cast to com.justnothing.nisser.debbie.MainActivity
The method that i'm trying to call here looks like this:
public void refreshNBName(){
NavigationView nV = (NavigationView) findViewById(R.id.nav_view);
View headerView = nV.getHeaderView(0);
TextView local_user = (TextView) headerView.findViewById(R.id.actualUser);
local_user.setText(((GlobalVariables) getApplication()).name + " " + ((GlobalVariables) getApplication()).surname);
}
What should i do here? Any help or advice is appreciated!
You wrote this which is not applicable.
MainActivity tempActivity = new MainActivity();
tempActivity.refreshNBName();
Because this is creating new instance of MainActivity class. not referring to the live instance of MainActivity.
You tried another thing, you can't even do this.
((MainActivity)getApplicationContext()).refreshNBName();
Because getApplicationContext will return you context of application class which is not MainActivity.
I have gone through your question, you need not call any method from another activity. If you want update navigation drawer. You can call refreshNBName() on onResume() of MainActivity.class.
So every time user comes back to MainActivity, navigation view will update automatically.
You can create static method in MainActivity and than call the method like this MainActivity.someMethod() but i don't recommend this ! it can lead to memory leak and lots of exception to handle
if your main activity is not alive and is in the pause,stop,destory state there is no point to refreshing the view in main activity and you can always refresh the view to latest data when activity state changed to resume by overwriting onResume method in activity .
and finally i think best way to communicating with activates and fragment is using callback for more information see this link :
https://developer.android.com/training/basics/fragments/communicating.html

Parent fragment to Child Fragment communication

I have been searching and haven't found the best way for nested fragments to communicate with parent fragment. The Android documentation states that:
All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.
Suppose I have a Gallery app, there is a ViewPagerFragment (parent) and ImageFragment(child) that is used to show images full screen when they are clicked. I need to pass an ArrayList of Files from my parent fragment to the child fragment. What is a proper way to do it?
1) Create a getter for the ArrayList in parent fragment and use the getParentFragment() in a child fragment to access this method?
2) Implement an interface and go through the Activity, but how will I locate the child fragment from the Activity if it doesn't have an ID?
3) Or use this in parent fragment:
ChildFragment fragment =(ChildFragment)getChildFragmentManager().findFragmentById(R.id.child_fragment_id);
And just use a setter in child fragment.
But again how do I get the ID of the childFragment?
Thanks everyone in advance
If you want to communicate with your child Fragment to your parent Fragment you can use getParentFragment() method from your child fragment.
Example
public class ExampleParentFragment extends Fragment {
public int getCount() {
return 10;
}
}
public class ChildFragment extends Fragment {
void doAction() {
Fragment parentFragment = getParentFragment();
if(parentFragment instanceof ExampleParentFragment) {
int count = ((ExampleParentFragment) parentFragment).getCount();
}
}
}
I understand that the Fragment to Fragment communication through the activity is for sibling fragments which are coordinated by the same activity.
In this case the siblign fragments are coordinated by a parent fragment, so I would say that the communication should be managed by the parent fragment.
If you are working directly with the fragments then you do that using the ChildFragmentManager().
If you are working with a ViewPager you pass the ChildFragmentManager to the ViewPager insted of passing it the FragmentManager.
If you have to pass a List, I think the easiest is for the ChildFragment to request it when it is ready to receive it by calling a method on the ParentFragment. It can allways get its instace with getParentFragment().
I am not sure where is the safest place to call getParentFrament() to get the list but you can try in onCreateView() ,in onActivityCreated(), o in onResume().
To call the method that returns the list, you can cast the parent Fragment to the specific Fragment class you have extended, or else you can define an interface with the method that returns the List and make your extended parent Fragment implement it.
Then in the child Fragment, you refert to the parent by the interface to call the method and get the list.
Data should be passed to fragments using Bundle as arguments. So just pass the Arraylist(serialized or otherwise) to your child fragment when launching it

How can I use my global variable inside an Adapter class? Android

Hi i'm trying to pass a value by using Global Variable. I have created a class file where it is extended to Application and then add it on my Manifest.
public class MyApplication extends Application {}
After that I had created an Adapter Class which is extended to BaseExpandableListAdapter, I've search on how to set and get the global variable i've created and found this
((MyApplication) getActivity().getApplication()).setMy_id(my_id);
and to be able to get the value I use this
Integer my_id = ((MyApplication) getActivity().getApplication()).getMy_id();
In my Fragments, I can use my getMy_id() method but when putting it inside the BaseExpandableListAdapter, I'm having an error in getActivity(). I already tried using this but still it says Cannot resolve method getApplication(), is there any other way to get the value of my global variable.
I'm doing this because I'm trying to use Cursor for my ListView. I wanted to create a Expandable ListView where the data is from my database and my Cursor have a parameter for it's WHERE condition where my data in my global variable will be used.
The reason why I'm using it as a global variable because I use this data in different Fragments where it is not static it changes its value depends on the selected item.
Thank you in advance.
You need to have a constructor in your class that extends BaseExpandableListAdapter. The defined constructor should receive a parameters of Context type. Here is the example -
private Context mContext;
public YourExpandableListAdapter(Context context) {
mContext = context;
Integer my_id = ((MyApplication) context.getApplicationContext()()).getMy_id();
}
Now create an instance like this in your activity -
YourExpandableListAdapter ob = new YourExpandableListAdapter(this);
This should work.
I'm not really sure what you're trying to achieve but whatever it is you're doing seems hacky to me! As per answering your question, getApplication() needs a context, so when you do
((MyApplication) getActivity().getApplication())
You are essentially using the activitiy's(getActivity()) context. And you cannot call getActivity() in an Adapter class. Try passing the context of your activity from the activity to the adapter in your constructor, something like.
MyAdapter myAdapter = new MyAdapter(this); //This line will be in your activity, and this will be the instance of your activity
And your adapter constructor would look something like
public MyAdapter(Context context){
//Use this context to get the application instance, something like
Integer my_id = ((MyApplication) context.getApplication()).getMy_id();
}
For Me, all above didn't work. try this:
((MyApplication) context.getApplicationContext()).getMy_id();

Android: how can fragment take a global variable of Activity

I have an activity with a global variable int x, how can a fragment get the current value of variable x of its activity ?
Either set the var as public static, or use
((MyActivity)getActivity()).getX()
Using a public static variable isn't the best way to communicate between an activity and a fragment. Check out this answer for other ways:
The Android documentation recommends using an interface when the Fragment wants communicate with the Activity. And when the Activity wants to communicate with the Fragment, the Activity should get a reference to the Fragment (with findFragmentById) and then call the Fragment's public method.
The reason for this is so that fragments are decoupled from the activity they are in. They can be reused in any activity. If you directly access a parent Activity or one of its global variables from within a fragment, you are no longer able to use that fragment in a different Activity.
Kotlin version:
(activity as MyActivity).x
***In your Activity
==================
Bundle args = new Bundle();
args.putInt("something", Whatever you want to pass);
fragA.setArguments(args);
In your Fragment
==================
Bundle args = getArguments();
//whatever you want to get ,get it here.
//for example integer given
int index = args.getInt("index", 0);

Categories

Resources