I'm very new to Android and Java coding in general, so bear with me if I don't understand basic concepts.. This is just a test to see if something works, so It might not initially make any sense.
I have two activities, Main and Other.
the Other Activity has an imageButton with visibility initially set to invisible.
When MainActivity is created, it should look for that imageButton in the Other activity, and set it's view to visible.
Though when debugging, all I get is a nullPointerException, because the button has null as value. How can I make it reference the button?
Part of Main Activity:
public class MainActivity extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pstep();
}
public void pstep() {
int pstep = 0;
ImageButton panfav = (ImageButton) findViewById(R.id.favpancake);
panfav.setVisibility(View.VISIBLE);
}
Part of Other Activity:
public class navfav extends AppCompatActivity {
ImageButton panfav = (ImageButton) findViewById(R.id.favpancake);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.navfav);
}
public void fab(View v){
ImageButton panfav = (ImageButton) findViewById(R.id.favpancake);
panfav.setVisibility(View.VISIBLE);
}
XML linked to Other Activity:
<ImageButton
android:id="#+id/favpancake"
android:layout_width="wrap_content"
android:layout_height="137dp"
android:layout_alignParentStart="true"
android:layout_below="#+id/imageView3"
android:background="#android:color/background_dark"
android:contentDescription="#string/nav_cook_dish"
android:onClick="fab"
android:scaleType="centerCrop"
android:src="#drawable/dishpancake"
android:visibility="invisible" />
Log:
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.widget.ImageButton.setVisibility(int)' on a null object reference
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method
'void android.widget.ImageButton.setVisibility(int)' on a null object reference
at com.p2.rookie.MainActivity.pstep(MainActivity.java:23)
at com.p2.rookie.MainActivity.onCreate(MainActivity.java:16)
Shoot if I'm missing anything you need to use, I'll provide as much as i can :)
Best
The visibility of the buttons are always "VISIBLE", please give me the log
and in the navFav activity the "fab" method are not in the onCreate
you are getting nullPointerException because ImageButton with id favpancake is not present in MainActivity layout activity_main
public class navfav extends AppCompatActivity {
public static List<String> recipes;
// other code here
}
and then when you want to add recipe to shown in Other Activity listView,
recipes = new ArrayList<String>();
recipes.add(recipe);
Now when you open the other Activity all those recipes will be available in list name "recipes". which you can use to show in your listView.
One Activity can and should not reference elements in other Activities.
If you call 'setContentView' with a layout file, you can only reference the views in that layout file.
Try and tell us what you're trying to achieve and we might be able to help you out in improving your code.
(Posted on behalf of the OP).
Just read a bunch of other stuff elsewhere, and I think something made sense now! Instead of creating new intents and startActivity'ies when changing layout/pages, I just setContentView to new layouts/pages, and gather all methods from different activities in one activity - That's how basic this fail was I think? ;)
Then all views and methods can reference each other.
Related
I basically want to change the visibility of some xml elements in my fragment when the "onRewardedVideoAdRewarded" method in my MainActivity gets called.
Here is the onRewardedVideoAdRewarded method in my MainActivity.java:
#Override
public void onRewardedVideoAdRewarded(Placement placement) {
MyFragment myFragment = new MyFragment();
myFragment.rewardedVideoFinished();
}
and here is the "rewardedVideoFinished" method of my Fragment:
public void rewardedVideoFinished (){
myButton.setVisibility(View.INVISIBLE);
...
}
I'm initializing the button in my fragment's onCreateView method like this:
final View rootView = inflater.inflate(R.layout.tablayout_rewarded,container,false);
myButton = rootView.findViewById(R.id.mybutton);
When the Rewarded Video Ad finishes and the "onRewardedVideoAdRewarded" gets called, the app crashes with the following message:
"java.lang.NullPointerException: Attempt to invoke virtual method
'void android.widget.Button.setVisibility(int)' on a null object
reference"
I know what NullPointerExceptions are and I know that "myButton" is not initialized when I call it, but why is this the case? I thought with making a new instance of my Fragment it gets initialized.
How can I fix the problem and make the view in my fragment invisible when the rewarded video ad finishes?
Thanks.
I want to use a view in multiple activities. In my case it's a FloatingActionButton. The moment I am searching for the view via findViewById the program throws a NullPointerException. How do I get access to the FloatingActionButton?
As the button should always be the same, I created a XML Layout only including the FloatingActionButton inside a mergeroot element to reduce overhead when using ìnclude.
floating_button.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/include_merge" >
<android.support.design.widget.FloatingActionButton
android:id="#+id/addBloodDonation"/>
</merge>
To use this in my other XML Layouts I use the include tag
XML Activitiy Layouts that should include the FloatingActionButton
<include
android:id="#+id/include_merge"
layout="#layout/floating_button" />
That works so far.
To have the same functionality in all my Activities, I created a BaseActivity which my other classes inherit from, e.g. my MainActivity.
BaseActivity
public abstract class BaseActivity extends AppCompatActivity {
public FloatingActionButton fab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View include_merge = findViewById(R.id.include_merge);
fab = include_merge.findViewById(R.id.addBloodDonation);
}
}
MainActivity (exemplarily)
public class MainActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
When starting the application I receive a NullPointerException in BaseActivity for trying to find the inner element as the View variable include_merge is null.
As I read here the include tag and the root element should have the same android:id. Is there a difference when using a merge as root element? And is it even possible to convert a merge tag into a View.
Do I need to make use of setContentView in the BaseActivity as its onCreate method is called before the one of MainActivity?
Edit:
Added setContentView(R.layout.activity_main); to BaseActivity as mentioned in the comments which still does not fix it.
You don't have to set an id to the <include> or <merge> tag. Just remove it as well as findViewById(R.id.include_merge). The <merge> tag indicates that all its views are added to the container of the <include> tag. Thus there's no View with the id you've set to it. But you can directly find the FAB.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fab = include_merge.findViewById(R.id.addBloodDonation);
}
I have been doing this for all my activities when I reference an element from my UI, I create a class variable. This can sometimes lead to 10 - 20 class variables just for UI elements:
public class CommentActivity extends AppCompatActivity {
LinearLayout addComment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_comment);
addComment = (LinearLayout) findViewById(R.id.addcomment);
addComment.setOnClickListener( // add an onclick listener here //);
}
}
Now, I have observed by looking at other people's code that sometimes they would do this instead:
public class CommentActivity extends AppCompatActivity {
// LinearLayout addComment; no more reference to class variable
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_comment);
//they just findViewById and add on the onclick listener
findViewById(R.id.addcomment).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
}
Is the second method more memory efficient? There is no longer a class variable strong reference and therefore garbage collection can happen more easily. But I'm just wondering what the risk is of using the second method. If garbage collection happens when using the app, does the addComment linearLayout lose its click functionality?
I'm just trying ways to optimise my app's memory use.
Is the second method more memory efficient?
Not particularly. The LinearLayout addComment reference costs ~8 bytes.
There is no longer a class variable strong reference and therefore garbage collection can happen more easily
Not in this case, since other things are holding onto the LinearLayout. After all, findViewById() is getting the LinearLayout from somewhere.
I got this weird problem and it's bugging me. I don't understand why I get this NullPointerException when I did initialise chronometer in MainActivity. If I initialise chronometer in SecondActivity the program works fine.
Hopefully someone can clear this up...
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Chronometer.setOnChronometerTickListener(android.widget.Chronometer$OnChronometerTickListener)' on a null object reference
-
public class MainActivity extends AppCompatActivity {
protected Chronometer chronometer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//chronometer gets initialised here but it's still null appearantly
chronometer = (Chronometer) findViewById(R.id.chronometer1);
//this works
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#cd2626")));
}
}
-
public class SecondActivity extends MainActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
//if chronometer gets initialised again, program does work.
//chronometer = (Chronometer) findViewById(R.id.chronometer1)
}
}
include setContentView(R.layout.main_layout); in your mainactivity otherwise findviewbyid will not be able to find chronometer and it will always show null exception
Your chronometer variable is not initialized in MainActivity.onCreate because layout is inflated (setContentView called) only in SecondActivity.onCreate. So findViewById in your MainActivity has no effect.
In general I recommend not to build class hierarchies aroun Activity. Try to use something else, like interfaces to achieve what you need.
I'm new to Java and I encountered the following code:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = new Button(this);
button.setText("Touch That!");
button.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
MainActivity.this.onButtonClick(v);
}
});
RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.rootlayout);
relativeLayout.addView(button);
}
public void onButtonClick(View view){
//do something when button is clicked.
}
}
I didn't understand the syntax, View.OnClickListener() c'tor is called and it is followed by {} and overidding method.
what does this syntax stand for?
to which object this refers?
My guess is the button. but if I'm right why to use MainActivity.this instead of this? (the object that invoked the method)
This is an anonymous class declaration. It means that you will override some methods inside the class dynamically.
Take a look at this arcticle:
http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
About your second question, MainActivity.this refers to the instance of the Activity you are currently in. If you call only this, it would refer to the actual object. When you call MainActivity.this, you will get the instance of MainActivity you are in, even if there is more activities created. Take a look at Android's activity lifecycle.
What's the difference between this and Activity.this
Hope it helps.
By calling
new View.OnClickListener(){}
you are creating an object implementing interface OnClickListerner that requires you to implement the click method.
Someone can correct if I am wrong.