我正在尝试以编程方式(不使用 XML 文件)在 Android 中创建自定义子视图(这就是我在 iOS 中所称的),这基本上是将许多基本视图(标签、按钮、文本字段等)组合成一个可重用的子视图类,所以我可以在我的内部UIViewControllers
或Activity
Android 中使用它。
我不知道 Android 中的正确术语是什么。似乎有一百万种不同的术语。
自定义视图、视图组、布局、小部件、组件,无论你想怎么称呼它。
在 iOS 中,这很简单:
自定义视图.h
@interface CustomView : UIView
@property (nonatomic, strong) UILabel *message;
@property (nonatomic, strong) UIButton *button;
@end
自定义视图.m
@implementation CustomView
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
[self initViews];
[self initConstraints];
}
return self;
}
-(void)initViews
{
self.message = [[UILabel alloc] init];
self.button = [[UIButton alloc] init];
[self addSubview:self.message];
[self addSubview:self.button];
}
-(void)initConstraints
{
id views = @{
@"message": self.message,
@"button": self.button
};
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[message]|" options:0 metrics:nil views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[button]|" options:0 metrics:nil views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[message][button]|" options:0 metrics:nil views:views]];
}
@end
Activity
现在我可以在我选择的任何 ViewController (Android) 中重用这个自定义视图。
一个人如何在 Android 中实现这样的目标?
我一直在环顾四周,从我在 Android 中收集的内容中,为了添加子视图,我将它们添加到Layouts
:
RelativeLayout relativeLayout = new RelativeLayout(...);
TextView textView = new TextView(...);
relativeLayout.addSubview(textView);
这是否意味着我需要扩展RelativeLayout
或ViewGroup
?
看这个页面:http: //developer.android.com/reference/android/view/ViewGroup.html
似乎我们需要编写一些非常复杂的逻辑来布局自定义视图,例如:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int count = getChildCount();
// These keep track of the space we are using on the left and right for
// views positioned there; we need member variables so we can also use
// these for layout later.
mLeftWidth = 0;
mRightWidth = 0;
// Measurement will ultimately be computing these values.
int maxHeight = 0;
int maxWidth = 0;
int childState = 0;
// Iterate through all children, measuring them and computing our dimensions
// from their size.
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
// Measure the child.
measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
// Update our size information based on the layout params. Children
// that asked to be positioned on the left or right go in those gutters.
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (lp.position == LayoutParams.POSITION_LEFT) {
mLeftWidth += Math.max(maxWidth,
child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
} else if (lp.position == LayoutParams.POSITION_RIGHT) {
mRightWidth += Math.max(maxWidth,
child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
} else {
maxWidth = Math.max(maxWidth,
child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
}
maxHeight = Math.max(maxHeight,
child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
childState = combineMeasuredStates(childState, child.getMeasuredState());
}
}
// Total width is the maximum width of all inner children plus the gutters.
maxWidth += mLeftWidth + mRightWidth;
// Check against our minimum height and width
maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
// Report our final dimensions.
setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
resolveSizeAndState(maxHeight, heightMeasureSpec,
childState << MEASURED_HEIGHT_STATE_SHIFT));
}
我要做的就是在自定义视图中使用多个基本的 android 标签、视图、按钮,如上面的 iOS 示例,为什么在 Android 中这么难?
我希望有这样简单的东西:
public class CustomView extends View
{
public RelativeLayout mainLayout;
public TextView message;
public Button button;
// default constructor
public CustomView()
{
...
initViews();
initLayouts();
addViews();
}
public initViews()
{
mainLayout = new RelativeLayout(this);
message = new TextView(this);
button = new Button(this);
...
}
public initLayouts()
{
// --------------------------------------------------
// use Android layout params to position subviews
// within this custom view class
// --------------------------------------------------
}
public addViews()
{
mainLayout.addView(message);
mainLayout.addView(button);
setContentView(mainLayout);
}
}
对不起,我真诚地尝试学习和构建一个基本的 Android 应用程序,而不是试图抨击 Android 的做事方式。
我知道如何在 Activity 中添加和布局子视图,并且过去两天一直在这样做,但不是在自定义视图/视图组/布局中。我不想最终为我在 Android 应用程序中的每个 Activity 构建完全相同的子视图,这违反了良好的编码习惯,对吗?:D
在这里只需要一些做过 iOS 和 Android 开发的人的指导。
编辑
似乎我正在寻找的东西被称为复合控件:http: //developer.android.com/guide/topics/ui/custom-components.html
我会继续挖掘,希望能达到我想要的结果:D
只需要解决这个充气机业务。