Intereting Posts
Определение активности Android в диалоге с легкой темой Не удается установить пример проекта ApiDemos на Android-эмуляторе Android – почему существует различное значение Action_mask для разных устройств Вкладки отображаются по-разному в зависимости от того, установлен ли Theme.NoTitleBar или нет в манифесте Рабочий многоточечный запрос POST с волейболом и без HttpEntity Изменение имени приложения в Eclipse Is onLoadFinished () асинхронный (фоновый поток)? Как обнаружить IBeacon в андроиде без использования какой-либо библиотеки Android: Вертикальный ListView с перекрывающимися рядами Android не может получить объект сообщения в AlertDialog Как вызвать скрипт Python с Android Как я могу получить родительский вид с помощью uiautomator? Почему мой ProgressDialog выходит, когда я нажимаю «Активность»? Показать значок загрузки в строке заголовка активности Okhttp игнорирует настройку Диспетчера при использовании с Retrofit RxJavaCallAdapterFactory

Создавайте подзаголовки Android, такие как iOS subviews

Я пытаюсь программно (не используя файлы XML) создавать пользовательские подзаголовки в Android (это то, что я называю это в iOS), который представляет собой в основном несколько основных представлений (ярлыки, кнопки, текстовые поля и т. Д.), Которые объединены в многоразовое подвью Класс, поэтому я могу использовать его внутри своих UIViewControllers или Activity в Android.

Я не знаю, какая правильная терминология в Android. Кажется, существует миллион различных терминов.

Custom View, ViewGroups, макеты, виджеты, компоненты, все, что вы хотите назвать.

В 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, чтобы добавить subviews, я добавляю их в 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?

Я надеялся на что-то простое:

 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 для Android.

Я знаю, как добавлять и компоновать подпрограммы внутри Activity и делал это в течение последних двух дней, но не внутри настраиваемой группы View / View Group / Layout. Я не хочу конструировать то же самое подобие для каждого из моих действий в приложении для Android, которое просто противоречит правильной практике кодирования? : D

Просто нужно немного руководство от других, которые сделали как iOS, так и разработку Android.

редактировать

Кажется, что то, что я ищу, называется Compound Control: http://developer.android.com/guide/topics/ui/custom-components.html

Я буду продолжать рыть и, надеюсь, достичь результата, который я буду: D

Просто нужно разработать этот бизнес Inflater.

Разработка приложений Android и ios – это две разные концепции, каждая из которых имеет свой собственный способ выполнения вашей задачи. Иногда его сложно разработать кусок кода в android, а иногда и в ios. Чтобы создать экран просмотра / дизайн / графический интерфейс в android, вы можете создать XML-файл (рекомендуется) или по коду (который так или иначе трудно поддерживать по XML).

Для вашего вопроса вам не нужно создавать собственные ViewGroup или RelativeLayout или LinearLayout например, если вы хотите использовать RelativeLayout в качестве родителя для своего представления, чем используя XML, который вы можете использовать.

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Some Text"/> </RelativeLayout> 

Если вы хотите создать свое представление прагматично, чем использовать

  RelativeLayout parentRelativeLayout = new RelativeLayout(context); RelativeLayout.LayoutParams parentParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); parentRelativeLayout.setLayoutParams(parentParams); TextView childTextView = new TextView(context); childTextView.setText("Some Text"); mRelativeLayout.addView(childTextView); 

Его просто пример кода имеет идентичный результат, но с программным подходом это будет сложно, так как ваш взгляд растет.

Если вы ищете свой код для создания пользовательского представления (почему?) В android, нам нужны только пользовательские представления, если представления по умолчанию не предоставляют некоторые функциональные возможности, которые нам нужно использовать / реализовать в нашем коде. Насколько я понимаю, вы хотите использовать пользовательские представления для повторного использования. Его хороший подход, но если андроид предоставляет некоторые функциональные возможности, чем то, почему вы пытаетесь изобрести колесо, просто используйте разные макеты, используйте только пользовательские представления, если вы хотите что-то дополнительное.

Хорошо, я думаю, что понял, не уверен, что это лучшее решение, но оно делает то, что я хочу.

Итак, это выглядит примерно так:

 public class CustomView extends RelativeLayout { private Context context; public TextView message; public Button button; public CustomView(Context context) { super(context); // --------------------------------------------------------- // store context as I like to create the views inside // initViews() method rather than in the constructor // --------------------------------------------------------- this.context = context; initViews(); initLayouts(); addViews(); } public CustomView(Context context, AttributeSet attrs) { super(context, attrs); // --------------------------------------------------------- // store context as I like to create the views inside // initViews() method rather than in the constructor // --------------------------------------------------------- this.context = context; initViews(); initLayouts(); addViews(); } public initViews() { // ---------------------------------------- // note "context" refers to this.context // that we stored above. // ---------------------------------------- message = new TextView(context); ... button = new Button(context); ... } public initLayouts() { // -------------------------------------------------- // use Android layout params to position subviews // within this custom view class // -------------------------------------------------- message.setId(View.generateViewId()); button.setId(View.generateViewId()); RelativeLayout.LayoutParams messageLayoutParams = new RelativeLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT ); message.setLayoutParams(messageLayoutParams); RelativeLayout.LayoutParams buttonLayoutParams = new RelativeLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT ); button.setLayoutParams(buttonLayoutParams); } public addViews() { // adding subviews to layout addView(message); addView(button); } } 

Теперь я могу использовать этот пользовательский вид в любой из моих задач:

 public class MainActivity extends ActionBarActivity { // custom view instance protected CustomView approvalView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... initViews(); } public initViews() { ... approvalView = new CustomView(this); approvalView.message.setText("1 + 1 = 2"); approvalView.button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Log.d("Logger", "Math formula approved! :D"); } }); } } 

Inflater используется, если мы создаем наш макет с использованием XML, который не является чем-то, что мне нравится делать, поэтому я сгенерировал макет моего представления программно: D

Вышеупомянутый «RelativeLayout» в «extends RelativeLayout» может быть заменен на «LinearLayout» или другие макеты, конечно.

Чтобы добавить простой ответ для общего посетителя на этот вопрос …

Вы не можете добавлять subviews в Android View как вы можете, с iOS UIView .

Если вам нужно добавить subviews в Android, используйте один из подклассов ViewGroup (например, LinearLayout , RelativeLayout или даже собственный собственный подкласс).

 myViewGroup.addView(myView);