Reputation: 449
In my \drawable-mdpi
folder, I have an image named: test.jpg
In my main.xml
file, in my LinearLayout section, I have:
<ImageView
android:id="@+id/test_image"
android:src="@drawable/test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
In my src folder, I have only 1 file, HelloAndroidActivity.java
with only the following method:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView image = new ImageView(this);
image = (ImageView) findViewById(R.id.test_image);
setContentView(image);
}
This seems to be correct, yet whenever I try to run it, I get The application HelloAndroid (process xxxxx) has stopped unexpectedly. Please try again.
The strange part is it previously did display the image, but now it won't and I don't know why.
Also, when I comment out the ImageDisplay code, and replace it with TextDisplay code. i.e.
TextView tv = new TextView(this);
tv.setText("Does this work?");
setContentView(tv);
It does display the text.
Edit: was asked to post logcat. Link to pastebin.
Upvotes: 1
Views: 9336
Reputation: 17342
This is going to sound harsh, but this is when I take the knife out of your hand and say you should do a little more reading or whatever:
setContentView(R.layout.main);
ImageView image = new ImageView(this);
image = (ImageView) findViewById(R.id.test_image);
setContentView(image);
You've set the content view to an xml layout. That's cool. Then you create a new ImageView instance in code, which is OK but probably a little over your skill level just now.
You then overwrite the ImageView you just created with one you pulled from the layout that Android has inflated for you from your original setContentView call. This makes no sense. Just do this.
setContentView(R.layout.main);
ImageView image = (ImageView) findViewById(R.id.test_image);
Finally, you overwrite the content view for the whole Activity with the image reference you pulled from within the content view for the current Activity. Do not do this. It makes no sense. My guess is that your exception is either that you're resetting the content view, or that you're trying to set the content view with a view that already exists in another view.
Are you trying to dynamically set the image that shows up? If not, if you're just trying to "show" the image, do this.
setContentView(R.layout.main);
That's it.
Upvotes: 3
Reputation: 28932
setContentView
and findViewById
don't do what you think they do.
setContentView
sets the given view as the top-level, root view of your activity. Usually you set it to a layout that defines a hierarchy of many nested views. If you give it a layout resource, that layout will be inflated into new views. If you give it an existing view, that existing view instance will be used.
Activity#findViewById
performs a tree search across the current view hierarchy for your activity's window, starting at the root. If it can find a view somewhere in the hierarchy with the given id, that view is returned. If it can't be found the function returns null.
So with those things in mind, let's step through your code:
setContentView(R.layout.main);
- Inflates your main layout and sets it as your activity content. Looks good so far.
ImageView image = new ImageView(this);
- Creates a new ImageView. Nothing technically wrong with this but probably not what you want because...
image = (ImageView) findViewById(R.id.test_image);
- Searches through the current view hierarchy (the one where you inflated R.layout.main above) for a View with the id test_image. This overwrites your image
variable, throwing out the new ImageView
you created on the line above to be garbage collected.
setContentView(image);
- Attempts to set the view with id test_image as the root of your activity's view hierarchy, overwriting the hierarchy you inflated in your first setContentView call. I'm guessing that if you check the stack trace from the exception, your app is crashing because at this point image
already has a parent view and you're trying to give it a new one without removing it from its current parent first.
Once a view has been attached to the hierarchy you do not need to re-add it when content changes. Simply change the content in-place if that's what you want to do. Calling setContentView
more than once is a very unusual thing to do. In the vast majority of cases it's unnecessary.
Since your main layout already specifies the drawable you want in your ImageView your onCreate
can be shortened to just the first two lines to simply show the image:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.id.main);
}
Upvotes: 1