我遇到问题从我指定的XML布局中以编程方式膨胀我的CustomView。
我有一个CustomView,它扩展了RelativeLayout并包含另一个RelativeLayout,它又包含2个ImageView和1个LinearLayout。 ImageViews是箭头图标,我通过android放置在父级的左侧和右侧:layout_alignParentLeft =“true”和android:layout_alignParentRight =“true”,而LinearLayout用于填充其间的所有空间。
为了说清楚,这里是Eclipse布局设计器中的xml布局视图,这是我想要的...
如果我是setContentView(R.layout.my_xml_layout);直接来自Activity,所有内容都显示在Eclipse Layout Designer中,但是,如果我从CustomView的构造函数中膨胀R.layout.my_xml_layout,则ImageView的左侧和右侧会有一个无法消失的顽固边距。
这是在java代码中完成的,并且存在问题:
任何帮助将受到高度赞赏!提前谢谢!
my_xml_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<ImageView
android:id="@+id/imageLeftArrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:src="@drawable/dock_leftarrow" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</LinearLayout>
<ImageView
android:id="@+id/imageRightArrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:src="@drawable/dock_rightarrow" />
</RelativeLayout>
</RelativeLayout>
我通过以下行在CustomView的构造函数中对它进行了膨胀:
View.inflate( mContext, R.layout.my_xml_layout, this );
我的CustomView的onLayout:
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// Do nothing. Do not call the superclass method--that would start a layout pass
// on this view's children. PieChart lays out its children in onSizeChanged().
Log.e("DrawView", "DrawView.onLayout: " + l + ", " + t + ", " + r + ", " + 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());
}
}
我的CustomView的onMeasure:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Try for a width based on our minimum
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.d("DockView", "DockView.onMeasure: width: " + widthMeasureSpec + " getWidth: " + MeasureSpec.getSize(widthMeasureSpec));
Log.d("DockView", "DockView.onMeasure: height: " + heightMeasureSpec + " getHeight: " + MeasureSpec.getSize(heightMeasureSpec));
Log.d("DockView", "DockView.onMeasure: getPaddingLeft: " + getPaddingLeft() + " getPaddingRight: " + getPaddingRight());
Log.d("DockView", "DockView.onMeasure: getPaddingTop: " + getPaddingTop() + " getPaddingBottom: " + getPaddingBottom());
// http://stackoverflow.com/a/17545273/474330
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)
);
}
}
答案 0 :(得分:1)
目前,我正在诉诸黑客。
我只将LinearLayout添加为CustomView的子视图。然后我手动渲染onDraw中的两个ImageView(Canvas c);我的CustomView的功能。为了使LinearLayout适合两个ImageView之间的剩余空间,我在CustomView的onLayout中计算LinearLayout的边距。
horizontal_dock_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@android:color/white" >
<ImageView
android:id="@+id/imageLauncher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"/>
</LinearLayout>
</RelativeLayout>
CustomView.java
/**
* Initialize the control. This code is in a separate method so that it can be
* called from both constructors.
*/
private void init() {
setWillNotDraw( false );
// Load the arrow bitmap
mArrowBitmap = ((BitmapDrawable)mContext.getResources().getDrawable(R.drawable.dock_leftarrow)).getBitmap();
ViewGroup pRootView = (ViewGroup) View.inflate( mContext, R.layout.horizontal_dock_view, this );
Log.d("DockView", "DockView.init: " + pRootView.getClass().getCanonicalName());
mIconContainerView = (LinearLayout) ((RelativeLayout)pRootView.getChildAt(0)).getChildAt(0);
Log.d("DockView", "DockView.init: " + mIconContainerView.getClass().getCanonicalName());
// if ( mArrowBitmap != null ) {
// // set the icon container margin
// float fWidth = this.getWidth(); // View's width
// float fHeight = this.getHeight(); // View's height
// float fScale = fHeight / mArrowBitmap.getHeight();
// float fArrowWidth = mArrowBitmap.getWidth() * fScale;
// float fArrowHeight = mArrowBitmap.getHeight() * fScale;
// Log.d("DockView", "DockView.init: " + fArrowWidth + ", " + fArrowHeight );
// ((RelativeLayout.LayoutParams)mIconContainerView.getLayoutParams()).setMargins((int)fArrowWidth, 0, (int)fArrowWidth, 0);
// }
}
CustomView.onLayout:
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// Do nothing. Do not call the superclass method--that would start a layout pass
// on this view's children. PieChart lays out its children in onSizeChanged().
Log.e("DrawView", "DrawView.onLayout: " + l + ", " + t + ", " + r + ", " + b);
if ( mIconContainerView != null && mArrowBitmap != null ) {
// set the icon container margin
float fHeight = this.getHeight();
float fScale = fHeight / mArrowBitmap.getHeight();
float fArrowWidth = mArrowBitmap.getWidth() * fScale;
float fArrowHeight = mArrowBitmap.getHeight() * fScale;
Log.d("DockView", "DockView.init: " + fArrowWidth + ", " + fArrowHeight );
((RelativeLayout.LayoutParams)mIconContainerView.getLayoutParams()).setMargins((int)fArrowWidth, 0, (int)fArrowWidth, 0);
this.requestLayout();
}
int iChildCount = this.getChildCount();
for ( int i = 0; i < iChildCount; i++ ) {
View pChild = this.getChildAt(i);
pChild.layout(0, 0, pChild.getMeasuredWidth(), pChild.getMeasuredHeight());
}
}
CustomView.onDraw
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// mBgColor = Color.CYAN;
// Log.e("DockView", "DockView.onDraw: " + mBgColor);
Log.e("DockView", "DockView.onDraw: width: " + this.getWidth() + " height: " + this.getHeight());
// debugChildren( (RelativeLayout) ((RelativeLayout)this.getChildAt(0)).getChildAt(0) );
debugChildren( ((RelativeLayout)this.getChildAt(0)) );
// draw the background
canvas.drawColor( mBgColor );
float fWidth = this.getWidth(); // View's width
float fHeight = this.getHeight(); // View's height
{
// draw the dock
float fTop = (2 * fHeight) / 3.0f;
Shader shader = new LinearGradient( 0, fTop, 0, fHeight, mDockTopGradientColor, mDockBottomGradientColor, TileMode.CLAMP );
Paint paint = new Paint();
paint.setShader(shader);
canvas.drawRect( new RectF( 0, fTop, fWidth, fHeight ), paint );
}
// moved to onLayout
// if ( mIconContainerView != null && mArrowBitmap != null ) {
// // set the icon container margin
// float fScale = fHeight / mArrowBitmap.getHeight();
// float fArrowWidth = mArrowBitmap.getWidth() * fScale;
// float fArrowHeight = mArrowBitmap.getHeight() * fScale;
// Log.d("DockView", "DockView.init: " + fArrowWidth + ", " + fArrowHeight );
// ((RelativeLayout.LayoutParams)mIconContainerView.getLayoutParams()).setMargins((int)fArrowWidth, 0, (int)fArrowWidth, 0);
// this.requestLayout();
// }
if ( mArrowBitmap != null ) {
// draw the arrow
// canvas.drawBitmap(mArrowBitmap, 0, 0, null);
float fScale = fHeight / mArrowBitmap.getHeight();
float fDrawnWidth = mArrowBitmap.getWidth() * fScale;
float fDrawnHeight = mArrowBitmap.getHeight() * fScale;
// float fLeft = fWidth - fDrawnWidth;
// float fTop = 0.0f;
// float fRight = fWidth;
// float fBottom = fDrawnHeight;
// Log.d("DockView", "DockView.onDraw: (" + fLeft + ", " + fTop + ", " + fRight + ", " + fBottom + ")");
canvas.drawBitmap(mArrowBitmap, null, new RectF(0, 0, fDrawnWidth, fDrawnHeight), null); // Left arrow
Log.d("DockView", "DockView.onDraw: (" + 0 + ", " + 0 + ", " + fDrawnWidth + ", " + fDrawnHeight + ")");
canvas.save();
canvas.scale(-1,1);
canvas.translate(-fWidth, 0);
// canvas.drawBitmap(mArrowBitmap, null, new RectF(fLeft, fTop, fRight, fBottom), null);
canvas.drawBitmap(mArrowBitmap, null, new RectF(0, 0, fDrawnWidth, fDrawnHeight), null); // Right arrow, flipped
canvas.restore();
}
}