0

我有一个 LinearLayout,它占据了屏幕的整个底部,就像 Mac OSX 扩展坞或 Windows 的任务栏一样。我在没有 xml 的情况下以编程方式创建它,因为内容将是动态的。但是,我对图标(即 ImageView 对象)的定位有疑问。我想指定图标之间的距离(我希望一些图标彼此更近,一些更远..也可以选择在开始或结束时保留一些空间),但是 setMargins、setGravity 等都是失败,没有明显的视觉变化。

这是它目前的样子:

当在 LayoutParams 中指定权重时,5 个图标均匀分布在整个 LinearLayout 中

这适用于 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 );

如果未指定重量:

当 LayoutParams 中未指定权重时,5 个图标占用相同空间

这适用于 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 );

问题:

  1. 如何控制 LinearLayout 内 ImageView 之间的距离?你能解释一下用来控制它的代码吗?我一直在徒劳地搜索Android文档...

  2. 谁能解释 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);
            }
        }

    }

}
4

1 回答 1

0

感谢@Luksprog 和@OnurA。以获得评论中的见解和帮助。我最终将孩子的宽度和高度设置为 WRAP_CONTENT,LinearLayout 设置为水平,并将权重设置为 1。然后我将孩子的 LayoutParam 的宽度和高度设置为所需的高度和高度,这样,我设法控制给孩子的定位。

谢谢大家的帮助!

于 2013-07-16T06:39:09.650 回答