0

We're trying to pass an ArrayList from Main Activity to use it in CustomView class.Both classes belong to the same activity.Depending on this array, some rectangles will be drawn on an image, but the array passed is always empty. We're newbies in Android and we've checked similar questions but nothing worked out with us.

This is the MainActivity.java class

package com.example.android.a3ozaarken;

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {


    //private CustomView mcustomView;
    public static ArrayList<String[]> park_data = new ArrayList<String[]>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    private ProgressDialog pDialog;
    String JSON_STRING ;
    JSONArray jsonArray;
    JSONObject jsonObject;
    private CustomView customView;

    // public Hashtable<Integer, Integer> hash_data = new Hashtable<Integer, Integer>();
    // Hashtable <Integer, String> hashPlaces = new Hashtable<Integer,String>();


    public void getJSON(View view)
    {

        new BackgroundTask().execute();

    }


    class BackgroundTask extends AsyncTask<Void,Void,String>

    {    String json_url ;
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            json_url="http://192.168.1.103/erknly.php?id=0";

            pDialog = new ProgressDialog(MainActivity.this);
            pDialog.setMessage("Please wait...");
            pDialog.setCancelable(false);
            pDialog.show();

        }

        @Override
        protected String doInBackground(Void... voids) {
            try {
                URL url = new URL(json_url);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = httpURLConnection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder stringBuilder = new StringBuilder();
                while((JSON_STRING = bufferedReader.readLine())!=null){
                    stringBuilder.append(JSON_STRING+"\n");
                }
                bufferedReader.close();
                inputStream.close();
                httpURLConnection.disconnect();
                return stringBuilder.toString().trim();

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
        }

        @Override
        protected void onPostExecute(String result) {
            //super.onPostExecute(aVoid);
            TextView textView = (TextView) findViewById(R.id.textView);
            int count = 0 ;
            String places,status,id;

            if (pDialog.isShowing())
                pDialog.dismiss();
            try {
                jsonObject = new JSONObject(result);
                jsonArray = jsonObject.getJSONArray("ParkInfo");

                while(count < 5){

                    JSONObject jo = jsonArray.getJSONObject(count);
                    places = jo.getString("Places");
                    status = jo.getString("Status");
                    id = jo.getString("id");
                    // ParkInfo parkInfo = new ParkInfo(places,status,id);

                    park_data.add(new String[] { id,status});

                    count ++;

                }
                customView.postInvalidate();

            } catch (JSONException e) {
                e.printStackTrace();
            }

          //  textView.setText(park_data.get(1)[0]);

        }
    }
}

and this is the CustomView class

package com.example.android.a3ozaarken;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.example.android.a3ozaarken.MainActivity;
import com.example.android.a3ozaarken.R;

import java.util.ArrayList;

//import com.example.android.a3ozaarken.MainActivity;
//import com.example.android.a3ozaarken.ParkInfo;


public class CustomView extends View {

    private Paint red_paint,green_paint;
    private Rect rec_frame_red ;
    private Rect rec_frame_green;
    ArrayList<String[]> park_data;


    public CustomView(Context context) {
        super(context);

        init(null);
    }

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

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

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

    private void init (@Nullable AttributeSet set){
        setBackgroundResource(R.drawable.lot2);
        red_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        green_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        rec_frame_green = new Rect();
        rec_frame_red = new Rect();
        park_data = MainActivity.park_data;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        red_paint.setColor(Color.RED);
        red_paint.setStyle(Paint.Style.FILL);

        // rec_frame_red.set(370,225,490,575);
        //canvas.drawRect(rec_frame_red,red_paint);


        green_paint.setColor(Color.GREEN);
        green_paint.setStyle(Paint.Style.FILL);

        // rec_frame_green.set(500,225,610,575);

        //  for (int i=0; i<mainActivity.park_data.size(); i++){
       // if(mainActivity.park_data.get(1).equals(1)){

            if(park_data.get(0)[0].equals(0)){

                rec_frame_green.set(370,225,490,575);
                canvas.drawRect(rec_frame_green,green_paint);
            }

//        }

        //    }

    }
}

and this is the error:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.android.a3ozaarken, PID: 16157
                  java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
                      at java.util.ArrayList.get(ArrayList.java:411)
                      at com.example.android.a3ozaarken.CustomView.onDraw(CustomView.java:84)
                      at android.view.View.draw(View.java:17185)
                      at android.view.View.updateDisplayListIfDirty(View.java:16167)
                      at android.view.View.draw(View.java:16951)
                      at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
                      at android.view.View.updateDisplayListIfDirty(View.java:16162)
                      at android.view.View.draw(View.java:16951)
                      at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
                      at android.view.View.updateDisplayListIfDirty(View.java:16162)
                      at android.view.View.draw(View.java:16951)
                      at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
                      at android.view.View.updateDisplayListIfDirty(View.java:16162)
                      at android.view.View.draw(View.java:16951)
                      at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
                      at android.view.View.updateDisplayListIfDirty(View.java:16162)
                      at android.view.View.draw(View.java:16951)
                      at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
                      at android.view.View.updateDisplayListIfDirty(View.java:16162)
                      at android.view.View.draw(View.java:16951)
                      at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
                      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
                      at android.view.View.draw(View.java:17188)
                      at com.android.internal.policy.DecorView.draw(DecorView.java:753)
                      at android.view.View.updateDisplayListIfDirty(View.java:16167)
                      at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:648)
                      at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:654)
                      at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:762)
                      at android.view.ViewRootImpl.draw(ViewRootImpl.java:2800)
                      at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2608)
                      at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2215)
                      at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
                      at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6337)
                      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
                      at android.view.Choreographer.doCallbacks(Choreographer.java:686)
                      at android.view.Choreographer.doFrame(Choreographer.java:621)
                      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
                      at android.os.Handler.handleCallback(Handler.java:751)
                      at android.os.Handler.dispatchMessage(Handler.java:95)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6119)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Application terminated.
Devil10
  • 1,853
  • 1
  • 18
  • 22
M.Alaa
  • 51
  • 7
  • Do not use static, create a setter method in the customview class and set it. INIT method called one time at the time of view initialization and only reference the empty array. – jitain sharma Apr 21 '18 at 16:08
  • `park_data.get(0)[0].equals(0)` will never actually be true (because inside the list is an array of `String`s, and `0` is an `Integer`), but it will throw exceptions if: 1) `park_data` is empty (*>you are here<*). 2) `park_data.get(0)` is `null`. 3) `park_data.get(0)` is an empty array. Seriously consider defining a proper class for data items, and proper object oriented way of working with it in your view. – M. Prokhorov Apr 21 '18 at 16:53
  • you need to set array to custom view by creating a setter method in CustomView class and than call invalidate – Waqar UlHaq Apr 22 '18 at 05:48
  • Thank you all ! I really appreciate your time ! – M.Alaa Apr 22 '18 at 06:57

3 Answers3

2

You should not assign data at the time of view creation because you do not have any data at that time. So just let the view inflate, call a method of view to set value. Modify your class as following.

public class CustomView extends View {
    private Paint red_paint,green_paint;
    private Rect rec_frame_red ;
    private Rect rec_frame_green;
    ArrayList<String[]> park_data;
    public CustomView(Context context) {
        super(context);
        init(null);
    }

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

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

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

    private void init (@Nullable AttributeSet set){
        setBackgroundResource(R.drawable.lot2);
        red_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        green_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        rec_frame_green = new Rect();
        rec_frame_red = new Rect();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        red_paint.setColor(Color.RED);
        red_paint.setStyle(Paint.Style.FILL);
        green_paint.setColor(Color.GREEN);
        green_paint.setStyle(Paint.Style.FILL);
        if(park_data!=null && park_data.size()>0)
        if(park_data.get(0)[0].equals(0)){
            rec_frame_green.set(370,225,490,575);
            canvas.drawRect(rec_frame_green,green_paint);
        }

    }

    public void setValue(ArrayList<String[]> park_data){
        this.park_data=park_data;
        invalidate();
    }
}

On data load finish call setValue().

customView.setValue(park_data)
ADM
  • 20,406
  • 11
  • 52
  • 83
  • THANK YOUUUUU ! It finally worked! I had to add this line (customview = (CustomView) findViewById(R.id.customview) too in the MainActivity . – M.Alaa Apr 22 '18 at 06:51
  • and since (.equals) method works with Strings , I had to add double quotes around 0 in the if-condition – M.Alaa Apr 22 '18 at 07:07
1

It looks like you’re adding items to park_data but not passing park data to your custom view. When you inflate your layout in your activity, you can find your view by id, cast it to your custom view class, and then set properties on that view. You could add a setter for the CustomView’s ArrayList, and then easily do any other view updating in that setter when the CustomView receives new data.

Zoe
  • 27,060
  • 21
  • 118
  • 148
AndrewPK
  • 6,100
  • 3
  • 32
  • 36
1

Solution you could use is setting a get method for your arraylist:

Mainactivity:

public ArrayList<String[]> getArraylist() {    
    return(park_data);
   }

CustomView class:

ArrayList<String[]> park_data_array;
park_data_array = MainActivity.getArraylist();
Daan Seuntjens
  • 880
  • 1
  • 18
  • 37