2

First of all, my Programm compiles, and starts. But as soon as you tab on the LinearLayout that uses the GestureDetector it throws a NullPointerException.

I have a Activity, in which a Fragment named "OrderFragment" is nested.

public class OrderFragment extends Fragment {
View view;
Activity activty;
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.orderfragment, container, false);
    return view;
}


@Override
public void onResume(){
    super.onResume();
    DragList orderContainer = (DragList) view.findViewById(R.id.orderContainer);
    for (int i=0;i<5;++i) {

        final TextView tv = new TextView(getActivity().getApplicationContext());
        tv.setTextColor(0x888888);
        tv.setText("wtf");
        orderContainer.addView(tv,new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
    }

}

}

In here, i want to programatically add some TextView into a DragView. This DragView exists in the orderfragment.xml

In the DragView class i try to create some TextViews, the Users can Drag and swap that way. But i struggle to get the Draging to work. Please notice, that the onTouchEvent function is copied word by word from the official android webiste here

public class DragList extends LinearLayout {


public DragList(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
}

public DragList(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context);
}

private void init(Context context) {
    //do stuff that was in your original constructor...
}

// The active pointer is the one currently moving our object.
private int INVALID_POINTER_ID = -1;
private int mActivePointerId = INVALID_POINTER_ID;
private float mLastTouchX;
private float mLastTouchY;
private GestureDetector mScaleDetector;

public DragList(Context context) {
    super(context);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    // Let the ScaleGestureDetector inspect all events.

    mScaleDetector.onTouchEvent(ev);

    final int action = MotionEventCompat.getActionMasked(ev);

    switch (action) {
        case MotionEvent.ACTION_DOWN: {
            final int pointerIndex = MotionEventCompat.getActionIndex(ev);
            final float x = MotionEventCompat.getX(ev, pointerIndex);
            final float y = MotionEventCompat.getY(ev, pointerIndex);

            // Remember where we started (for dragging)
            mLastTouchX = x;
            mLastTouchY = y;
            // Save the ID of this pointer (for dragging)
            mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
            break;
        }

        case MotionEvent.ACTION_MOVE: {
            // Find the index of the active pointer and fetch its position
            final int pointerIndex =
                    MotionEventCompat.findPointerIndex(ev, mActivePointerId);

            final float x = MotionEventCompat.getX(ev, pointerIndex);
            final float y = MotionEventCompat.getY(ev, pointerIndex);

            // Calculate the distance moved
            final float dx = x - mLastTouchX;
            final float dy = y - mLastTouchY;

            float mPosX = dx;
            float mPosY = dy;



            // Remember this touch position for the next move event
            mLastTouchX = x;
            mLastTouchY = y;

            break;
        }

        case MotionEvent.ACTION_UP: {
            mActivePointerId = INVALID_POINTER_ID;
            break;
        }

        case MotionEvent.ACTION_CANCEL: {
            mActivePointerId = INVALID_POINTER_ID;
            break;
        }

        case MotionEvent.ACTION_POINTER_UP: {

            final int pointerIndex = MotionEventCompat.getActionIndex(ev);
            final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);

            if (pointerId == mActivePointerId) {
                // This was our active pointer going up. Choose a new
                // active pointer and adjust accordingly.
                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                mLastTouchX = MotionEventCompat.getX(ev, newPointerIndex);
                mLastTouchY = MotionEventCompat.getY(ev, newPointerIndex);
                mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
            }
            break;
        }
    }
    return true;
}

}

The Error:

    java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.view.GestureDetector.onTouchEvent(android.view.MotionEvent)' on a null object reference
        at com.example.jacobusconradi.versuchstestappv20.DragList.onTouchEvent(DragList.java:46)

And i can also confirm, that the DragList is visually empty, or NOT there, as I only see the white backgroundcolor given to the Container. When i use Debugging-mode it doesnt throw anything though, when i get to the programatically added TextViews.

THanks for help and cheers

PlatinTato
  • 378
  • 2
  • 19

2 Answers2

3

Please initialize mScaleDetector in your Constructor section

http://developer.android.com/intl/es/reference/android/view/GestureDetector.html

mScaleDetector = new GestureDetector(context);

Finally

    public DragList(Context context) {
    super(context);
    mScaleDetector = new GestureDetector(context);
    }
IntelliJ Amiya
  • 74,896
  • 15
  • 165
  • 198
  • ok now i am seriously confused. When i do this, it says that it is deprecated, and there is no Option for the GestrureDetector constructor to take a Context, but wants to cast it into a OnGestureListener – PlatinTato Nov 04 '15 at 11:55
  • @JacobusConradi http://stackoverflow.com/questions/12873708/gesturedetector-deprecated-issue – IntelliJ Amiya Nov 04 '15 at 11:56
  • @IntelliJAmiya i have the same problem here https://stackoverflow.com/questions/62507726/attempt-to-invoke-virtual-method-float-android-view-motionevent-getx-on-exop – sanoj lawrence Jun 22 '20 at 16:33
0

Please instantiate your gesture Detector

public DragList(Context context) {
    super(context);
    mScaleDetector = new GestureDetector(context);
}

Hope this helps.

EDIT

You dont need the gestureDetector for what you are doing, you can just delete it and it should work.

You will need to pass a OnGestureListener if you want the gestureDetector to be able to do something.

Nanoc
  • 2,381
  • 1
  • 20
  • 35