Android: Drawing on Canvas in Scrollview
Asked Answered
P

2

8

I'm pretty much new in programing for Android. My app is sample app from api demos on developer android website. When I change parameters in that sample drawing it gets larger . That drawing needs to be displayed in scroll view (it doesn't need to be shrinked to fit the screen). This is the code I used:

DrawPoints.java

    public class DrawPoints extends myActivity {


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.routes); 

    }

    public static class SampleView extends View {
        private Paint   mPaint = new Paint();
        private float[] mPts;

       /*here comes declaration of parametars



        private void buildPoints() {

        /*here comes some coding*/

            }
        }

        public SampleView(Context context, AttributeSet attributeset) {
            super(context, attributeSet);

            buildPoints();
        }

        @Override 
        protected void onDraw(Canvas canvas) {
            Paint paint = mPaint;

            //here also comes code
        }
    }
}

here is xml Code:

routes.xml

<?xml version="1.0" encoding="utf-8"?>
    <ScrollView 
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/scrollView1"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" >
        <HorizontalScrollView 
                android:id="@+id/scrollView2"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent">

                    <!-- This code is just to make sure that scroll views work how 
                        I want them to work, image size is 625*351 px
                     <ImageView
                        android:id="@+id/image_View1"
                        android:layout_width="fill_parent"
                        android:layout_height="fill_parent"
                        android:src="@drawable/bus_design"
                            /> -->
                     <my.package.DrawPoints.SampleView
                        android:layout_width="fill_parent" 
                        android:layout_height="fill_parent" /> 


        </HorizontalScrollView>
    </ScrollView>

When I run that application and push the button in main activity application crashes. Drawing looks like Figure1 when I'm not using xml layout or scrollviews:

https://i.sstatic.net/za5MP.png Figure1

I also tried to use this code after method setContentView:

View v = new SampleView(this);
addContentView(v, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
            ViewGroup.LayoutParams.FILL_PARENT));

and also this one:

View v = new SampleView(this);
    ScrollView.LayoutParams lp = new ScrollView.LayoutParams(1000, 1000);

    addContentView(v, lp);

when I use codes, shown above, app displays Figure1 without scrollview, it seems like second content view overwrites that xml but it doesn't show correctly. After that I tried to use this code after setContentView:

View v = new SampleView(this);
    FrameLayout fl = new FrameLayout(this);
    fl.findViewById(R.id.FrameLayout1);
    fl.addView(v);

Frame layout (FrameLayout1) is added in routes.xml file after horizontal scroll view. When application runs I get blank screen without Figure1. Does Anyone have an idea how to upgrade my code that would display Figure1 in ScrollView?

Thanks in advance!

Phantom answered 24/4, 2012 at 18:15 Comment(1)
Hello everyone, no one posted any answer on my question so I looked for some solutions. I found that in android is not implemented bi directional Scrolling I found really good implementation of bi directional scrolling on this web page [link]#2045275 solution was posted by Mahdi Hijazi. Solution works like charm, but when I try to implement my SampleView class on his solution again nothing happens. If I got some solution I will than post that solution here. Until then hope that someone have solution.Phantom
M
12

write this line in your touchevent of custom View class

getParent().requestDisallowInterceptTouchEvent(true)

Massengale answered 9/1, 2013 at 11:48 Comment(1)
That is so awsome :) best solution by far thanks! I just call this on the ScrollView parent.Betty
P
5

finally I found solution to my problem. I used solution from this site:

Link1

well I saw that solution before, but unfortunately I didn't realize that this solution is good for me. I knew that I need onMeasure method for Canvas to show it in xml, but withouth of solution from mentioned site it didn't work. Now it works. Here is my xml, and SampleView solution.

XML code:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/app_layout" android:orientation="horizontal"
    android:layout_width="fill_parent" android:layout_height="fill_parent">
    <!-- SCENE -->
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/scene_layout" 
        android:drawingCacheQuality="low"
        android:orientation="horizontal" android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <com.testiranje.Kristijan.TwoDScrollView
            android:id="@+id/scene_scroller" android:drawingCacheQuality="low"
            android:scrollbars="horizontal"

            android:layout_width="fill_parent" android:layout_height="fill_parent">
            <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/scene_container" 
                android:drawingCacheQuality="low"
                android:background="@drawable/map"
                android:layout_width="fill_parent" android:layout_height="fill_parent">

                <com.testiranje.Kristijan.SampleView
                    android:layout_height="fill_parent"
                    android:layout_width="fill_parent">

                    </com.testiranje.Kristijan.SampleView>

                <!--  <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
                    android:id="@+id/scene_background" android:drawingCacheQuality="low"
                    android:background="@drawable/map"
                    android:layout_width="fill_parent" android:layout_height="fill_parent" /> -->
            </RelativeLayout>
        </com.testiranje.Kristijan.TwoDScrollView>
    </RelativeLayout>
</RelativeLayout>

This is my SampleView solution:

 public class SampleView extends View {
    private Paint   mPaint = new Paint();
    private float[] mPts;

    private static final float SIZE = 1000;
    private static final int SEGS = 50;
    private static final int X = 0;
    private static final int Y = 1;

    private void buildPoints() {
        final int ptCount = (SEGS + 1) * 2;
        mPts = new float[ptCount * 2];

        float value = 0;
        final float delta = SIZE / SEGS;
        for (int i = 0; i <= SEGS; i++) {
            mPts[i*4 + X] = SIZE - value;
            mPts[i*4 + Y] = 0;
            mPts[i*4 + X + 2] = 0;
            mPts[i*4 + Y + 2] = value;
            value += delta;
        }
    }

    public SampleView(Context context){
        super(context);
        //initSampleView();
        buildPoints();

    }

   //This constructor is very important because withouth of this 
   //you can't insert this view in xml
   public SampleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        //initSampleView();
        buildPoints();
    }

    /*private final void initSampleView() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        setPadding(3, 3, 3, 3);
    }*/

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(measureWidth(widthMeasureSpec),
                measureHeight(heightMeasureSpec));
    }

    /**
     * Determines the width of this view
     * @param measureSpec A measureSpec packed into an int
     * @return The width of the view, honoring constraints from measureSpec
     */
    private int measureWidth(int measureSpec) {
        int result = 0;
        //This is because of background image in relativeLayout, which is 1000*1000px
        measureSpec = 1001;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.UNSPECIFIED) {
            // We were told how big to be
            result = specSize;
        }

        return result;
    }

    /**
     * Determines the height of this view
     * @param measureSpec A measureSpec packed into an int
     * @return The height of the view, honoring constraints from measureSpec
     */
   private int measureHeight(int measureSpec) {
        int result = 0;
        //This is because of background image in relativeLayout, which is 1000*1000px 
        measureSpec = 1001;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);


        if (specMode == MeasureSpec.UNSPECIFIED) {
            // Here we say how Heigh to be
            result = specSize;
        } 
        return result;
    }

    @Override 
    protected void onDraw(Canvas canvas) {
        Paint paint = mPaint;

        canvas.translate(10, 10);

        paint.setColor(Color.RED);
        paint.setStrokeWidth(0);
        canvas.drawLines(mPts, paint);


        paint.setColor(Color.BLUE);
        paint.setStrokeWidth(3);
        canvas.drawPoints(mPts, paint);

    }
}

Now I got this image, when I run my app:

https://i.sstatic.net/lWhvT.png

If anyone have questions about this feel free to ask me :).

Phantom answered 28/5, 2012 at 20:58 Comment(1)
how to add a scroll on canvas?Beaufert

© 2022 - 2024 — McMap. All rights reserved.