【问题标题】:Passing ArrayList from MainActivity class to CustomView class in Android [duplicate]将ArrayList从MainActivity类传递给Android中的CustomView类[重复]
【发布时间】:2018-04-21 16:00:16
【问题描述】:

我们正在尝试从Main Activity 传递一个ArrayList 以在CustomView class 中使用它。两个类属于同一个活动。根据这个数组,一些矩形将被绘制在图像上,但是数组通过的总是空的。 我们是 Android 新手,我们检查了类似的问题,但没有任何解决办法。

这是 MainActivity.java

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]);

        }
    }
}

这是 CustomView

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);
            }

//        }

        //    }

    }
}

这是错误

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.

【问题讨论】:

  • 不要使用static,在customview类中创建一个setter方法并设置。 INIT 方法在视图初始化时调用一次,并且只引用空数组。
  • park_data.get(0)[0].equals(0) 永远不会真正为真(因为列表内部是Strings 的数组,而0Integer),但在以下情况下会抛出异常:1) park_data 为空(>你在这里)。 2) park_data.get(0)null。 3) park_data.get(0) 是一个空数组。认真考虑为数据项定义一个适当的类,并在您的视图中以适当的面向对象的方式使用它。
  • 您需要通过在 CustomView 类中创建一个 setter 方法将数组设置为自定义视图,然后调用 invalidate
  • 谢谢大家!非常感谢您的宝贵时间!

标签: java android arraylist android-custom-view


【解决方案1】:

您不应在创建视图时分配数据,因为那时您没有任何数据。 所以只是让视图膨胀,调用视图的方法来设置值。修改你的类如下。

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();
    }
}

在数据加载完成时调用setValue()

customView.setValue(park_data)

【讨论】:

  • 谢谢你!它终于奏效了!我必须在 MainActivity 中添加这一行 (customview = (CustomView) findViewById(R.id.customview) 。
  • 并且由于 (.equals) 方法适用于 Strings ,我必须在 if 条件中在 0 周围添加双引号
【解决方案2】:

您可以使用的解决方案是为您的 arraylist 设置一个 get 方法:

主要活动:

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

CustomView 类:

ArrayList<String[]> park_data_array;
park_data_array = MainActivity.getArraylist();

【讨论】:

    【解决方案3】:

    看起来您正在向 park_data 添加项目,但没有将公园数据传递到您的自定义视图。当您在活动中扩展您的布局时,您可以通过 id 找到您的视图,将其转换为您的自定义视图类,然后在该视图上设置属性。您可以为 CustomView 的 ArrayList 添加一个 setter,然后在 CustomView 接收到新数据时轻松地在该 setter 中更新任何其他视图。

    【讨论】:

      猜你喜欢
      • 2019-04-20
      • 1970-01-01
      • 2021-02-10
      • 1970-01-01
      • 1970-01-01
      • 2021-05-06
      • 1970-01-01
      • 2014-11-17
      • 2020-06-05
      相关资源
      最近更新 更多