I'm trying to customize a relative layout during onCreate() and am having problems because ImageView's getWidth() and getHeight() properties return zero. Several threads here say that this is because the layout hasn't been drawn yet, so it is too early to know the actual image dimensions.
At what point in the lifecycle should I be doing this?
This is what I'm trying to accomplish, without hard-coding the image width:
Here's the app's layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="#44000000"
>
<RelativeLayout
android:id="@+id/bannerAdLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="60dip"
android:orientation="horizontal"
android:clickable="true"
android:background="#00000000"
>
<LinearLayout android:id="@+id/bannerAdActionButtonLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:background="#ff00ff00"
>
<!-- NOTE: image's left margin set at run-time -->
<ImageView android:id="@+id/bannerAdThumbnail"
android:contentDescription=""
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"
/>
</LinearLayout>
<!-- NOTE: layout's left margin set to 50% of screen width at run-time -->
<LinearLayout android:id="@+id/bannerAdTextLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:background="#ffffffff"
>
<TextView android:id="@+id/bannerAdInstructions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:text="First line of text"
/>
<TextView android:id="@+id/bannerAdTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:text="Second line of text"
/>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
And code from onCreate() to customize the layout and set the imageview's left margin so that it is positioned to the left of center:
private Context mThisActivityContext = null;
private Resources mResources = null;
private ImageView mBannerAdImage = null;
private TextView mBannerAdLabel = null;
private TextView mBannerAdOffer = null;
private RelativeLayout mBannerAdLayout = null;
int mBannerAdImageWidth = 48; // set a default width
// Screen dimensions
private int mScreenHeight;
private int mScreenWidth;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mThisActivityContext = MainActivity.this;
mResources = mThisActivityContext.getResources();
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// get screen dimensions
mScreenHeight = mThisActivityContext.getResources().getDisplayMetrics().heightPixels;
mScreenWidth = mThisActivityContext.getResources().getDisplayMetrics().widthPixels;
Log.w(TAG, String.format("Device screen dimensions are: %d w x %d h", mScreenWidth, mScreenHeight));
// get the banner ad layout
mBannerAdLayout = (RelativeLayout)findViewById(R.id.bannerAdLayout);
// get the image to use for the banner ad
mBannerAdImage = (ImageView)findViewById(R.id.bannerAdThumbnail);
GetImageFromAsset(mResources, mBannerAdImage, "ic_launcher");
Log.w(TAG, String.format("Image ic_launcher dimensions are %d W x %d H", mBannerAdImage.getWidth(), mBannerAdImage.getHeight()));
// get the banner ad TextView controls
mBannerAdLabel = ((TextView)findViewById(R.id.bannerAdInstructions));
mBannerAdOffer = ((TextView)findViewById(R.id.bannerAdTitle));
// initialize the banner ad layout
initBannerAdLayout();
}
// set an image's bitmap from the specified asset
private void GetImageFromAsset(Resources res, ImageView image, String assetName) {
try {
int drawableId = res.getIdentifier(assetName, "drawable", "com.example.animationtest");
Bitmap bMap = BitmapFactory.decodeResource(res, drawableId);
image.setImageBitmap(bMap);
if (image.getWidth() > 0) {
mBannerAdImageWidth = image.getWidth();
}
}
catch (Exception e) {
Log.e(TAG, "Failure to get drawable id for " + assetName, e);
}
}
// initialize the Banner Ad layout based on the screen dimensions
private void initBannerAdLayout() {
// reset the background color
mBannerAdLayout.setBackgroundColor(Color.TRANSPARENT);
// use margin layout parameters to set the position of the action button within its LinearLayout
int marginLeft = (int)(mScreenWidth * 0.5) - mBannerAdImageWidth;
MarginLayoutParams params = (MarginLayoutParams)mBannerAdImage.getLayoutParams();
params.setMargins(marginLeft, 0, 0, 0);
mBannerAdImage.setLayoutParams(params);
Log.w(TAG, String.format("Image left margin is %d, image width is %d", marginLeft, mBannerAdImage.getWidth())); // xxx
// use margin layout parameters to set the position of the inner text LinearLayout
LinearLayout bannerAdTextLayout = (LinearLayout)findViewById(R.id.bannerAdTextLayout);
marginLeft = (int)(mScreenWidth * 0.5);
params = (MarginLayoutParams)bannerAdTextLayout.getLayoutParams();
params.setMargins(marginLeft, 0, 0, 0);
bannerAdTextLayout.setLayoutParams(params);
Log.w(TAG, String.format("Text layout left margin is %d", marginLeft));
mBannerAdLayout.invalidate();
}
Create a bitmap from the drawable resource.
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
Once you have the bitmap, you can get the image dimensions through bitmap.getWidth() & bitmap.getHeight().