Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android共享绘图画布路径绘图顺序_Android_Firebase_Canvas_Firebase Realtime Database_Path - Fatal编程技术网

Android共享绘图画布路径绘图顺序

Android共享绘图画布路径绘图顺序,android,firebase,canvas,firebase-realtime-database,path,Android,Firebase,Canvas,Firebase Realtime Database,Path,我正在开发一个协作的艺术应用程序,用户可以使用FireBase实时数据库在画布上一起画一段距离。我已经到了一个点,在一个用户屏幕上绘制的片段出现在另一个用户的屏幕上,反之亦然 但是,一旦片段从firebase中拉出,它将在背景中绘制片段,而不是在用户“绘制”的顶部 有没有一种方法可以告诉程序总是把不同的片段画在彼此的上面 我将使用的代码片段放在这里: 这是我从FireBase中提取片段的地方: mListener=mRef.addChildEventListener(new C

我正在开发一个协作的艺术应用程序,用户可以使用FireBase实时数据库在画布上一起画一段距离。我已经到了一个点,在一个用户屏幕上绘制的片段出现在另一个用户的屏幕上,反之亦然

但是,一旦片段从firebase中拉出,它将在背景中绘制片段,而不是在用户“绘制”的顶部

有没有一种方法可以告诉程序总是把不同的片段画在彼此的上面

我将使用的代码片段放在这里:

这是我从FireBase中提取片段的地方:

        mListener=mRef.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
                String name=dataSnapshot.getKey();
                if (!mOutstandingSegments.contains(name)) {
                    Segment segment = dataSnapshot.getValue(Segment.class);

                    drawSegmentPath(segment.getPoints(), segment.getColor(), segment.getBlurEnabled(), segment.getStrokeWidth());

                    //invalidate();
                }
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {            
                }
            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });
    } 
    private void touchUp(){
        mPath.lineTo(mX,mY);

        DatabaseReference segmentRef=mRef.push();
        final String segmentName=segmentRef.getKey();
        currentSegmentKey=segmentName;
        mOutstandingSegments.add(segmentName);

        Segment mySegment = new Segment(mCurrentSegment.getColor(), mCurrentSegment.getStrokeWidth(), blurEnabled);
        for (Point point: mCurrentSegment.getPoints()) {
            mySegment.addPoint(point.x , point.y );
        }

        System.out.println("Segment is: " + mySegment);

        // Save our segment into Firebase.
        segmentRef.setValue(mySegment, new DatabaseReference.CompletionListener() {
            @Override
            public void onComplete(DatabaseError error, DatabaseReference firebaseRef) {
                if (error != null) {
                    throw error.toException();
                }
                mOutstandingSegments.remove(segmentName);
            }
        });
    }
使用以下方法将段转换为路径:

    public void drawSegmentPath(List<Point> segmentPoints, int color, boolean blurEnabled, float strokeWidth){
        Point currentSegmentPoint = segmentPoints.get(0);

        Path newSegmentPath = new Path();
        FingerPath fireBasePath = new FingerPath(color, blurEnabled, strokeWidth, newSegmentPath);

        firePath.add(fireBasePath);

        newSegmentPath.reset();

        newSegmentPath.moveTo(currentSegmentPoint.x, currentSegmentPoint.y);

        Point nextSegmentPoint = null;
        invalidate();

        for (int i = 1; i < segmentPoints.size(); i++) {
            nextSegmentPoint = segmentPoints.get(i);
            newSegmentPath.quadTo(currentSegmentPoint.x, currentSegmentPoint.y, (int)((nextSegmentPoint.x + currentSegmentPoint.x) / 2), (int)((nextSegmentPoint.y + currentSegmentPoint.y) / 2));
            currentSegmentPoint = nextSegmentPoint;
            System.out.println("Current Segment Points: " + currentSegmentPoint);

            invalidate();
        }


        if (nextSegmentPoint != null) {
            newSegmentPath.lineTo(nextSegmentPoint.x, nextSegmentPoint.y);
            invalidate();
        }

    }
当用户通过在segment类中不断添加点在屏幕上移动手指时,将生成一个段:

    pivate void touchStart(float positionX, float positionY){

        mPath = new Path();
        FingerPath fp = new FingerPath(currentBrushColor, blurEnabled, strokeWidth, mPath);
        mCurrentSegment = new Segment(currentBrushColor, strokeWidth, blurEnabled);
        paths.add(fp);

        mPath.reset();
        mPath.moveTo(positionX, positionY);

        mX = positionX;
        mY = positionY;

        mCurrentSegment.addPoint((int)mX, (int)mY);

    }

    private void touchMove(float positionX, float positionY){
        float dx = Math.abs(positionX - mX);
        float dy = Math.abs(positionY - mY);

        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE){
            mPath.quadTo(mX, mY, (positionX + mX)/2, (positionY + mY)/2);
            mX = positionX;
            mY = positionY;
            mCurrentSegment.addPoint((int)mX, (int)mY);
        }
    }

然后,当用户完成绘图时,该段被推入FireBase:

        mListener=mRef.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
                String name=dataSnapshot.getKey();
                if (!mOutstandingSegments.contains(name)) {
                    Segment segment = dataSnapshot.getValue(Segment.class);

                    drawSegmentPath(segment.getPoints(), segment.getColor(), segment.getBlurEnabled(), segment.getStrokeWidth());

                    //invalidate();
                }
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {            
                }
            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });
    } 
    private void touchUp(){
        mPath.lineTo(mX,mY);

        DatabaseReference segmentRef=mRef.push();
        final String segmentName=segmentRef.getKey();
        currentSegmentKey=segmentName;
        mOutstandingSegments.add(segmentName);

        Segment mySegment = new Segment(mCurrentSegment.getColor(), mCurrentSegment.getStrokeWidth(), blurEnabled);
        for (Point point: mCurrentSegment.getPoints()) {
            mySegment.addPoint(point.x , point.y );
        }

        System.out.println("Segment is: " + mySegment);

        // Save our segment into Firebase.
        segmentRef.setValue(mySegment, new DatabaseReference.CompletionListener() {
            @Override
            public void onComplete(DatabaseError error, DatabaseReference firebaseRef) {
                if (error != null) {
                    throw error.toException();
                }
                mOutstandingSegments.remove(segmentName);
            }
        });
    }
在以下onTouchEvent lstener中调用不同的onTouch方法:

    @Override
    public boolean onTouchEvent(MotionEvent event){

            float positionX = event.getX()
            float positionY = event.getY()

            switch (event.getAction()) {

                case MotionEvent.ACTION_DOWN:
                    touchStart(positionX, positionY);
                    invalidate();
                    break;
                case MotionEvent.ACTION_MOVE:
                    touchMove(positionX, positionY);
                    invalidate();
                    break;
                case MotionEvent.ACTION_UP:
                    touchUp();
                    invalidate();

                    break;
            }
        }

        return true;
    }


堆栈溢出是一种效率极低的交互式调试器。您已经发布了450多行代码,这对我们来说太多了,无法合理地帮助您。我建议您按照中的指导隔离问题。感谢@FrankvanPuffelen的回复!请原谅我。我只有几周的编码经验,这是我的第一篇帖子,所以在我看来,一切都很重要,哈哈。我已尝试构建代码,使其更易于理解,并消除了不必要的内容;)希望这使它更容易理解!堆栈溢出是一种效率极低的交互式调试器。您已经发布了450多行代码,这对我们来说太多了,无法合理地帮助您。我建议您按照中的指导隔离问题。感谢@FrankvanPuffelen的回复!请原谅我。我只有几周的编码经验,这是我的第一篇帖子,所以在我看来,一切都很重要,哈哈。我已尝试构建代码,使其更易于理解,并消除了不必要的内容;)希望这使它更容易理解!