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
Related
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
I am trying to fetch some API data to my app and I have two activities. The first one is a Splash Screen (like those used by google while your app gets loaded) and I want to know where to call finish() to end the activity.
public class SplashScreen extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AsyncDataFetch fetch = new AsyncDataFetch();
fetch.setContext(this);
fetch.execute();
}
}
I have moved all my code in my AsyncTask so I don't block the ui thread and now I can't call finish() there, or I don't know how.
Why would I call finish for my app there instead of calling it on my activity you might ask... It is because it generates some sort of glitch if I do this, because my API fetch takes about 1 second and showing and closing this activity takes less.
So, where should I call finish() and how?
You should call finish() in onPostExecute of Async Task after getting result from doInBackground().
If your activity you wanna finish is a splash srceen, you should put finish() at postExecute(), which should be overriden in your asyncsTask.
So if the user is on my app and they click home and go to several other apps and then come back, then the activity will be recreated and getActivity will be null when I call on it in my fragment.
A solution I found was to create a static variable and store getActivity in the onCreateView.
I feel like this isn't a good solution. Is there any other way that I can go about this?
I tried using a non static variable and storing it in OncreateView and onAttach, but getActivity will be null.
Here is the error I will get when I use getActivity if I don't save it as a static variable. I use it in my AsyncTask for ProcessDialog in my Fragment.
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources$Theme android.content.Context.getTheme()' on a null object reference
Thanks.
If you are sure that onAttach(Activity activity) also has null, then I suspect you have multiple instance of same fragment at the same time. Print the fragment instance in onResume and check the instances.
Are you implementing the method onActivityCreated? You should use getActivity inside this method.
Another workaround would be use onAttach to keep your Activity.
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = activity;
}
I am going through Head First Android Development and I am a bit confused with
this method --> findViewById(int id)
I have the below button in the file "activity_find_beer.xml" :
<Button
android:id="#+id/find_beer"
android:text="#string/find_beer"
android:onClick="onClickFindBeer" />
and the following code from the class FindBeerActivity.java which is taking the user selected beer and displaying the same in a textview.
public class FindBeerActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_find_beer);
}
//Call when the button gets clicked
public void onClickFindBeer(View view) {
//Get a reference to the TextView
TextView brands = (TextView) findViewById(R.id.brands);
//Get a reference to the Spinner
Spinner color = (Spinner) findViewById(R.id.color);
//Get the selected item in the Spinner
String beerType = String.valueOf(color.getSelectedItem());
//Display the selected item
brands.setText(beerType);
}
}
My Question is the method onClickFindBeer(View view) takes a View type of
object as a parameter , but in the xml i have just mentioned
android:onClick="onClickFindBeer" and when the user clicks the
button , the method onClickFindBeer gets invoked...Who is passing the object of
type View to the onClickFindBeer(View view) ...is it something
implicit ?
Second,on developer.android.com I see that the method
findViewById(int id) is both in the Activity class (
https://developer.android.com/reference/android/app/Activity.html
) and also in the View class
https://developer.android.com/reference/android/view/View.html
... It's not clear to me which class (Activity or View)
findViewById(int id) method is invoked when i call findViewById()
from onClickFindBeer(View view){}.
Would be highly obliged if someone could throw light on this.
Regards.
The method takes a View parameter as that is how it is implemented in a superclass of the Button class (It is public class Button extends TextView.). The views you add to XML are actually java classes. When you set a property to such an XML item, that constructs the object from the particular java class accordingly. The onClick method of the View class goes as onClick(View v). By setting an XML you just asked the Button class to look for the entered method but its signature is always with a View as a paramenter, which refers to the view clicked.
findViewById has to be called on a View group. But the Actyvity class implements it to search an item in view assigned to it by the setContentView() method.
It is done somewhat implicitly. When building your app, the XML file is actually converted into Java file. When you click the view, the view is passed into the onClickFindBeer(View view) function.
The findViewById() is being called here by the activity. You can see the method declaration by clicking on findViewByID while pressing Ctrl. For a view, you would have to call it using the view. For example,
view.findViewById();
Its called JAVA Reflection which is used by android
2.
As I know, main difference is that when you used OnClickListener from activity it is connected with partivular object such as Textview,Button
find_beer.setOnClickListener and below code is excuted when someButton is pressed.
While android:onClick = "onClickFindBeer" is used handle click directly in the view's activity without need to implement any interface
You have assigned the method onClickBeer to your button. When the button gets clicked, the object, in this case the button, is passed to the method you assigned to it. A Button is a type of View object, so you have a more generic View object as the parameter, but you are perfectly ok to caste it to a button object.
findViewById is called through a "context", which is a way of getting at system resources. You are asking the system to return to you a specific object, which you can then use. It is worth reading up on contexts.
Hope that answers some of your query.
Base on your sample above the android:onClick method is the one being invoked because when invoking a onclick method in java class, it need to call a onClickListener.
cause on the other question. as far as I know it belong to the view class because it always to reference an object on your design.
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);