-
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
@aleien, Манюхина #21
base: master
Are you sure you want to change the base?
Changes from all commits
9566607
3860bfd
c6d255d
7e06a6e
f7cb639
65ceff8
c03b520
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,137 @@ | ||
package ru.yandex.yamblz.ui.views; | ||
|
||
import android.content.Context; | ||
import android.graphics.Point; | ||
import android.graphics.Rect; | ||
import android.util.AttributeSet; | ||
import android.view.Display; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
import android.view.WindowManager; | ||
import android.widget.FrameLayout; | ||
|
||
import timber.log.Timber; | ||
|
||
/** | ||
* Created by user on 17.07.16. | ||
*/ | ||
|
||
public class OnePassHorizontalLayout extends ViewGroup { | ||
|
||
private int mLeftWidth; | ||
private int mRightWidth; | ||
private final Rect mTmpContainerRect = new Rect(); | ||
private final Rect mTmpChildRect = new Rect(); | ||
private int matchParentPosition = -1; | ||
private int remainingSpace; | ||
|
||
private LayoutParams mLayoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); | ||
private int deviceWidth; | ||
|
||
public OnePassHorizontalLayout(Context context) { | ||
super(context); | ||
init(); | ||
} | ||
|
||
public OnePassHorizontalLayout(Context context, AttributeSet attrs) { | ||
super(context, attrs); | ||
init(); | ||
} | ||
|
||
|
||
@Override | ||
protected MarginLayoutParams generateLayoutParams(LayoutParams p) { | ||
return new MarginLayoutParams(super.generateLayoutParams(p)); | ||
} | ||
|
||
@Override | ||
protected MarginLayoutParams generateDefaultLayoutParams() { | ||
return new MarginLayoutParams(super.generateDefaultLayoutParams()); | ||
} | ||
|
||
private void init() { | ||
final Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); | ||
Point deviceDisplay = new Point(); | ||
display.getSize(deviceDisplay); | ||
deviceWidth = deviceDisplay.x; | ||
|
||
} | ||
|
||
@Override | ||
public void addView(View child, LayoutParams params) { | ||
Timber.d("Add view in: child params"); | ||
super.addView(child, new MarginLayoutParams(params)); | ||
} | ||
|
||
@Override | ||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | ||
super.onMeasure(widthMeasureSpec, heightMeasureSpec); | ||
int count = getChildCount(); | ||
|
||
int maxHeight = 0; | ||
int maxWidth = 0; | ||
int childState = 0; | ||
|
||
for (int i = 0; i < count; i++) { | ||
final View child = getChildAt(i); | ||
|
||
if (child.getVisibility() == GONE) | ||
continue; | ||
|
||
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); | ||
if (lp.width == LayoutParams.MATCH_PARENT) { | ||
matchParentPosition = i; | ||
} else { | ||
measureChildWithMargins(child, widthMeasureSpec, maxWidth, heightMeasureSpec, maxHeight); | ||
maxWidth += child.getMeasuredWidth(); | ||
} | ||
|
||
maxHeight = Math.max(maxHeight, child.getMeasuredHeight()); | ||
childState = combineMeasuredStates(childState, child.getMeasuredState()); | ||
|
||
} | ||
|
||
remainingSpace = deviceWidth - maxWidth; | ||
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 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 = Math.max(maxHeight, getSuggestedMinimumHeight()); | ||
maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth()); | ||
|
||
getChildAt(matchParentPosition).measure(MeasureSpec.makeMeasureSpec(remainingSpace, MeasureSpec.UNSPECIFIED), 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. При вызове View.measure не учитываются отступы у родителя, это может вести к тому, что вьюха будет обрезаться. Вообще, мне кажется тут больше подходит MeasureSpec.EXACTLY, так как нам нужно заполнить определенную отступ, MeasureSpec.UNSPECIFIED используется, например, тогда, когда родитель это ScrollView и нужно просто измерить весь контент. 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. можно ручками, можно использовать measureChild или, раз ты захотела поддержать марджины measureChildWithMargins |
||
|
||
setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState), | ||
resolveSizeAndState(maxHeight, heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT)); | ||
} | ||
|
||
@Override | ||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { | ||
final int count = getChildCount(); | ||
int curWidth, curHeight, curLeft, maxHeight; | ||
|
||
maxHeight = 0; | ||
curLeft = this.getPaddingLeft(); | ||
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. :D |
||
|
||
for (int i = 0; i < count; i++) { | ||
View child = getChildAt(i); | ||
|
||
if (child.getVisibility() == GONE) | ||
return; | ||
|
||
LayoutParams layoutParams = child.getLayoutParams(); | ||
|
||
if (layoutParams.width == LayoutParams.MATCH_PARENT) { | ||
curWidth = remainingSpace; | ||
curHeight = child.getMeasuredHeight(); | ||
} else { | ||
curWidth = child.getMeasuredWidth(); | ||
curHeight = child.getMeasuredHeight(); | ||
} | ||
|
||
child.layout(curLeft, 0, curLeft + curWidth, curHeight); | ||
|
||
if (maxHeight < curHeight) | ||
maxHeight = curHeight; | ||
curLeft += curWidth; | ||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,124 @@ | ||
<?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"> | ||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
android:orientation="vertical" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent"> | ||
|
||
<TextView | ||
<ru.yandex.yamblz.ui.views.OnePassHorizontalLayout | ||
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"> | ||
|
||
</FrameLayout> | ||
<TextView | ||
android:layout_width="match_parent" | ||
android:layout_height="wrap_content" | ||
android:background="#404040" | ||
android:ellipsize="end" | ||
android:text="MATCH" | ||
android:textSize="@dimen/text_size" /> | ||
|
||
<TextView | ||
android:layout_width="100dp" | ||
android:layout_height="wrap_content" | ||
android:background="#ffffff" | ||
android:ellipsize="end" | ||
android:text="100dp" | ||
android:textSize="@dimen/text_size" /> | ||
|
||
<TextView | ||
android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | ||
android:background="#a7a39d" | ||
android:ellipsize="end" | ||
android:text="WRAP" | ||
android:textSize="@dimen/text_size" /> | ||
|
||
<TextView | ||
android:layout_width="50dp" | ||
android:layout_height="wrap_content" | ||
android:background="#ffffff" | ||
android:ellipsize="end" | ||
android:text="50dp" | ||
android:textSize="@dimen/text_size" /> | ||
|
||
|
||
</ru.yandex.yamblz.ui.views.OnePassHorizontalLayout> | ||
|
||
<ru.yandex.yamblz.ui.views.OnePassHorizontalLayout | ||
android:layout_width="match_parent" | ||
android:layout_height="wrap_content"> | ||
|
||
<TextView | ||
android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | ||
android:background="#a7a39d" | ||
android:ellipsize="end" | ||
android:text="WRAP" | ||
android:textSize="@dimen/text_size" /> | ||
|
||
<TextView | ||
android:layout_width="match_parent" | ||
android:layout_height="wrap_content" | ||
android:background="#404040" | ||
android:ellipsize="end" | ||
android:text="MATCH" | ||
android:textSize="@dimen/text_size" /> | ||
|
||
|
||
<TextView | ||
android:layout_width="50dp" | ||
android:layout_height="wrap_content" | ||
android:background="#ffffff" | ||
android:ellipsize="end" | ||
android:text="50dp" | ||
android:textSize="@dimen/text_size" /> | ||
|
||
<TextView | ||
android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | ||
android:background="#a7a39d" | ||
android:ellipsize="end" | ||
android:text="WRAP" | ||
android:textSize="@dimen/text_size" /> | ||
|
||
</ru.yandex.yamblz.ui.views.OnePassHorizontalLayout> | ||
|
||
<ru.yandex.yamblz.ui.views.OnePassHorizontalLayout | ||
android:layout_width="match_parent" | ||
android:layout_height="wrap_content"> | ||
|
||
<TextView | ||
android:layout_width="150dp" | ||
android:layout_height="wrap_content" | ||
android:background="#ffffff" | ||
android:ellipsize="end" | ||
android:text="150dp" | ||
android:textSize="@dimen/text_size" /> | ||
|
||
<TextView | ||
android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | ||
android:background="#a7a39d" | ||
android:ellipsize="end" | ||
android:text="WRAP" | ||
android:textSize="@dimen/text_size" /> | ||
|
||
<TextView | ||
android:layout_width="50dp" | ||
android:layout_height="wrap_content" | ||
android:background="#ffffff" | ||
android:ellipsize="end" | ||
android:text="50dp" | ||
android:textSize="@dimen/text_size" /> | ||
|
||
<TextView | ||
android:layout_width="match_parent" | ||
android:layout_height="wrap_content" | ||
android:background="#404040" | ||
android:ellipsize="end" | ||
android:text="MATCH" | ||
android:textSize="@dimen/text_size" /> | ||
|
||
</ru.yandex.yamblz.ui.views.OnePassHorizontalLayout> | ||
|
||
|
||
</LinearLayout> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
#Mon May 30 20:17:48 ICT 2016 | ||
#Sun Jul 17 17:44:01 MSK 2016 | ||
distributionBase=GRADLE_USER_HOME | ||
distributionPath=wrapper/dists | ||
zipStoreBase=GRADLE_USER_HOME | ||
zipStorePath=wrapper/dists | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-all.zip |
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.
Если захотела поддерживать марджины, тогда уж и checkLayoutParams нужно вызывать, тогда у тебя вызывался бы generateLayoutParams и не нужно было бы переопределять addView
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.
У кода пола нет :D
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.
Все-таки не поняла, как через checkLayoutParams делать. Он же вроде просто проверку делает, и не дергает ничего?
Я вначале хотела переопределить generateLayoutParams, но не знаю, что именно нужно вызывать, чтобы он дергался при создании детей.
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.
по исходникам при инфлейте проверяется соотвествуют ли параметры по умолчанию тем, которые ты выбираешь и если нет, то вызывается generateLayoutParams(LayoutParams p).
ЗЫ в addViewInternal, если не ошибаюсь
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.
Ага. Т.е. generatelayoutparams вызовется, если мы в xml установим марджины?
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.
да, другой правда generateLayoutParams(AttributeSet attrs), generateLayoutParams(LayoutParams p) будет вызываться, если мы программно вьюху добавляем