我有一个 LinearLayout,它占据了屏幕的整个底部,就像 Mac OSX 扩展坞或 Windows 的任务栏一样。我在没有 xml 的情况下以编程方式创建它,因为内容将是动态的。但是,我对图标(即 ImageView 对象)的定位有疑问。我想指定图标之间的距离(我希望一些图标彼此更近,一些更远..也可以选择在开始或结束时保留一些空间),但是 setMargins、setGravity 等都是失败,没有明显的视觉变化。
这是它目前的样子:
这适用于 LinearLayout:
setOrientation( LinearLayout.HORIZONTAL );
这适用于 ImageView(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 );
如果未指定重量:
这适用于 LinearLayout:
setOrientation( LinearLayout.HORIZONTAL );
这适用于 ImageView(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 );
问题:
如何控制 LinearLayout 内 ImageView 之间的距离?你能解释一下用来控制它的代码吗?我一直在徒劳地搜索Android文档...
谁能解释 LayoutParams 中“重量”参数的神奇之处?我花了很长时间调试丢失的 ImageView 并通过反复试验找到了神奇的“重量”参数,但在文档中没有明确解释的情况下仍然无法弄清楚为什么它会做如此强大的事情
编辑:为 LinearLayout 插入代码(绿色容器)
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 );
}
}
游戏图标:
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);
}
}
}
}