Android LinearLayout保证金 - 无法调整

时间:2013-07-12 06:10:48

标签: android layout view android-linearlayout

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

目前的情况如下:

5 icons distributed evenly across the whole LinearLayout, when weight is specified in LayoutParams

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

如果未指定重量:

5 icons occupying the same space, when weight is not specified in LayoutParams

这适用于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. 如何控制ImageView内部的距离 的LinearLayout?你能解释一下以前的代码吗? 控制它?我一直在Android doc中搜索...

  2. 有人能解释LayoutParams中“重量”参数的神奇之处吗?我花了很长时间调试丢失的ImageView,并通过反复试验找到神奇的“重量”参数, 但仍然无法弄清楚为什么没有这么强大的东西 文档中明确的解释

  3. 编辑:插入的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);
                }
            }
    
        }
    
    }
    

1 个答案:

答案 0 :(得分:0)

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

感谢大家的帮助!