-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Владимир Каткалов @katkalov #25
base: master
Are you sure you want to change the base?
Changes from all commits
62d5455
3ef74f4
3efbfa9
d666b53
bc0416a
4f1158b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package ru.yandex.yamblz.ui.layouts; | ||
|
||
import android.content.Context; | ||
import android.util.AttributeSet; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
|
||
import java.util.ArrayList; | ||
|
||
public class CustomLayout extends ViewGroup { | ||
private ArrayList<View> mMatchParentChildren = new ArrayList<>(); | ||
|
||
public CustomLayout(Context context) { | ||
this(context, null, 0); | ||
} | ||
|
||
public CustomLayout(Context context, AttributeSet attrs) { | ||
this(context, attrs, 0); | ||
} | ||
|
||
public CustomLayout(Context context, AttributeSet attrs, int defStyleAttr) { | ||
super(context, attrs, defStyleAttr); | ||
} | ||
|
||
@Override | ||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | ||
int horizontalPadding = getPaddingLeft() + getPaddingRight(); | ||
int verticalPadding = getPaddingTop() + getPaddingBottom(); | ||
int totalWidth = 0; | ||
int layoutWidth = MeasureSpec.getSize(widthMeasureSpec) - horizontalPadding; | ||
//Высота лейаута по высоте максимального элемента | ||
int maxHeight = MeasureSpec.getSize(heightMeasureSpec) - verticalPadding; | ||
int changedHeightMeasureSpec = heightMeasureSpec; | ||
|
||
//Родитель может вызвать onMeasure не единожды | ||
mMatchParentChildren.clear(); | ||
|
||
|
||
for (int i = 0; i < getChildCount(); ++i) { | ||
View child = getChildAt(i); | ||
|
||
if (child.getVisibility() == GONE) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. неплохо бы проверять скрыта ли вьюха и в onLayout There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix |
||
continue; | ||
} | ||
|
||
switch (child.getLayoutParams().width) { | ||
case LayoutParams.MATCH_PARENT: | ||
mMatchParentChildren.add(child); | ||
break; | ||
case LayoutParams.WRAP_CONTENT: | ||
default: | ||
measureChild(child, widthMeasureSpec, heightMeasureSpec); | ||
totalWidth += child.getMeasuredWidth(); | ||
int measuredHeight = child.getMeasuredHeight(); | ||
if (maxHeight < measuredHeight) { | ||
maxHeight = measuredHeight; | ||
changedHeightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.UNSPECIFIED); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. UNSPECIFIED по идее не подразумевает никаких ограничений There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ну да, у меня и нет желания его ограничивать по высоте. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Это я к тому, что раз ограничений нет и maxHeight ни на что не влияет, то можно его и не передавать There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. смысл в том, что по maxHeight будет определена высота самого лейаута потом There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. да, верно, значит мой коммент неактуален |
||
} | ||
} | ||
} | ||
//Если осталось место или оно не ограничено, почему бы не показать matchParent | ||
boolean haveSpace = (totalWidth < layoutWidth) | ||
|| widthMeasureSpec == MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); | ||
//И у нас есть, чем его заполнять | ||
if ((mMatchParentChildren.size() > 0) && haveSpace) { | ||
//В случае, если не знаем ширина родителя не остановленна,используем вдвое увеличенную ширину не match_parent элементов | ||
layoutWidth = layoutWidth != 0 ? layoutWidth : totalWidth * 2; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. почему не утроенную ширину? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Можно и утроенную) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Да, три тоже хорошее число) мне кажется, если в сумме все потомки превышают ширину экрана, то ширина match_parent вьюхи, должна быть просто 0, так как места для нее нет. Так получается более предсказуемо, чем умножать на 2, 3 и любое другое число. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. =) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ну да, теперь зачитаться можно) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. сорян) у меня фантазия разыгралась тогда) |
||
//Остаток разделям между оставшимися детьми | ||
int mpChildWidth = (layoutWidth - totalWidth) / mMatchParentChildren.size(); | ||
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(mpChildWidth, MeasureSpec.EXACTLY); | ||
for (int i = 0; i < mMatchParentChildren.size(); i++) { | ||
int childHeightMeasureSpec = getChildMeasureSpec( | ||
heightMeasureSpec, | ||
verticalPadding, | ||
mMatchParentChildren.get(i).getLayoutParams().height | ||
); | ||
mMatchParentChildren.get(i).measure( | ||
childWidthMeasureSpec, | ||
childHeightMeasureSpec | ||
); | ||
totalWidth += mMatchParentChildren.get(i).getMeasuredWidth(); | ||
int measuredHeight = mMatchParentChildren.get(i).getMeasuredHeight(); | ||
if (maxHeight < measuredHeight) { | ||
maxHeight = measuredHeight; | ||
changedHeightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST); | ||
} | ||
} | ||
} | ||
super.onMeasure(MeasureSpec.makeMeasureSpec(layoutWidth + horizontalPadding, MeasureSpec.EXACTLY), changedHeightMeasureSpec); | ||
} | ||
|
||
@Override | ||
protected void onLayout(boolean changed, int l, int t, int r, int b) { | ||
|
||
int horizontalOffset = getPaddingLeft(); | ||
int verticalOffset = getPaddingTop(); | ||
int childCount = getChildCount(); | ||
for (int i = 0; i < childCount; ++i) { | ||
View child = getChildAt(i); | ||
if (child.getVisibility() == GONE) { | ||
continue; | ||
} | ||
int childWidth = child.getMeasuredWidth(); | ||
int childHeight = child.getMeasuredHeight(); | ||
child.layout(horizontalOffset, verticalOffset, horizontalOffset + childWidth, verticalOffset + childHeight); | ||
horizontalOffset += childWidth; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,24 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent"> | ||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" | ||
|
||
<TextView | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent"> | ||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" | ||
android:text="@string/content" | ||
android:textSize="42sp" | ||
android:gravity="center" | ||
/> | ||
android:layout_height="wrap_content" | ||
android:orientation="vertical"> | ||
|
||
</FrameLayout> | ||
|
||
<include layout="@layout/inner_test_1"/> | ||
<include layout="@layout/inner_test_2"/> | ||
<include layout="@layout/inner_test_3"/> | ||
<include layout="@layout/inner_test_33"/> | ||
<include layout="@layout/inner_test_5"/> | ||
<include layout="@layout/inner_test_6"/> | ||
<include layout="@layout/inner_test_7"/> | ||
<include layout="@layout/inner_test_8"/> | ||
<include layout="@layout/inner_test_9"/> | ||
<include layout="@layout/inner_test_10"/> | ||
|
||
</LinearLayout> | ||
</ScrollView> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" | ||
android:orientation="vertical"> | ||
|
||
<TextView | ||
android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | ||
android:text="wrap_content LL and CL with expecly width for all" /> | ||
|
||
<LinearLayout | ||
android:layout_width="wrap_content" | ||
android:layout_height="100dp"> | ||
|
||
<TextView | ||
android:layout_width="10dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/gray" /> | ||
|
||
<TextView | ||
android:layout_width="100dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/colorAccent" /> | ||
|
||
<TextView | ||
android:layout_width="50dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/colorPrimary" /> | ||
|
||
<TextView | ||
android:layout_width="70dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/colorPrimaryDark" /> | ||
|
||
<TextView | ||
android:layout_width="1000dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/d2m_font_default_description" /> | ||
|
||
</LinearLayout> | ||
|
||
|
||
<TextView | ||
android:layout_width="match_parent" | ||
android:layout_height="1dp" | ||
android:background="@color/black" /> | ||
|
||
<ru.yandex.yamblz.ui.layouts.CustomLayout | ||
android:layout_width="wrap_content" | ||
android:layout_height="100dp"> | ||
|
||
<TextView | ||
android:layout_width="10dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/gray" /> | ||
|
||
<TextView | ||
android:layout_width="100dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/colorAccent" /> | ||
|
||
<TextView | ||
android:layout_width="50dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/colorPrimary" /> | ||
|
||
<TextView | ||
android:layout_width="70dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/colorPrimaryDark" /> | ||
|
||
|
||
<TextView | ||
android:layout_width="1000dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/d2m_font_default_description" /> | ||
|
||
</ru.yandex.yamblz.ui.layouts.CustomLayout> | ||
|
||
<TextView | ||
android:layout_width="match_parent" | ||
android:layout_height="3dp" | ||
android:background="@color/black" /> | ||
</LinearLayout> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" | ||
android:orientation="vertical"> | ||
|
||
<TextView | ||
android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | ||
android:text="LL and CL with child margin" | ||
/> | ||
|
||
<LinearLayout | ||
android:layout_width="match_parent" | ||
android:layout_height="100dp" | ||
> | ||
|
||
<TextView | ||
android:layout_width="10dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/gray" /> | ||
|
||
<TextView | ||
android:layout_width="100dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/colorAccent" /> | ||
|
||
<TextView | ||
android:layout_width="0dp" | ||
android:layout_weight="1" | ||
android:layout_margin="8dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/colorPrimary" /> | ||
|
||
<TextView | ||
android:layout_width="70dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/colorPrimaryDark" /> | ||
|
||
<TextView | ||
android:layout_width="50dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/d2m_font_default_description" /> | ||
|
||
</LinearLayout> | ||
|
||
|
||
<TextView | ||
android:layout_width="match_parent" | ||
android:layout_height="1dp" | ||
android:background="@color/black" /> | ||
|
||
<ru.yandex.yamblz.ui.layouts.CustomLayout | ||
android:layout_width="wrap_content" | ||
android:layout_height="100dp"> | ||
|
||
<TextView | ||
android:layout_width="10dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/gray" /> | ||
|
||
<TextView | ||
android:layout_width="100dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/colorAccent" /> | ||
|
||
<TextView | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" | ||
android:layout_margin="8dp" | ||
android:background="@color/colorPrimary" /> | ||
|
||
<TextView | ||
android:layout_width="70dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/colorPrimaryDark" /> | ||
|
||
|
||
<TextView | ||
android:layout_width="50dp" | ||
android:layout_height="match_parent" | ||
android:background="@color/d2m_font_default_description" /> | ||
|
||
</ru.yandex.yamblz.ui.layouts.CustomLayout> | ||
|
||
<TextView | ||
android:layout_width="match_parent" | ||
android:layout_height="3dp" | ||
android:background="@color/black" /> | ||
</LinearLayout> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Нужно учитывать паддинги и при измерении
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
согласен, мой косяк
просто сравнив с linear'ом получил одинаковый результат(на скриншоте первом видно), и не стал задумываться
видимо тест не очень удачный
при первой возможности пофикшу
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
потыкал паддинги в методе измерения
ни к чему хорошему это не приводит)
наверно потому, что за меня это решает метод измерения суперкласса
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А можешь показать, где это супер класс делает?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Отказать, первое предположение было неверно
Осознал
Я вызываю для детей measureChild и он там вызывает getChildMeasureSpec и он думает, что я передаю родительские MeasureSpec поэтому хватает падинги родителя и смело из с их учетом расчитывает чилда.
И если это так и происходит для первых детей, то для детей которые match_parent это не так.
Это все будет работать до тех пор, пока match_parent в лейауте один. :)
то есть по сути задание выполнено)))
но надо бы исправить, чтобы для двух
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Так view.measure не учитывает паддинги, паддинги учитывает measureChild, поэтому просто измерится по ширине и высоте родительской вьюхи без каких либо ограничений, а при отрисовке паддинг учитывается.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
да я про прошлый случай и рассказывал, про measureChild. Типа почему это все работало раньше :)
Пока тыкался сейчас, понял, что забыл проверять отсутствие match_parent элементов и делил на 0. Видимо, забыл добавить проверку, когда решил, что у меня может быть их больше одного. so sad
пофиксил
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
разобрались) в общем, это просто тонкий момент, который нужно в голове держать
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
понял. спасибо, было познавательно)
как-нибудь на досуге буду разбираться еще с мерджинами потомков, чтобы совсем проникнуться)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
без проблем