Skip to content
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

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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));
Copy link
Collaborator

@bracadabra bracadabra Aug 10, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если захотела поддерживать марджины, тогда уж и checkLayoutParams нужно вызывать, тогда у тебя вызывался бы generateLayoutParams и не нужно было бы переопределять addView

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Во, спасибо! Я это как раз искала, как сделать, и не нашла.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ой, не понял, что ты девочка сначала, извини

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

У кода пола нет :D

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

да, но есть же какие-то правила обращения)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Все-таки не поняла, как через checkLayoutParams делать. Он же вроде просто проверку делает, и не дергает ничего?
Я вначале хотела переопределить generateLayoutParams, но не знаю, что именно нужно вызывать, чтобы он дергался при создании детей.

Copy link
Collaborator

@bracadabra bracadabra Aug 10, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

по исходникам при инфлейте проверяется соотвествуют ли параметры по умолчанию тем, которые ты выбираешь и если нет, то вызывается generateLayoutParams(LayoutParams p).

ЗЫ в addViewInternal, если не ошибаюсь

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ага. Т.е. generatelayoutparams вызовется, если мы в xml установим марджины?

Copy link
Collaborator

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) будет вызываться, если мы программно вьюху добавляем

}

@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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ширина экрана не обязательно оставшееся свободное место, это частный случай, когда вьюха растянута на весь экран с match_parent

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да, действительно. Это было сделано для скорости (: По-хорошему, конечно, нужно брать текущий размер вьюхи и из него высчитывать оставшееся свободное пространство.

Copy link
Collaborator

Choose a reason for hiding this comment

The 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));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

При вызове View.measure не учитываются отступы у родителя, это может вести к тому, что вьюха будет обрезаться. Вообще, мне кажется тут больше подходит MeasureSpec.EXACTLY, так как нам нужно заполнить определенную отступ, MeasureSpec.UNSPECIFIED используется, например, тогда, когда родитель это ScrollView и нужно просто измерить весь контент.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А это ручками нужно делать, или есть какой-то метод специальный для этого?
Про EXACTLY согласна, затупила что-то)

Copy link
Collaborator

Choose a reason for hiding this comment

The 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();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

еще бывают и сверху отступы)

Copy link
Author

Choose a reason for hiding this comment

The 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;
}
}

}
130 changes: 120 additions & 10 deletions app/src/main/res/layout/fragment_content.xml
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>
1 change: 1 addition & 0 deletions app/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="text_size">18sp</dimen>

</resources>
2 changes: 1 addition & 1 deletion dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ext.versions = [
compileSdk : 23,
buildTools : '23.0.3',

androidGradlePlugin : '2.2.0-alpha4',
androidGradlePlugin : '2.2.0-alpha6',
aptGradlePlugin : '1.8',
retrolambdaGradlePlugin : '3.2.5',
lombokGradlePlugin : '0.2.3.a2',
Expand Down
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
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