Android-написание пользовательского (составного) компонента
Android-приложение, которое я в настоящее время разрабатываю, имеет основную деятельность, которая выросла довольно большой. Это в основном потому, что он содержит TabWidget
С 3 вкладками. Каждая вкладка имеет довольно много компонентов. Деятельность должна контролировать все эти компоненты одновременно. Так что я думаю вы можете себе представить, что эта деятельность, как 20 полей (поле почти для каждого компонента). Также он содержит много логики (нажмите прослушиватели, логику для заполнения списков и т. д.).
что я обычно делаю в компоненте фреймворки должны разделить все на пользовательские компоненты. Тогда каждый пользовательский компонент будет нести четкую ответственность. Он будет содержать собственный набор компонентов и всю другую логику, связанную с этим компонентом.
я попытался выяснить, как это можно сделать, и я нашел что-то в документации Android, что они любят называть "составной контроль". (См.http://developer.android.com/guide/topics/ui/custom-components.html#compound и прокрутите до Раздел "составные элементы управления") я хотел бы создать такой компонент на основе XML-файла, определяющего структуру представления.
в документации написано:
обратите внимание, что так же, как с деятельностью, можно использовать либо декларативный (На основе XML) подход к созданию содержащиеся компоненты, или вы можете вложить их программно из кода.
Ну, это хорошие новости! Подход на основе XML-это именно то, что я хочу! Но он не говорит, как это сделать, за исключением того, что это"как с деятельностью"... Но то, что я делаю в деятельности, - это call setContentView(...)
для раздувания представлений из XML. Этот метод недоступен, если вы, например, подкласс LinearLayout
.
поэтому я попытался раздуть XML вручную следующим образом:
public class MyCompoundComponent extends LinearLayout {
public MyCompoundComponent(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.my_layout, this);
}
}
это работает, за исключением того, что XML, который я загружаю, имеет LinearLayout
объявляется корневой элемент. Это приводит к завышенным LinearLayout
детство MyCompoundComponent
которая сама уже есть LinearLayout
!! Итак, теперь у нас есть избыточный LinearLayout между MyCompoundComponent
и представления, которые ему действительно нужны.
может кто-нибудь, пожалуйста, предоставить мне лучший способ подойти к этому, избегая избыточного LinearLayout
инстанцируется?
2 ответов
использовать слияние тег как ваш XML root
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Your Layout -->
</merge>
Я думаю, как вы должны это сделать, это использовать имя класса в качестве корневого элемента XML:
<com.example.views.MyView xmlns:....
android:orientation="vertical" etc.>
<TextView android:id="@+id/text" ... />
</com.example.views.MyView>
а затем ваш класс, производный от любого макета, который вы хотите использовать. Обратите внимание, что если вы используете этот метод, вы не используйте надувной макет здесь.
public class MyView extends LinearLayout
{
public ConversationListItem(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ConversationListItem(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
public void setData(String text)
{
mTextView.setText(text);
}
private TextView mTextView;
@Override
protected void onFinishInflate()
{
super.onFinishInflate();
mTextView = (TextView)findViewById(R.id.text);
}
}
и затем вы можете использовать свое представление в XML-макетах как обычно. Если вы хотите сделать представление программно, вам нужно раздуть его самостоятельно:
MyView v = (MyView)inflater.inflate(R.layout.my_view, parent, false);
к сожалению это не позволяет вам сделать v = new MyView(context)
потому что, похоже, нет способа обойти проблему вложенных макетов, поэтому это не полное решение. Вы можете добавить такой метод в MyView
чтобы сделать его немного приятнее:
public static MyView create(Context context)
{
return (MyView)LayoutInflater.fromContext(context).inflate(R.layout.my_view, null, false);
}
отказ от ответственности: я могу говорить полную чушь.