I have a LinearLayout that is occupying the entire lower bottom of the screen, just like Mac OSX dock or Windows' taskbar. I'm creating it programmatically without xml as the content will be dynamic. However, I'm having problem with the positioning of the icons (which is ImageView objects). I'd like to specify the distance between the icons (I want some icons to be closer to each other, and some farther away.. also optionally to retain some space in the beginning or the end), but setMargins, setGravity, etc all failed with no apparent noticable visual changes.
This is how it is currently looked like:
this is applied to the LinearLayout:
setOrientation( LinearLayout.HORIZONTAL );
this is applied to the ImageView (icons within the LinearLayout):
LayoutParams lp = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, (1) ); // weight has to be specified, otherwise only will show 1 icon
imageIcon.setGravity( Gravity.CENTER_HORIZONTAL );
If weight is not specified:
this is applied to the LinearLayout:
setOrientation( LinearLayout.HORIZONTAL );
this is applied to the ImageView (icons within the LinearLayout):
LayoutParams lp = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT /* , (1) */); // weight has to be specified, otherwise only will show 1 icon
imageIcon.setGravity( Gravity.CENTER_HORIZONTAL );
The question:
How do I control the distance between the ImageView inside the LinearLayout? Would you please explain about the code used to control it? I've been searching in the Android doc in vain...
Could anyone explain the magical thing the "weight" param in LayoutParams do? I've spent very long time debugging the missing ImageView and find through trial and error the magic "weight" param, but still can't figure out why it does such powerful thing without clear explanation in the documentation
EDIT: Inserted code for the LinearLayout (The green Container)
public class GameSliderView extends LinearLayout {
private Context mContext;
private Vector<GameEntryView> mGameEntries;
public GameSliderView(Context context) {
super(context);
mContext = context;
mGameEntries = new Vector<GameEntryView>();
setOrientation( LinearLayout.HORIZONTAL );
}
public void addGameEntry( String szIconUrl ) {
GameEntryView gameEntry = new GameEntryView(mContext);
LayoutParams lp = new LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT );
this.setGravity( Gravity.CENTER_HORIZONTAL );
// lp.setMargins( 0, 0, 0, 0 );
gameEntry.setLayoutParams( lp );
gameEntry.loadIcon( szIconUrl );
gameEntry.requestLayout();
mGameEntries.add( gameEntry );
addView( gameEntry );
}
}
The Game Icon:
public class GameEntryView extends RelativeLayout {
private Context mContext;
private GameIconView mGameIcon;
// private ImageView mNewIcon;
private String mIconUrl;
public GameEntryView(Context context) {
super(context);
mContext = context;
}
@Override
protected void onLayout( boolean changed, int l, int t, int r, int b ) {
int iChildCount = this.getChildCount();
for ( int i = 0; i < iChildCount; i++ ) {
View pChild = this.getChildAt(i);
pChild.layout(0, 0, pChild.getMeasuredWidth(), pChild.getMeasuredHeight());
}
}
@Override
protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec ) {
int iParentWidth = MeasureSpec.getSize( widthMeasureSpec );
int iParentHeight = MeasureSpec.getSize( heightMeasureSpec );
this.setMeasuredDimension( iParentWidth, iParentHeight );
int iChildCount = this.getChildCount();
for ( int i = 0; i < iChildCount; i++ ) {
View pChild = this.getChildAt(i);
this.measureChild(
pChild,
MeasureSpec.makeMeasureSpec( iParentWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec( iParentHeight, MeasureSpec.EXACTLY)
);
}
}
public void loadIcon( String szUrl ) {
mGameIcon = new GameIconView( mContext );
addView( mGameIcon );
ImageManager.getInstance( mContext ).get( szUrl, new OnImageReceivedListener() {
@Override
public void onImageReceived(String source, Bitmap bitmap) {
mGameIcon.setImageBitmap( bitmap );
mGameIcon.setLayoutParams( new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT ) );
postInvalidate();
}
});
}
public String getIconUrl() {
return mIconUrl;
}
/**
* @author Hakim Hauston
* @desc Resizable ImageView - surprised that Android library did not include this?
* @ref http://stackoverflow.com/questions/5554682/android-imageview-adjusting-parents-height-and-fitting-width
*/
class GameIconView extends ImageView {
public GameIconView(Context context) {
super(context);
}
@Override
protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec ) {
Drawable d = getDrawable();
if ( d != null ) {
float fScale = 0.90f;
int iHeight = (int) (MeasureSpec.getSize( heightMeasureSpec ) * fScale);
int iWidth = (int) ((iHeight * d.getIntrinsicWidth() / d.getIntrinsicHeight()) * fScale);
setMeasuredDimension( iWidth, iHeight );
Log.d("GameEntryView", "GameEntryView.onMeasure: measureSpec: (" + widthMeasureSpec + ", " + heightMeasureSpec + ");");
Log.d("GameEntryView", "GameEntryView.onMeasure: intrinsic: (" + d.getIntrinsicWidth() + ", " + d.getIntrinsicHeight() + ");");
Log.d("GameEntryView", "GameEntryView.onMeasure: calculated: (" + iWidth + ", " + iHeight + ");");
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
}