Я создаю пользовательскую группу ViewGroup. Если добавить свой собственный ViewGroup в макет без указания LayoutParams (как показано ниже), он отображает правильно:Высота дочерних высот ViewGroup равна 0, когда родительский параметр установлен на WRAP_CONTENT
...
MyCustomViewGroup myViewGroup = new MyCustomViewGroup(this);
myRelativeLayout.addView(myViewGroup);
...
Если я указываю LayoutParams и установить ширину MATCH_PARENT и высоту до WRAP_CONTENT (как показано ниже) , оно не отображается:
...
MyCustomViewGroup myViewGroup = new MyCustomViewGroup(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
myRelativeLayout.addView(myViewGroup, params);
...
Я запустил Debug для обоих сценариев.
Сценарий 1
Если я не указать LayoutParams, мнения ребенка измерения правильно, и когда метод перебирает все мнения ребенка, чтобы определить максимальную высоту, child.getMeasuredHeight()
возвращает правильные значения каждый раз.
Сценарий 2
Если я указать LayoutParams с шириной, как MATCH_PARENT, и высоты, как WRAP_CONTENT, система делает два прохода через onMeasure, как описано ниже.
Pass 1
widthSpecMode = ТОЧНО
ширина = widthSpecSize = 758, которая является ширина родительского RelativeLayout
heightSpecMode = ТОЧНО
высота = heightSpecSize = 1055, которая равна высоте родителя RelativeLayout
Pass 2
widthSpecMode = ТОЧНО
ширина = widthSpecSize = 758 Вт hich - ширина родительского RelativeLayout
heightSpecMode = AT_MOST
Затем метод выполняет итерацию по всем дочерним представлениям для определения максимальной высоты, но child.getMeasuredHeight()
возвращает 0 каждый раз.
Представления для детей представляют собой несколько ImageButtons и TextView. Все они имеют контент, и этот контент отображается правильно в первом сценарии. Почему во втором сценарии это получается как высота 0, и как я могу его исправить?
`' Я написал упрощенное тестовое приложение для воссоздания проблемы. Все необходимые коды показаны ниже. Если кто-то захочет попробовать, вы можете просто вырезать и вставить.
MainActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout rootLayout = (RelativeLayout)findViewById(R.id.LayoutRoot);
// Create an instance of MyViewGroup
MyViewGroup viewGroupOne = new MyViewGroup(this);
viewGroupOne.setId(1);
rootLayout.addView(viewGroupOne);
// Create a second instance and set layout width and height both to WRAP_CONTENT
MyViewGroup viewGroupTwo = new MyViewGroup(this);
viewGroupTwo.setId(2);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.BELOW, 1);
rootLayout.addView(viewGroupTwo, params);
// Create a third Instance. Set layout width to MATCH_PARENT and height to WRAP_CONTENT
MyViewGroup viewGroupThree = new MyViewGroup(this);
params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.BELOW, 2);
rootLayout.addView(viewGroupThree, params);
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LayoutRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
</RelativeLayout>
MyViewGroup.Java
public class MyViewGroup extends ViewGroup {
private static int instanceCounter;
public MyViewGroup(Context context) {
super(context);
instanceCounter++;
// Add a TextView
TextView textView = new TextView(context);
String text = "Instance " + instanceCounter;
textView.setText(text);
addView(textView);
// Add an ImageView
ImageView imageView = new ImageView(context);
imageView.setImageResource(android.R.drawable.ic_menu_add);
addView(imageView);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int childCount = getChildCount();
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
int width = 0;
int height = 0;
int childState = 0;
// Measure Width
if (widthSpecMode == MeasureSpec.EXACTLY) {
width = widthSpecSize;
} else {
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
measureChild(child, widthMeasureSpec, heightMeasureSpec);
width += child.getMeasuredWidth();
}
}
}
if (widthSpecMode == MeasureSpec.AT_MOST) {
width = Math.min(width, widthSpecSize);
}
// Measure Height
if (heightSpecMode == MeasureSpec.EXACTLY) {
height = heightSpecSize;
} else {
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
height = Math.max(height, child.getMeasuredHeight());
}
}
}
if (heightSpecMode == MeasureSpec.AT_MOST) {
height = Math.min(height, heightSpecSize);
}
// Combine child states
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
childState = combineMeasuredStates(childState, child.getMeasuredState());
}
}
// Check against minimum width and height
width = Math.max(width, getSuggestedMinimumWidth());
height = Math.max(height, getSuggestedMinimumHeight());
// Report final dimensions
setMeasuredDimension(resolveSizeAndState(width, widthMeasureSpec, childState),
resolveSizeAndState(height, heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT));
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount();
int leftPos = 0;
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
final int childWidth = child.getMeasuredWidth();
if (child.getVisibility() != GONE) {
child.layout(leftPos, 0, leftPos + childWidth, getMeasuredHeight());
leftPos += childWidth;
}
}
}
}
сообщение MyCustomViewGroup.onLayout – pskink
@pskink Привет. Спасибо, что посмотрели. Я обновил свой пост по запросу. –
извините, но ничего не могу поделать, так как я вижу обратное: wirhout params я ничего не вижу, с параметрами wrap_content, weapon_content я вижу что-то – pskink