私はプログラムで(XMLファイルを使用せずに)Androidでカスタムサブビューを作成しようとしています(これは私がiOSで呼んでいるものです)。これは基本的にいくつかの基本的なビュー(ラベル、ボタン、テキストフィールドなど)を再利用可能なサブビューにまとめたものですクラスを作成して、自分の内部UIViewControllers
またはActivity
Android で使用できるようにしました。
Android の正しい用語がわかりません。何百万もの異なる用語があるようです。
Custom View、ViewGroups、Layouts、Widgets、Components など、お好きな名前を付けてください。
iOS では、これは次のように単純に行われます。
CustomView.h
@interface CustomView : UIView
@property (nonatomic, strong) UILabel *message;
@property (nonatomic, strong) UIButton *button;
@end
CustomView.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
これで、選択した任意の ViewController (Android Activity
) でこのカスタム ビューを再利用できます。
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));
}
私がやろうとしているのは、上記の iOS の例のようなカスタム ビューで複数の基本的な Android ラベル、ビュー、ボタンを使用することだけですが、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 のやり方を否定するつもりはありません。
アクティビティ内にサブビューを追加してレイアウトする方法を知っており、過去 2 日間そうしていますが、カスタム ビュー/ビュー グループ/レイアウト内ではそうしていません。Android アプリのアクティビティごとにまったく同じサブビューを作成することはしたくありません。これは、適切なコーディング プラクティスに反するだけです。:D
ここでは、iOS と Android の両方の開発を行った他の人からのちょっとしたガイダンスが必要です。
編集
私が探しているのは複合コントロールと呼ばれているようです: http://developer.android.com/guide/topics/ui/custom-components.html
私は掘り続けて、うまくいけば私が求めている結果を達成します:D
このインフレータ事業を解決する必要があります。