我有这个自定义视图:
public class TopBarHandler extends FrameLayout {
private Drawable mRightButtonSrc;
private boolean mShowRightButton;
private String mTitle;
private ImageButton mHamburgerButton;
private EllipsizingTextView mTitleTextView;
private ImageButton mRightButton;
private ProgressBar mProgressBar;
public TopBarHandler(final Context context, final AttributeSet attrs) {
super(context, attrs);
initView();
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.topbarMenu);
mShowRightButton = a.getBoolean(R.styleable.topbarMenu_showRightButton, false);
mRightButtonSrc = a.getDrawable(R.styleable.topbarMenu_rightButtonSrc);
mTitle = a.getString(R.styleable.topbarMenu_titleText);
}
public TopBarHandler(final Context context) {
super(context);
initView();
}
private void initView() {
View view = inflate(getContext(), R.layout.top_bar_layout, null);
mHamburgerButton = (ImageButton) findViewById(R.id.top_bar_hamburger_button);
mTitleTextView = (EllipsizingTextView) findViewById(R.id.top_bar_title);
mRightButton = (ImageButton) findViewById(R.id.top_bar_right_button);
mProgressBar = (ProgressBar) findViewById(R.id.top_bar_progress_bar);
addView(view);
}
public interface TopBarListener {
void onHamburgerButtonPressed();
void onRightButtonPressed();
}
}
使用此布局定义:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/top_bar_layout"
android:layout_width="match_parent"
android:layout_height="@dimen/height_top_bar"
android:background="@drawable/gradient_top_bar"
android:gravity="center_vertical">
<ImageButton
android:id="@+id/top_bar_hamburger_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/margin_objects_top_bar"
android:src="@drawable/selector_menu_topbar"
android:background="@null"/>
<com.myproject.android.utilities.fonts.EllipsizingTextView
android:id="@+id/top_bar_title"
style="@style/bar_title_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="@string/CameraWizard_CameraWizard"
android:textSize="@dimen/menu_top_bar_title_size"
android:layout_marginLeft="@dimen/margin_top_bar_title"
android:layout_toLeftOf="@+id/top_bar_right_button"
android:layout_alignParentLeft="true"/>
<ImageButton
android:id="@+id/top_bar_right_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="@dimen/margin_objects_top_bar"
android:background="@drawable/top_bar_search"
android:visibility="invisible" />
<ProgressBar
android:id="@+id/top_bar_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="@dimen/margin_objects_top_bar"
android:indeterminate="false"
android:minHeight="50dp"
android:minWidth="50dp"
android:progress="1"
android:visibility="gone" />
</RelativeLayout>
我想把它放在多个布局中,所以我这样做:
<com.myproject.android.menu.TopBarHandler
android:layout_height="@dimen/height_top_bar"
android:layout_width="fill_parent"
/>
但问题是,如果我想将它放在多个布局(70+)中,那么我必须在每个布局中指定高度和宽度。有没有办法在自定义视图中强制执行高度?
如果我没有在目标布局上指定高度和宽度,那么我会收到错误。如果我放入wrap_content,则忽略topbar_layout中指定的高度。
答案 0 :(得分:0)
您需要在自定义视图中实现onMeasure():
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// What is the desired size of the view?
int desiredWidth = 250;
int desiredHeight = 250;
// The MeasureSpecs passed in will depend on the LayoutParams
// applied to the view in xml or programmatically
// Analyse the MeasureSpec for width and height separately like this:
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
switch (widthMode) {
case MeasureSpec.UNSPECIFIED:
widthSize = desiredWidth;
break;
case MeasureSpec.AT_MOST:
widthSize = Math.min(widthSize, desiredWidth);
break;
case MeasureSpec.EXACTLY:
break;
default:
}
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
switch (heightMode) {
case MeasureSpec.UNSPECIFIED:
heightSize = desiredHeight;
break;
case MeasureSpec.AT_MOST:
heightSize = Math.min(heightSize, desiredHeight);
break;
case MeasureSpec.EXACTLY:
break;
default:
}
// You must call setMeasuredDimension()
setMeasuredDimension(widthSize, heightSize);
}