Переполнение стека ViewDragHelper

Я следил за этим пошаговым руководством для ViewDragHelper.

http://flavienlaurent.com/blog/2013/08/28/each-navigation-drawer-hides-a-viewdraghelper/

В настоящее время я пытаюсь реализовать собственный макет, и у меня возникают проблемы с ViewDragHelper. Я пытаюсь получить макет в стиле «ящика» с ручкой перетаскивания, которая открывается справа налево (т.е. по горизонтали). Я знаю, что SliderDrawer справляется с этой задачей, но моя цель — просто узнать о ViewDragHelper. Это ошибка, которую я получаю:

09-24 14:27:21.031: E/AndroidRuntime(24002): FATAL EXCEPTION: main
09-24 14:27:21.031: E/AndroidRuntime(24002): java.lang.StackOverflowError
09-24 14:27:21.031: E/AndroidRuntime(24002):    at android.widget.TextView.setFrame(TextView.java:4365)
09-24 14:27:21.031: E/AndroidRuntime(24002):    at android.view.View.layout(View.java:14293)
09-24 14:27:21.031: E/AndroidRuntime(24002):    at com.example.vdh.DragLayout.onLayout(DragLayout.java:91)
09-24 14:27:21.031: E/AndroidRuntime(24002):    at android.view.View.layout(View.java:14296)
09-24 14:27:21.031: E/AndroidRuntime(24002):    at android.view.ViewGroup.layout(ViewGroup.java:4562)
09-24 14:27:21.031: E/AndroidRuntime(24002):    at com.example.vdh.DragLayout.onLayout(DragLayout.java:97)
09-24 14:27:21.031: E/AndroidRuntime(24002):    at android.view.View.layout(View.java:14296)
09-24 14:27:21.031: E/AndroidRuntime(24002):    at android.view.ViewGroup.layout(ViewGroup.java:4562)

Обратите внимание, что последние 3 или около того строки повторяются. Я знаю, что эта функция onLayout отвечает за исключение во время выполнения. Вот исходный код:

package com.example.vdh;

import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;

public class DragLayout extends LinearLayout {

private final ViewDragHelper mDragHelper;
private View mDrawerView;
private View mHandle;

private int mDragRange;
private int mLeft;

public DragLayout(Context context) {
  this(context, null);
}

public DragLayout(Context context, AttributeSet attrs) {
  this(context, attrs, 0);
}

public DragLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mDragHelper = ViewDragHelper.create(this, 1.0f, new DragHelperCallback());
}

@Override
protected void onFinishInflate() {
    mHandle = findViewById(R.id.handle);
    mDrawerView = findViewById(R.id.drawer);
}


@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
  final int action = MotionEventCompat.getActionMasked(ev);
  if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
      mDragHelper.cancel();
      return false;
  }
  return mDragHelper.shouldInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
  mDragHelper.processTouchEvent(ev);
  return true;
}

private class DragHelperCallback extends ViewDragHelper.Callback {

    @Override
    public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
        mLeft = left;
        requestLayout();
    }

    @Override
    public int clampViewPositionHorizontal(View child, int left, int dx) {
      Log.d("DragLayout", "clampViewPositionHorizontal " + left + "," + dx);

      final int leftBound = getPaddingLeft();
      final int rightBound = getWidth() - mHandle.getWidth();

      final int newLeft = Math.min(Math.max(left, leftBound), rightBound);

      return newLeft;
    }

    @Override
    public boolean tryCaptureView(View child, int pointerId) {
        return child == mHandle;
    }
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    //mDragRange = getHeight() - mHandle.getWidth();

    /*Log.d("onLayout", "Handle: " + mHandle.getWidth() + ", " + mHandle.getHeight());
    Log.d("onLayout", "Drawer: " + mDrawerView.getWidth() + ", " + mDrawerView.getHeight());*/


    mHandle.layout(
        mLeft,
        0,
        mLeft + mHandle.getMeasuredWidth(),
        b);

    mDrawerView.layout(
        mLeft + mHandle.getMeasuredWidth(),
        0,
        mLeft + r,
        b);
}

}

    mHandle.layout(
        mLeft,
        0,
        mLeft + mHandle.getMeasuredWidth(),
        b);

    mDrawerView.layout(
        mLeft + mHandle.getMeasuredWidth(),
        0,
        mLeft + r,
        b);
}

person user1927638    schedule 24.09.2013    source источник
comment
Пожалуйста, обновите свой вопрос с помощью макета XML.   -  person Basbous    schedule 13.10.2013


Ответы (1)


Согласно трассировке стека, у вас есть рекурсивный вызов onLayout вашего DragLayout.

Ваш DragLayout вызывает layout(...) только для двух представлений: mHandle и mDrawerView, и кажется, что одно из них (не может определить по журналам, какое из них) вызывает переполнение стека.

Пожалуйста, опубликуйте свой код просмотра, чтобы я мог попытаться помочь вам найти проблему.

person Erez    schedule 31.12.2013
comment
Это не ответ. Пожалуйста, напишите разъяснение, которое вы хотите, в комментариях - person Rohan Kandwal; 31.12.2013