Сохраните рисунки холста для использования после показа фрагмента - PullRequest
0 голосов
/ 09 мая 2019

У меня проблема. В моей MainActivity я вызываю фрагменты, когда вы нажимаете кнопку. Одним из фрагментов является холст SkiaSharp с сеткой TriangleGrid. Когда вы нажимаете на треугольник, он меняет цвет этого треугольника. Теперь, когда я в первый раз перехожу на фрагмент SkiaSharp, все загружается правильно, как я хочу, но когда я перехожу на другую страницу, а затем возвращаюсь на холст SkiaSharp, весь холст остается пустым. Треугольник все еще заполняется, когда вы нажимаете на него, но TriangleGrid больше нет. Также Треугольники, которые были ранее нажаты, кроме последнего. Вот самые важные части моего кода.

Это FULL MainActivity:

public class MainActivity : FragmentActivity
{
    Dictionary<string, TriangleRegistryObject> TriangleRegistry = new Dictionary<string, TriangleRegistryObject>();

    //ALL FRAGMENTS
    private Android.Support.V4.App.Fragment CurrentFragment;
    private int CurrentFragmentNum;
    private int PreviousFragmentNum;
    private Shape_Selection ShapeSelectionFragment;
    private Shape_Formation ShapeFormationFragment;

    private string Direction;


    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        ActionBar.SetCustomView(Resource.Layout.setup_nav_bar);
        ActionBar.SetDisplayShowCustomEnabled(true);
        ((Toolbar)ActionBar.CustomView.Parent).SetContentInsetsAbsolute(0, 0);
        SetContentView(Resource.Layout.activity_main);

        Button btnBack = FindViewById<Button>(Resource.Id.btnBack);
        Button btnNext = FindViewById<Button>(Resource.Id.btnNext);

        btnBack.Click += btnBack_Click;
        btnNext.Click += btnNext_Click;



        ShapeSelectionFragment = new Shape_Selection();
        ShapeFormationFragment = new Shape_Formation();

        var trans = SupportFragmentManager.BeginTransaction();
        trans.Add(Resource.Id.fragmentContainer, ShapeFormationFragment, "Shape_Formation");
        trans.Hide(ShapeFormationFragment);
        trans.Add(Resource.Id.fragmentContainer, ShapeSelectionFragment, "Shape_Selection");
        //trans.Hide(ShapeSelectionFragment);
        trans.Commit();

        CurrentFragmentNum = 1;
        Direction = "Startup";
        ShowFragment(CurrentFragmentNum, 1, Direction);
    }

    private void ShowFragment (int CurrentFragmentNum, int PreviousFragmentNum, string Direction)
    {
        Android.Support.V4.App.Fragment fragment = null;
        Android.Support.V4.App.Fragment PreviousFragment = null;

        switch (CurrentFragmentNum)
        {
            case 1:
                fragment = ShapeSelectionFragment;
                break;
            case 2:
                fragment = ShapeFormationFragment;
                break;
        }

        switch (PreviousFragmentNum)
        {
            case 1:
                PreviousFragment = ShapeSelectionFragment;
                break;
            case 2:
                PreviousFragment = ShapeFormationFragment;
                break;
        }


        var trans = SupportFragmentManager.BeginTransaction();


        switch (Direction)
        {
            case "Forwards":
                trans.SetCustomAnimations(Resource.Animation.slide_in_right, Resource.Animation.slide_out_left);
                break;
            case "Backwards":
                trans.SetCustomAnimations(Resource.Animation.slide_in_left, Resource.Animation.slide_out_right);
                break;
        }

        trans.Replace(Resource.Id.fragmentContainer, fragment);
        trans.Hide(PreviousFragment);
        trans.Show(fragment);
        trans.AddToBackStack(null);
        trans.Commit();

        CurrentFragment = fragment;
        if(CurrentFragment == ShapeSelectionFragment)
        {
            CurrentFragmentNum = 1;
        }
        else if (CurrentFragment == ShapeFormationFragment)
        {
            CurrentFragmentNum = 2;
        }
    }

    public void btnBack_Click(object sender, EventArgs e)
    {
        if (CurrentFragmentNum > 1)
        {
            PreviousFragmentNum = CurrentFragmentNum;
            CurrentFragmentNum -= 1;
            Direction = "Backwards";
            ShowFragment(CurrentFragmentNum, PreviousFragmentNum, Direction);
        }
    }

    public void btnNext_Click(object sender, EventArgs e)
    {
        if (CurrentFragmentNum < 2)
        {
            PreviousFragmentNum = CurrentFragmentNum;
            CurrentFragmentNum += 1;
            Direction = "Forwards";
            ShowFragment(CurrentFragmentNum, PreviousFragmentNum, Direction);
        }
    }
}

И это FULL Shape_Formation.cs:

public class Shape_Formation : Android.Support.V4.App.Fragment, IOnTouchListener
{
    private SKCanvasView skiaView;
    private SKPaint TriangleFillColor;
    private string Action { get; set; }

    Dictionary<string, TriangleRegistryObject> TriangleRegistry = new Dictionary<string, TriangleRegistryObject>();

    private int UnscaledWidth;
    private int UnscaledHeight;

    private int TrianglesPerUpperRow;
    private int TrianglesPerLowerRow;
    private int TrianglesVisiblePerRow = 4;
    private int CurrentRow = 0;

    private float TriangleWidth;
    private float TriangleRowHeight;


    //ALL SHAPE PATHS
    private SKPath TriangleGridPath = new SKPath();
    private SKPath TrianglePath = new SKPath();

    //================//
    // PAINT VARIANTS //
    //================//

    SKPaint TriangleGridPaint = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        Color = SKColors.White,
        StrokeWidth = 3
    };

    SKPaint SelectTrianglePaint = new SKPaint
    {
        Style = SKPaintStyle.Fill,
        Color = SKColors.Blue
    };

    SKPaint UnselectTrianglePaint = new SKPaint
    {
        Style = SKPaintStyle.Fill,
        Color = SKColor.Parse("#0e2a56")
    };

    SKPaint BackgroundPaint = new SKPaint
    {
        Style = SKPaintStyle.Fill,
        Color = SKColor.Parse("#0e2a56")
    };

    SKPaint FocusedTrianglePaint = new SKPaint
    {
        Style = SKPaintStyle.Fill,
        Color = SKColors.LightGray
    };


    //=======================//
    // END OF PAINT VARIANTS //
    //=======================//

    public override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
    }

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.Inflate(Resource.Layout.setup_shape_formation, container, false);

        skiaView = view.FindViewById<SKCanvasView>(Resource.Id.skiaView);
        skiaView.SetOnTouchListener(this);
        skiaView.PaintSurface += PaintSurface;

        return view;
    }

    private void PaintSurface(object sender, SKPaintSurfaceEventArgs e)
    {

        //==============//
        // CANVAS SETUP //
        //==============//

        SKCanvas canvas = e.Surface.Canvas;

        //SOME VARIABLES OF SCREEN SIZE
        UnscaledWidth = e.Info.Width;
        UnscaledHeight = e.Info.Height;

        //=====================//
        // END OF CANVAS SETUP //
        //=====================//


        if (TriangleFillColor != null)
        {
            canvas.DrawPath(TrianglePath, TriangleFillColor);
            canvas.DrawPath(TrianglePath, TriangleGridPaint);
        }


        //====================//
        // DRAW TRIANGLE GRID //
        //====================//

        int TriangleCount = 0;

        TriangleWidth = UnscaledWidth / TrianglesVisiblePerRow;
        TriangleRowHeight = (float)Math.Sqrt(Math.Pow(TriangleWidth, 2) - (Math.Pow((UnscaledWidth / (TrianglesVisiblePerRow * 2)), 2)));

        CurrentRow = 1;
        float X_Start_CooridnateUpperRow = 0;
        float Y_Start_CooridnateUpperRow = 0;

        float X_Start_CooridnateLowerRow = -(TriangleWidth / 2);
        float Y_Start_CooridnateLowerRow = TriangleRowHeight;

        SKPaint TriangleBorderPaint;

        //DRAW MULTIPLE ROWS
        while (Y_Start_CooridnateUpperRow <= UnscaledHeight)
        {

            TrianglesPerUpperRow = 5;
            TrianglesPerLowerRow = 5;

            //SET THE TRIANGLE COUNTER FOR BOTH ROWS
            int TriangleUpperCountOnRow = 0;
            int TriangleLowerCountOnRow = 0;


            //DRAW THE UPPER ROW OF TRIANGLES
            while (TriangleUpperCountOnRow < TrianglesPerUpperRow)
            {
                float x1 = X_Start_CooridnateUpperRow;
                float y1 = Y_Start_CooridnateUpperRow;
                float x2 = X_Start_CooridnateUpperRow + TriangleWidth;
                float y2 = y1;
                float x3 = X_Start_CooridnateUpperRow + TriangleWidth / 2;
                float y3 = TriangleRowHeight * (CurrentRow);

                TriangleGridPath = new SKPath();
                TriangleGridPath.MoveTo(x1, y1);
                TriangleGridPath.LineTo(x2, y2);
                TriangleGridPath.LineTo(x3, y3);
                TriangleGridPath.LineTo(x1, y1);
                TriangleGridPath.Close();

                TriangleRegistryObject value;
                TriangleRegistry.TryGetValue(TriangleCount.ToString(), out value);

                if (value == null)
                {
                    if (x1 > UnscaledWidth ||
                        x2 > UnscaledWidth ||
                        x3 > UnscaledWidth ||
                        x1 < 0 ||
                        x2 < 0 ||
                        x3 < 0 ||
                        y1 > UnscaledHeight ||
                        y2 > UnscaledHeight ||
                        y3 > UnscaledHeight)
                    {
                        TriangleBorderPaint = BackgroundPaint;
                        TriangleRegistry[TriangleCount.ToString()] = new TriangleRegistryObject { x1 = x1, y1 = y1, x2 = x2, y2 = y2, x3 = x3, y3 = y3, Selected = false, Visible = false };
                    }
                    else
                    {
                        TriangleBorderPaint = TriangleGridPaint;
                        TriangleRegistry[TriangleCount.ToString()] = new TriangleRegistryObject { x1 = x1, y1 = y1, x2 = x2, y2 = y2, x3 = x3, y3 = y3, Selected = false, Visible = true };
                    }

                    canvas.DrawPath(TriangleGridPath, TriangleBorderPaint);
                }

                TriangleCount += 1;
                TriangleUpperCountOnRow += 1;
                X_Start_CooridnateUpperRow += TriangleWidth;

            }

            //DRAW THE LOWER ROW OF TRIANGLES
            while (TriangleLowerCountOnRow < TrianglesPerLowerRow)
            {
                float x1 = X_Start_CooridnateLowerRow;
                float y1 = Y_Start_CooridnateLowerRow;
                float x2 = X_Start_CooridnateLowerRow + TriangleWidth;
                float y2 = y1;
                float x3 = X_Start_CooridnateLowerRow + (TriangleWidth / 2);
                float y3 = TriangleRowHeight * (CurrentRow - 1);

                TriangleGridPath = new SKPath();
                TriangleGridPath.MoveTo(x1, y1);
                TriangleGridPath.LineTo(x2, y2);
                TriangleGridPath.LineTo(x3, y3);
                TriangleGridPath.LineTo(x1, y1);
                TriangleGridPath.Close();

                TriangleRegistryObject value;
                TriangleRegistry.TryGetValue(TriangleCount.ToString(), out value);

                if (value == null)
                {
                    if (x1 > UnscaledWidth ||
                        x2 > UnscaledWidth ||
                        x3 > UnscaledWidth ||
                        x1 < 0 ||
                        x2 < 0 ||
                        x3 < 0 ||
                        y1 > UnscaledHeight ||
                        y2 > UnscaledHeight ||
                        y3 > UnscaledHeight)
                    {
                        TriangleBorderPaint = BackgroundPaint;
                        TriangleRegistry[TriangleCount.ToString()] = new TriangleRegistryObject { x1 = x1, y1 = y1, x2 = x2, y2 = y2, x3 = x3, y3 = y3, Selected = false, Focused = false, Visible = false };
                    }
                    else
                    {
                        TriangleBorderPaint = TriangleGridPaint;
                        TriangleRegistry[TriangleCount.ToString()] = new TriangleRegistryObject { x1 = x1, y1 = y1, x2 = x2, y2 = y2, x3 = x3, y3 = y3, Selected = false, Focused = false, Visible = true };
                    }

                    canvas.DrawPath(TriangleGridPath, TriangleBorderPaint);
                }

                TriangleCount += 1;
                TriangleLowerCountOnRow += 1;
                X_Start_CooridnateLowerRow += TriangleWidth;
            }

            CurrentRow += 1;

            if ((CurrentRow - 1) % 2 != 0)
            {
                X_Start_CooridnateUpperRow = -(TriangleWidth / 2);
                X_Start_CooridnateLowerRow = 0;
            }
            else
            {
                X_Start_CooridnateUpperRow = 0;
                X_Start_CooridnateLowerRow = -(TriangleWidth / 2);
            }

            Y_Start_CooridnateUpperRow += TriangleRowHeight;
            Y_Start_CooridnateLowerRow += TriangleRowHeight;

        }

        //==============================//
        // END OF DRAWING TRIANGLE GRID //
        //==============================//

    }

    public override void OnDestroy()
    {
        skiaView.PaintSurface -= PaintSurface;
        base.OnDestroy();
    }


    private void DrawTrianglePath(double x1, double y1, double x2, double y2, double x3, double y3, string key, string Action)
    {
        bool ChangedState = true;

        var Triangle = TriangleRegistry[key];
        if (Triangle.Visible == true)
        {
            if (Triangle.Selected == false)
            {
                if (Action == "Selected")
                {
                    Triangle.Selected = true;
                    TriangleRegistry[key] = Triangle;
                    TriangleFillColor = SelectTrianglePaint;
                }
                else if (Action == "Focused")
                {
                    if (Triangle.Focused == false)
                    {
                        Triangle.Focused = true;
                        TriangleRegistry[key] = Triangle;
                        TriangleFillColor = FocusedTrianglePaint;
                    }
                }

            }
            else
            {
                Triangle.Selected = false;
                TriangleFillColor = UnselectTrianglePaint;
            }

            if (ChangedState == true)
            {
                TrianglePath = new SKPath();
                TrianglePath.MoveTo((float)Triangle.x1, (float)Triangle.y1);
                TrianglePath.LineTo((float)Triangle.x2, (float)Triangle.y2);
                TrianglePath.LineTo((float)Triangle.x3, (float)Triangle.y3);
                TrianglePath.LineTo((float)Triangle.x1, (float)Triangle.y1);
                TrianglePath.Close();

                skiaView.Invalidate();
            }
        }
    }

    public bool OnTouch(View v, MotionEvent e)
    {
        if (e.Action == MotionEventActions.Down)
        {

            var X_Clicked = e.GetX();
            var Y_Clicked = e.GetY();

            bool TriangleFound = false;

            while (TriangleFound == false)
            {
                foreach (KeyValuePair<string, TriangleRegistryObject> row in TriangleRegistry.ToList())
                {
                    if (isInside(row.Value.x1, row.Value.y1, row.Value.x2, row.Value.y2, row.Value.x3, row.Value.y3, X_Clicked, Y_Clicked))
                    {
                        TriangleFound = true;
                        Action = "Selected";
                        DrawTrianglePath(row.Value.x1, row.Value.y1, row.Value.x2, row.Value.y2, row.Value.x3, row.Value.y3, row.Key, Action);
                    }
                }
            }
        }

        return true;
    }

    static double area(double x1, double y1, double x2, double y2, double x3, double y3)
    {
        return Math.Abs((x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) / 2.0);
    }

    static bool isInside(double x1, double y1, double x2, double y2, double x3, double y3, double x, double y)
    {
        double A = area(x1, y1, x2, y2, x3, y3);
        double A1 = area(x, y, x2, y2, x3, y3);
        double A2 = area(x1, y1, x, y, x3, y3);

        /* Calculate area of triangle PAB */
        double A3 = area(x1, y1, x2, y2, x, y);

        /* Check if sum of A1, A2 and A3 is same as A */
        return (A == A1 + A2 + A3);
    }
}

Может кто-нибудь помочь мне с этой проблемой!?

1 Ответ

1 голос
/ 10 мая 2019

вы можете увидеть эти строки кода в вашем ShowFragment:

trans.Replace(Resource.Id.fragmentContainer, fragment);
    trans.Hide(PreviousFragment);
    trans.Show(fragment);
    trans.AddToBackStack(null);
    trans.Commit();

вы используете replace, он будет уничтожать фрагмент, который вы добавили в Resource.Id.fragmentContainer ранее, поэтому он не мог сохранить холст, здесь вам нужно только показать и скрыть фрагмент, который вы добавили ранее, вы можете просто изменить вот так (это не уничтожит фрагмент, а скроет и покажет):

trans.Hide(PreviousFragment);
trans.Show(fragment);
trans.Commit();
...