java - 使用 ArrayAdapter 返回 ListView 时获取 IndexOutOfBoundsException : Index: 1, Size: 0 (Java Android)

标签 java android listview android-fragments

我有以下自定义适配器(数组适配器),它将我发送到一个 fragment ,以便仅向所选服务添加描述。但是,当我返回到呈现此 listView 的 fragment 时,出现以下错误。

修复服务适配器

public class ReparationServicesAdapter extends ArrayAdapter<Service> {

ViewGroup parent;

public ReparationServicesAdapter(@NonNull Context context, List<Service> repServicesList) {
        super(context, 0, repServicesList);
    }

public ViewGroup getParent() {
         return parent;
    }

@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

    View listItemView = convertView;
    RepServicesViewHolder holder;
    if (listItemView == null) {
        listItemView = LayoutInflater.from(getContext()).inflate(R.layout.reparation_service_item, parent, false);
        holder = new RepServicesViewHolder();
        holder.name = (TextView) listItemView.findViewById(R.id.service_name);
        holder.price = (TextView) listItemView.findViewById(R.id.service_price);
        holder.menuBtn = (ImageButton) listItemView.findViewById(R.id.menu_btn);
        holder.checked = (Switch) listItemView.findViewById(R.id.maintenance_service_switch);
        listItemView.setTag(holder);
    } else {
        holder = (RepServicesViewHolder) listItemView.getTag();
        holder.name.setText("");
        holder.price.setText("");
        holder.menuBtn.setOnClickListener(null);
        holder.checked.setOnCheckedChangeListener(null);
        holder.checked.setChecked(false);
    }

    Log.i("Count", String.valueOf(getCount()));

    final Service currentRepService = getItem(position);

    holder.name.setText(currentRepService.getName() + " - ");

    holder.price.setText("$" + String.valueOf(currentRepService.getPrice()));

    this.parent = parent;

    holder.menuBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ((DashboardActivity) getContext()).getAppointmentHelper().getRepServices().add(currentRepService);
            ((DashboardActivity) getContext()).setWorkService(new Service(
                    currentRepService.getCode(),
                    currentRepService.getName(),
                    currentRepService.getPrice()));
            ((DashboardActivity) getContext()).setView("A_REPARATION_SERVICES_DESCRIPTION");
        }
    });

    final TextView repServicesAddedLabel = (TextView) ((ViewGroup) parent.getParent()).findViewById(R.id.bottom_available_services_label);
    final TextView repServicesAddedPrice = (TextView) ((ViewGroup) parent.getParent()).findViewById(R.id.bottom_available_services_price);

    holder.checked.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (!isChecked) {
                int size = ((DashboardActivity) getContext()).getAppointmentHelper().getRepServices().size();
                for (int i = 0; i < size; i++) {
                    if (((Service) ((DashboardActivity) getContext()).getAppointmentHelper().getRepServices().get(i)).getCode().equals(currentRepService.getCode())) {
                        ((DashboardActivity) getContext()).getAppointmentHelper().getRepServices().remove(i);
                        size--;
                    }
                }

                double price = 0;

                for (int i = 0; i < size; i++) {
                    price += ((Service) ((DashboardActivity) getContext()).getAppointmentHelper().getRepServices().get(i)).getPrice();
                }
                ((DashboardActivity) getContext()).getAppointmentHelper().setRepServicesPrice(price);
                repServicesAddedPrice.setText("$" + String.valueOf(price));
                if (size > 1) {
                    repServicesAddedLabel.setText(size + " servicios seleccionados - ");
                } else {
                    repServicesAddedLabel.setText(size + " servicio seleccionado - ");
                }

            }
            else {
                ((DashboardActivity) getContext()).getAppointmentHelper().getRepServices().add(currentRepService);
                ((DashboardActivity) getContext()).setWorkService(new Service(
                        currentRepService.getCode(),
                        currentRepService.getName(),
                        currentRepService.getPrice()));
                ((DashboardActivity) getContext()).setView("A_REPARATION_SERVICES_DESCRIPTION");
            }
        }
    });

    int size = ((DashboardActivity) getContext()).getAppointmentHelper().getRepServices().size();

    Log.i("RPSize", String.valueOf(((DashboardActivity) getContext()).getAppointmentHelper().getRepServices().size()));

    for (int i = 0; i < size; i++) {
        Service serv = ((Service) ((DashboardActivity) getContext()).getAppointmentHelper().getRepServices().get(i));
        if (serv.getCode().equals(currentRepService.getCode())) {
            Log.i("For", String.valueOf(i));
            Log.i("Data Service", String.valueOf(currentRepService.getName()));
            holder.checked.setChecked(true);
        }
    }

    return listItemView;
}

private static class RepServicesViewHolder {
    public TextView name;
    public TextView price;
    public ImageButton menuBtn;
    public Switch checked;
}

当我在服务描述 fragment 上填写描述,然后 ListView 尝试重新渲染时,我收到此错误,它表明 ListView 显然没有 size() 。

这是创建列表的原始 fragment :

public class ReparationServicesFragment extends Fragment implements LoaderManager.LoaderCallbacks<JSONObject> {

private static final int REPARATION_SERVICES_LIST_LOADER_ID = 0;

@BindView(R.id.reparation_services_toolbar)
Toolbar reparationServicesToolbar;
@BindView(R.id.reparation_services_list)
ListView reparationServicesList;
@BindView(R.id.bottom_available_services_label)
TextView bottomAvailableServicesLabel;
@BindView(R.id.bottom_available_services_price)
TextView bottomAvailableServicesPrice;
Unbinder unbinder;

private ProgressDialog pDialog;
List<Service> services;
private ReparationServicesAdapter adapter;
private JSONObject appointmentData;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_reparation_services, container, false);

    unbinder = ButterKnife.bind(this, rootView);

    services = new ArrayList<>();
    adapter = new ReparationServicesAdapter(this.getContext(), new ArrayList<Service>());
    reparationServicesList.setAdapter(adapter);

    reparationServicesToolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            UiUtils.hideKeyboard(getContext());
            ((DashboardActivity) getActivity()).setView("A_SET");

        }
    });

    Log.i("RepServices", "Am i here?");
    Log.i("AppointmentHelper !!", String.valueOf(((DashboardActivity) getContext()).getAppointmentHelper().getRepServices().size()));

    /*for (int i = 0; i < ((DashboardActivity) getContext()).getAppointmentHelper().getRepServices().size(); i++) {
        Log.i("RepServices",((Service) ((DashboardActivity) getContext()).getAppointmentHelper().getRepServices().get(i)).getCode());
        Log.i("RepServices",((Service) ((DashboardActivity) getContext()).getAppointmentHelper().getRepServices().get(i)).getDescription());
    }*/

    appointmentData = new JSONObject();
    try {
        JSONArray workTypes = ((DashboardActivity) getActivity()).getAppointmentHelper().getBranch().getWorkTypes();

        for (int i = 0; i < workTypes.length(); i++) {
            if (workTypes.getJSONObject(i).get("tipo").toString().trim().equals("REPARACION")) {
                appointmentData.put("branchId", ((DashboardActivity) getActivity()).getAppointmentHelper().getBranch().getId());
                appointmentData.put("svcType", "REPARACION");
                appointmentData.put("vin", ((DashboardActivity) getActivity()).getVehicle().getVin());
                getLoaderManager().restartLoader(REPARATION_SERVICES_LIST_LOADER_ID, null, this);
            }
        }

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

    return rootView;
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    unbinder.unbind();
}

@Override
public Loader<JSONObject> onCreateLoader(int id, Bundle args) {
    pDialog = new ProgressDialog(getContext());
    pDialog.setMessage("Procesando...");
    pDialog.setCancelable(false);
    pDialog.show();
    Log.i("CreateLoader", "Cargando reportes de reparación");
    return new RepWorkServiceLoader(getContext());
}

@Override
public void onLoadFinished(Loader<JSONObject> loader, JSONObject data) {
    Log.i("JONN",  data.toString());

    if (pDialog.isShowing())
        pDialog.dismiss();

    if (data != null) {
        try {
            if (!data.get("data").toString().equals("null")) {
                JSONArray values = new JSONArray(data.get("data").toString());
                adapter.clear();
                if (values.length() > 0) {
                    for (int i = 0; i < values.length(); i++) {
                        JSONObject properties = values.getJSONObject(i);
                        services.add(new Service(
                                properties.getString("opcode").trim(),
                                properties.getString("nombre").trim(),
                                properties.getDouble("precio")
                        ));
                    }

                    Log.i("Servicios", String.valueOf(services.size()));

                    adapter.addAll(services);
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

@Override
public void onLoaderReset(Loader<JSONObject> loader) {
    adapter.clear();
}

我明白了

java.lang.IndexOutOfBoundsException: Index: 1, Size: 0 at java.util.ArrayList.get(ArrayList.java:411) at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:349) at com.ccstudio.android.petroautos.ui.adapters.ReparationServicesAdapter.getView(ReparationServicesAdapter.java:69

错误似乎在这里:

final Service currentRepService = getItem(position);

当我返回 fragment (来自服务描述 fragment )时,适配器中 getItem 的索引为 1,大小为 0。

感谢任何帮助。

-- 编辑-- 当我单击列表中项目上的开关时,我会转到以下 fragment :

public class ServiceDescriptionFragment extends Fragment {

@BindView(R.id.reparation_services_toolbar)
Toolbar reparationServicesToolbar;
@BindView(R.id.service_description)
EditText serviceDescription;
ArrayList services;
Unbinder unbinder;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_reparation_service_description, container, false);

    unbinder = ButterKnife.bind(this, rootView);

    services = ((DashboardActivity) getContext()).getAppointmentHelper().getRepServices();

    reparationServicesToolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            UiUtils.hideKeyboard(getContext());
            ((DashboardActivity) getActivity()).setView("A_REPARATION_SERVICES");

        }
    });
    return rootView;
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    unbinder.unbind();
}

@OnClick(R.id.service_description_btn)
public void onViewClicked() {
    for (int i = 0; i < services.size(); i++) {
        if (((Service) services.get(i)).getCode().equals(((DashboardActivity) getContext()).getWorkService().getCode().toString())) {
            ((Service) services.get(i)).setDescription(serviceDescription.getText().toString());
            ((DashboardActivity) getContext()).getAppointmentHelper().setRepServices(services);
        }
    }
    ((DashboardActivity) getActivity()).setView("A_REPARATION_SERVICES");
}

}

当我返回带有列表的修复服务 View 时,它给出了错误。

最佳答案

你为什么不这样做:

public class ReparationServicesAdapter extends ArrayAdapter<Service> {

    List<Service> serviceList; // store here for access later

    public ReparationServicesAdapter(@NonNull Context context, List<Service> repServicesList) {
        super(context, 0, repServicesList);
        serviceList = repServicesList
    }
}

并访问如下数据:

// instead of this
final Service currentRepService = getItem(position);

// some more code
final Service currentRepService = serviceList.get(position);

我认为这不会导致内存开销,因为 java 中的每个非原始数据类型都被引用。

关于java - 使用 ArrayAdapter 返回 ListView 时获取 IndexOutOfBoundsException : Index: 1, Size: 0 (Java Android),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53273767/

相关文章:

Java:Apache commons邮件立即进入hotmail垃圾文件夹

java - 多线程 "unpredictable"行为

android - React Native Expo Android WebView

java - Android - 自定义 ListView Viewholder

android - 刷新 ListView 中的复选框状态

Java递归问题

Java Discord Bot - 获取角色成员?

java - 使用动态类名以新 Intent 启动 Activity

android - 在android中以编程方式设置TextView TextAppearance

asp.net ListView,在页脚中显示计算摘要?