Ich habe vor kurzem benutzerdefinierte Ansichten studiert und versucht, ein spezielles Beispiel ausrechnen aus einem Tutorial hier befindet sich zu machen: http://flavienlaurent.com/blog/2013/08/28/each-navigation-drawer-hides-a-viewdraghelper/Kinder match_parent ignorieren Eltern in benutzerdefinierte Ansicht mit viewdraghelper
Ich werde den entsprechenden Code hinzufügen Informationsverlust zu verhindern, toter Link. Der Autor des Tutorial erklärt, wie ein ViewDragHelper ähnlich wie YouTube Android App Spielerverhalten erstellen und diese sind die Codes er
vorgesehenactivity_main.xml
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:tag="list"
/>
<com.example.vdh.YoutubeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/youtubeLayout"
android:orientation="vertical"
android:visibility="visible">
<TextView
android:id="@+id/viewHeader"
android:layout_width="match_parent"
android:layout_height="128dp"
android:fontFamily="sans-serif-thin"
android:textSize="25sp"
android:tag="text"
android:gravity="center"
android:textColor="@android:color/white"
android:background="#AD78CC"/>
<TextView
android:id="@+id/viewDesc"
android:tag="desc"
android:textSize="35sp"
android:gravity="center"
android:text="Loreum Loreum"
android:textColor="@android:color/white"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF00FF"/>
</com.example.vdh.YoutubeLayout>
YoutubeLayout.java
public class YoutubeLayout extends ViewGroup {
private final ViewDragHelper mDragHelper;
private View mHeaderView;
private View mDescView;
private float mInitialMotionX;
private float mInitialMotionY;
private int mDragRange;
private int mTop;
private float mDragOffset;
public YoutubeLayout(Context context) {
this(context, null);
}
public YoutubeLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@Override
protected void onFinishInflate() {
mHeaderView = findViewById(R.id.viewHeader);
mDescView = findViewById(R.id.viewDesc);
}
public YoutubeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mDragHelper = ViewDragHelper.create(this, 1f, new DragHelperCallback());
}
public void maximize() {
smoothSlideTo(0f);
}
boolean smoothSlideTo(float slideOffset) {
final int topBound = getPaddingTop();
int y = (int) (topBound + slideOffset * mDragRange);
if (mDragHelper.smoothSlideViewTo(mHeaderView, mHeaderView.getLeft(), y)) {
ViewCompat.postInvalidateOnAnimation(this);
return true;
}
return false;
}
private class DragHelperCallback extends ViewDragHelper.Callback {
@Override
public boolean tryCaptureView(View child, int pointerId) {
return child == mHeaderView;
}
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
mTop = top;
mDragOffset = (float) top/mDragRange;
mHeaderView.setPivotX(mHeaderView.getWidth());
mHeaderView.setPivotY(mHeaderView.getHeight());
mHeaderView.setScaleX(1 - mDragOffset/2);
mHeaderView.setScaleY(1 - mDragOffset/2);
mDescView.setAlpha(1 - mDragOffset);
requestLayout();
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
int top = getPaddingTop();
if (yvel > 0 || (yvel == 0 && mDragOffset > 0.5f)) {
top += mDragRange;
}
mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), top);
}
@Override
public int getViewVerticalDragRange(View child) {
return mDragRange;
}
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
final int topBound = getPaddingTop();
final int bottomBound = getHeight() - mHeaderView.getHeight() - mHeaderView.getPaddingBottom();
final int newTop = Math.min(Math.max(top, topBound), bottomBound);
return newTop;
}
}
@Override
public void computeScroll() {
if (mDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = MotionEventCompat.getActionMasked(ev);
if ((action != MotionEvent.ACTION_DOWN)) {
mDragHelper.cancel();
return super.onInterceptTouchEvent(ev);
}
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
mDragHelper.cancel();
return false;
}
final float x = ev.getX();
final float y = ev.getY();
boolean interceptTap = false;
switch (action) {
case MotionEvent.ACTION_DOWN: {
mInitialMotionX = x;
mInitialMotionY = y;
interceptTap = mDragHelper.isViewUnder(mHeaderView, (int) x, (int) y);
break;
}
case MotionEvent.ACTION_MOVE: {
final float adx = Math.abs(x - mInitialMotionX);
final float ady = Math.abs(y - mInitialMotionY);
final int slop = mDragHelper.getTouchSlop();
if (ady > slop && adx > ady) {
mDragHelper.cancel();
return false;
}
}
}
return mDragHelper.shouldInterceptTouchEvent(ev) || interceptTap;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
mDragHelper.processTouchEvent(ev);
final int action = ev.getAction();
final float x = ev.getX();
final float y = ev.getY();
boolean isHeaderViewUnder = mDragHelper.isViewUnder(mHeaderView, (int) x, (int) y);
switch (action & MotionEventCompat.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
mInitialMotionX = x;
mInitialMotionY = y;
break;
}
case MotionEvent.ACTION_UP: {
final float dx = x - mInitialMotionX;
final float dy = y - mInitialMotionY;
final int slop = mDragHelper.getTouchSlop();
if (dx * dx + dy * dy < slop * slop && isHeaderViewUnder) {
if (mDragOffset == 0) {
smoothSlideTo(1f);
} else {
smoothSlideTo(0f);
}
}
break;
}
}
return isHeaderViewUnder && isViewHit(mHeaderView, (int) x, (int) y) || isViewHit(mDescView, (int) x, (int) y);
}
private boolean isViewHit(View view, int x, int y) {
int[] viewLocation = new int[2];
view.getLocationOnScreen(viewLocation);
int[] parentLocation = new int[2];
this.getLocationOnScreen(parentLocation);
int screenX = parentLocation[0] + x;
int screenY = parentLocation[1] + y;
return screenX >= viewLocation[0] && screenX < viewLocation[0] + view.getWidth() &&
screenY >= viewLocation[1] && screenY < viewLocation[1] + view.getHeight();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measureChildren(widthMeasureSpec, heightMeasureSpec);
int maxWidth = MeasureSpec.getSize(widthMeasureSpec);
int maxHeight = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, 0),
resolveSizeAndState(maxHeight, heightMeasureSpec, 0));
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mDragRange = getHeight() - mHeaderView.getHeight();
mHeaderView.layout(
0,
mTop,
r,
mTop + mHeaderView.getMeasuredHeight());
mDescView.layout(
0,
mTop + mHeaderView.getMeasuredHeight(),
r,
mTop + b);
}
}
Die Autor stellt fest, dass onLayout
und onMeasure
schlecht geschrieben sind und ich nehme an diese (oder einer von ihnen) könnte die Ursache eines Problems mit einem der Kinder sein.
Für mein Ziel, ersetzte ich die mDescView
mit einer Framelayout
Ansicht, die die entsprechenden TextView
enthält. Beide haben ihre Höhe auf match_parent
und das übergeordnete (mDescView
) legt seine Höhe korrekt, aber seine Kinder (TextView
innerhalb mDescView
) ignorieren die übergeordnete Höhe und strecken, um ihre Höhe gleich der Bildschirmhöhe (oder der benutzerdefinierten Ansichtshöhe , kann den Unterschied nicht erkennen). Dies ist ein Problem, weil die mDescView
Kinder nie ihre Höhe korrekt nach dem Eltern durch anpassen und ich suchte nach einer Lösung für Tage, aber keine wurde gefunden und durch Forschung konnte ich keinen Grund finden, warum dies geschah .
Dies ist das Ergebnis dieses Problems feststellen, wie die TextView
Höhe ist größer als ihre Mutter mDescView
trotz beide haben ihre Höhe auf match_parent
Also mein Problem ist, wie kann ich die Kind (Kinder) dieses Elternteils (oder jeder Elternteil), um die Größe ihrer Eltern so anzupassen, wie sie es sollten.
Als zusätzliche Anfrage, wenn möglich, kann jemand erklären, warum der Autor denkt, dass einige seiner Methoden nicht die besten/richtigen sind und wie sie stattdessen richtig/besser gemacht werden sollten.