Candy Flip
Candy Flip

Reputation: 1

Is it possible to send the TouchEvents of a user's device in realtime to another device?

I have the following code in Android Studio (java) (Maybe the view has too much methods and irrelevant methods, variables?)

public class Drawingview extends View {

    private DatabaseReference mDatabase;
    private Path mPath;
    private Paint mPaint;
    private float mX, mY;
    private static final float TOUCH_TOLERANCE = 4;

    public Drawingview(Context context) {
        super(context);
        init();
    }

    public Drawingview(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public Drawingview(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mDatabase = FirebaseDatabase.getInstance().getReference().child("points");
        mPath = new Path();
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeWidth(12f);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPath(mPath, mPaint);
    }

    private void touchStart(float x, float y) {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }

    private void touchMove(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
            mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
            mX = x;
            mY = y;

            // Send the points to Firebase database
            Point point = new Point(x, y);
            mDatabase.push().setValue(point);
        }
    }

    private void touchUp() {
        mPath.lineTo(mX, mY);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touchStart(x, y);
                break;
            case MotionEvent.ACTION_MOVE:
                touchMove(x, y);
                break;
            case MotionEvent.ACTION_UP:
                touchUp();
                break;
            default:
                return false;
        }

        invalidate();
        return true;
    }

    public static class Point {
        public float x;
        public float y;

        public Point(float x, float y) {
            this.x = x;
            this.y = y;
        }

        public Point() {
            // Required empty constructor for Firebase
        }
    }
  }

The layout.xml part looks like this

<RelativeLayout
        android:id="@+id/relative_drawing"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <FrameLayout
            android:id="@+id/drawing_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/white">

            <com.example.apps.Drawingview
                android:id="@+id/drawing_view_drawer"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginStart="@dimen/margin_10dp"
                android:layout_marginTop="5dp"
                android:layout_marginEnd="@dimen/margin_10dp"
                android:layout_marginBottom="5dp" />
        </FrameLayout>
    </RelativeLayout>

This works so far. I can draw and the points are added to the Firebase database

What I want to do is, that another user receives the last points which where added to the firebase by the other user. This user has another layout which looks like this:

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <FrameLayout
            android:id="@+id/path_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/kariert_block_version1">

            <com.example.app.views.PathView
                android:id="@+id/path_view_realtime"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginStart="@dimen/margin_10dp"
                android:layout_marginTop="5dp"
                android:layout_marginEnd="@dimen/margin_10dp"
                android:layout_marginBottom="5dp"/>
        </FrameLayout>
    </RelativeLayout>

Now here's what I don't quite understand: So I want the other user to listen to every change. I do that with the following code?

DatabaseReference pointsRef = FirebaseDatabase.getInstance().getReference("points");

  // Listen for new touch event data and draw it on the view
        pointsRef.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
                //what Im doing here?
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String   previousChildName) {

            }

But where must the code be implemented? In the PathView class or in the activity where the layout is?

And the most important. How can I show in realtime a point at the position where the other user presses on his display? so I want to see only a point, without a line or something - just the position of the touch.

Thanks in advance!

I tried it with the codes provided above, but I cant figure out what to do with the points. How to draw it and how to receive only the last points of the database.

Upvotes: 0

Views: 28

Answers (1)

Candy Flip
Candy Flip

Reputation: 1

Ok guys I did it:

I created this view class:

public class PointsView extends View {

private DatabaseReference mDatabase;
private Paint mPaint;
private List<Point> mPoints;

public PointsView(Context context) {
    super(context);
    init();
}

public PointsView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    init();
}

public PointsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
}

private void init() {
    mDatabase = FirebaseDatabase.getInstance().getReference().child("points");
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setColor(Color.BLACK);
    mPaint.setStyle(Paint.Style.FILL);
    mPoints = new ArrayList<>();

    // Listen for child added events
    mDatabase.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
            Point point = dataSnapshot.getValue(Point.class);
            mPoints.add(point);
            invalidate();
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
            // Do nothing
        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {
            // Do nothing
        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
            // Do nothing
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            // Do nothing
        }
    });
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    for (Point point : mPoints) {
        canvas.drawCircle(point.x, point.y, 20f, mPaint);
    }
}

public static class Point {
    public float x;
    public float y;

    public Point(float x, float y) {
        this.x = x;
        this.y = y;
    }

    public Point() {
        // Required empty constructor for Firebase
    }
}
}

also I updated the layout.xml file to this:

<com.example.app.PointsView
    android:id="@+id/path_view_end_showing"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginStart="@dimen/margin_10dp"
    android:layout_marginEnd="@dimen/margin_10dp"
    android:layout_marginTop="@dimen/margin_10dp"
    android:layout_marginBottom="@dimen/margin_10dp"/>

So I just removed the Framelayout and Realtivelayout and it is working!

Upvotes: 0

Related Questions