Mac OSX ドックや Windows のタスクバーと同じように、画面の下部全体を占める LinearLayout があります。コンテンツが動的になるため、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);
}
}
}
}