java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
Приложение вылетает. Не могу полностью понять в чем проблема. В logcat пишет:
java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
at java.util.ArrayList.get(ArrayList.java:437)
at ru.bladegames.rustate.gui.dialogs.Dialog.loadTabList(Dialog.java:152)
код:
private void loadTabList(String content) {
String[] strings = content.split("\n");
for (int i = 0; i < strings.length; i++) {
if (this.mCurrentDialogTypeId == 5 && i == 0) {
String[] headers = strings[i].split("\t");
for (int j = 0; j < headers.length; j++) {
this.mHeadersList.get(j).setText(Utils.transfromColors(headers[j]));
this.mHeadersList.get(j).setVisibility(View.VISIBLE);
}
} else {
this.mRowsList.add(strings[i]);
}
}
}
полный код:
public class Dialog {
private static final int DIALOG_LEFT_BTN_ID = 1;
private static final int DIALOG_RIGHT_BTN_ID = 0;
private static final int DIALOG_STYLE_INPUT = 1;
private static final int DIALOG_STYLE_LIST = 2;
private static final int DIALOG_STYLE_MSGBOX = 0;
private static final int DIALOG_STYLE_PASSWORD = 3;
private static final int DIALOG_STYLE_TABLIST = 4;
private static final int DIALOG_STYLE_TABLIST_HEADER = 5;
private final TextView mCaption;
private final TextView mContent;
private int mCurrentDialogId = -1;
private int mCurrentDialogTypeId = -1;
private String mCurrentInputText = "";
private int mCurrentListItem = -1;
private final CustomRecyclerView mCustomRecyclerView;
private final ArrayList<TextView> mHeadersList;
private final CustomEditText mInput;
private final ConstraintLayout mInputLayout;
private final ConstraintLayout mLeftBtn;
private final ConstraintLayout mListLayout;
private final ConstraintLayout mMainLayout;
private final ScrollView mMsgBoxLayout;
private final ConstraintLayout mRightBtn;
private ArrayList<String> mRowsList;
public Dialog(Activity activity) {
this.mMainLayout = activity.findViewById(R.id.rustate_dialog_main);
this.mCaption = (TextView) activity.findViewById(R.id.rustate_dialog_caption);
this.mContent = (TextView) activity.findViewById(R.id.rustate_dialog_text);
ConstraintLayout findViewById1 = activity.findViewById(R.id.sd_button_positive);
this.mLeftBtn = findViewById1;
ConstraintLayout findViewById2 = activity.findViewById(R.id.sd_button_negative);
this.mRightBtn = findViewById2;
this.mInputLayout = activity.findViewById(R.id.rustate_dialog_input_layout);
this.mListLayout = activity.findViewById(R.id.rustate_dialog_list_layout);
this.mMsgBoxLayout = (ScrollView) activity.findViewById(R.id.rustate_dialog_text_layout);
this.mInput = (CustomEditText) activity.findViewById(R.id.rustate_dialog_input);
this.mCustomRecyclerView = (CustomRecyclerView) activity.findViewById(R.id.rustate_dialog_list_recycler);
findViewById1.setOnClickListener(view -> sendDialogResponse(1));
findViewById2.setOnClickListener(view -> sendDialogResponse(0));
this.mRowsList = new ArrayList<>();
this.mHeadersList = new ArrayList<>();
ConstraintLayout mHeadersLayout = activity.findViewById(R.id.rustate_dialog_tablist_row);
for (int i = 0; i < mHeadersLayout.getChildCount(); i++) {
this.mHeadersList.add((TextView) mHeadersLayout.getChildAt(i));
}
this.mInput.setOnEditorActionListener((textView, i, keyEvent) -> {
Editable editableText;
if ((i != 6 && i != 5) || (editableText = this.mInput.getText()) == null) {
return false;
}
this.mCurrentInputText = editableText.toString();
return false;
});
this.mInput.setOnClickListener(view ->
{
this.mInput.requestFocus();
((InputMethodManager) NvEventQueueActivity.getInstance().getSystemService("input_method")).showSoftInput(this.mInput, 1);
});
Utils.HideLayout(this.mMainLayout, false);
}
public void show(int dialogId, int dialogTypeId, String caption, String content, String leftBtnText, String rightBtnText) {
clearDialogData();
this.mCurrentDialogId = dialogId;
this.mCurrentDialogTypeId = dialogTypeId;
if (dialogTypeId == 0) {
this.mInputLayout.setVisibility(View.GONE);
this.mListLayout.setVisibility(View.GONE);
this.mMsgBoxLayout.setVisibility(View.VISIBLE);
}
else if(dialogTypeId == 1 || dialogTypeId == 3)
{
this.mInputLayout.setVisibility(View.VISIBLE); // выполняется инпут
this.mMsgBoxLayout.setVisibility(View.VISIBLE);
this.mListLayout.setVisibility(View.GONE);
}
else
{
this.mInputLayout.setVisibility(View.GONE);
this.mMsgBoxLayout.setVisibility(View.GONE); // LIST, TABLIST, TABLIST_HEADER
this.mListLayout.setVisibility(View.VISIBLE);
loadTabList(content);
ArrayList<String> fixFieldsForDialog = Utils.fixFieldsForDialog(this.mRowsList);
this.mRowsList = fixFieldsForDialog;
DialogAdapter adapter = new DialogAdapter(fixFieldsForDialog, this.mHeadersList);
adapter.setOnClickListener((i, str) -> { this.mCurrentListItem = i;
this.mCurrentInputText = str; });
adapter.setOnDoubleClickListener(() -> sendDialogResponse(1));
this.mCustomRecyclerView.setLayoutManager(new LinearLayoutManager((Context) NvEventQueueActivity.getInstance()));
this.mCustomRecyclerView.setAdapter(adapter);
if (dialogTypeId != 2) {
CustomRecyclerView customRecyclerView = this.mCustomRecyclerView;
adapter.getClass();
customRecyclerView.post(() -> adapter.updateSizes());
}
}
this.mCaption.setText(Utils.transfromColors(caption));
this.mContent.setText(Utils.transfromColors(content));
((TextView) this.mLeftBtn.getChildAt(0)).setText(Utils.transfromColors(leftBtnText));
((TextView) this.mRightBtn.getChildAt(0)).setText(Utils.transfromColors(rightBtnText));
if (rightBtnText.equals("")) { this.mRightBtn.setVisibility(View.GONE); }
else { this.mRightBtn.setVisibility(View.VISIBLE); }
Utils.ShowLayout(this.mMainLayout, true);
}
public void hideWithoutReset() { Utils.HideLayout(this.mMainLayout, false); }
public void showWithOldContent() { Utils.ShowLayout(this.mMainLayout, false); }
public void sendDialogResponse(int btnId) {
if (!this.mCurrentInputText.equals(this.mInput.getText().toString())) { this.mCurrentInputText = this.mInput.getText().toString(); }
((InputMethodManager) NvEventQueueActivity.getInstance().getSystemService("input_method")).hideSoftInputFromWindow(this.mInput.getWindowToken(), 0);
byte[] str = null;
try { str = this.mCurrentInputText.getBytes("windows-1251"); }
catch(UnsupportedEncodingException e) { }
NvEventQueueActivity.getInstance().sendDialogResponse(btnId, this.mCurrentDialogId, this.mCurrentListItem, str);
Utils.HideLayout(this.mMainLayout, true);
}
private void loadTabList(String content) {
String[] strings = content.split("\n");
for (int i = 0; i < strings.length; i++) {
if (this.mCurrentDialogTypeId == 5 && i == 0) {
String[] headers = strings[i].split("\t");
for (int j = 0; j < headers.length; j++) {
this.mHeadersList.get(j).setText(Utils.transfromColors(headers[j]));
this.mHeadersList.get(j).setVisibility(View.VISIBLE);
}
} else {
this.mRowsList.add(strings[i]);
}
}
}
private void clearDialogData() {
this.mInput.setText("");
this.mCurrentDialogId = -1;
this.mCurrentDialogTypeId = -1;
this.mCurrentListItem = -1;
this.mRowsList.clear();
for (int i = 0; i < this.mHeadersList.size(); i++) {
this.mHeadersList.get(i).setVisibility(View.GONE);
}
}
public void onHeightChanged(int height) {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) this.mMainLayout.getLayoutParams();
params.setMargins(0, 0, 0, height);
this.mMainLayout.setLayoutParams(params);
}
}
Также добавляю DialogAdapter.java, думаю он пригодится:
public class DialogAdapter extends RecyclerView.Adapter {
private int mCurrentSelectedPosition = 0;
private View mCurrentSelectedView;
private final ArrayList<TextView> mFieldHeaders;
private final ArrayList<String> mFieldTexts;
private final ArrayList<ArrayList<TextView>> mFields;
private OnClickListener mOnClickListener;
private OnDoubleClickListener mOnDoubleClickListener;
public interface OnClickListener {
void onClick(int i, String str);
}
public interface OnDoubleClickListener {
void onDoubleClick();
}
public DialogAdapter(ArrayList<String> fields, ArrayList<TextView> fieldHeaders) {
this.mFieldTexts = fields;
this.mFieldHeaders = fieldHeaders;
this.mFields = new ArrayList<>();
}
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.rustate_dialog_item, parent, false));
}
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
onBindViewHolder((ViewHolder) holder, position);
}
public void onBindViewHolder(ViewHolder holder, int position) {
String[] headers = this.mFieldTexts.get(position).split("\t");
ArrayList<TextView> fields = new ArrayList<>();
for (int i = 0; i < headers.length; i++) {
TextView field = holder.mFields.get(i);
field.setText(Utils.transfromColors(headers[i].replace("\\t", "")));
field.setVisibility(View.VISIBLE);
fields.add(field);
}
this.mFields.add(fields);
if (this.mCurrentSelectedPosition == position) {
ImageView imageView = holder.mFieldBg;
this.mCurrentSelectedView = imageView;
imageView.setVisibility(View.VISIBLE);
this.mOnClickListener.onClick(position, holder.mFields.get(0).getText().toString());
} else {
holder.mFieldBg.setVisibility(View.GONE);
}
holder.getView().setOnClickListener(view -> {
if (this.mCurrentSelectedPosition != holder.getAdapterPosition()) {
View view2 = this.mCurrentSelectedView;
if (view2 != null) {
view2.setVisibility(View.GONE);
}
this.mCurrentSelectedPosition = holder.getAdapterPosition();
this.mCurrentSelectedView = holder.mFieldBg;
holder.mFieldBg.setVisibility(View.VISIBLE);
this.mOnClickListener.onClick(holder.getAdapterPosition(), holder.mFields.get(0).getText().toString());
return;
}
OnDoubleClickListener onDoubleClickListener = this.mOnDoubleClickListener;
if (onDoubleClickListener != null) {
onDoubleClickListener.onDoubleClick();
}
});
}
public void updateSizes() {
int[] max = new int[4];
for (int i = 0; i < this.mFields.size(); i++) {
for (int j = 0; j < this.mFields.get(i).size(); j++) {
int width = this.mFields.get(i).get(j).getWidth();
if (max[j] < width) {
max[j] = width;
}
}
}
for (int i2 = 0; i2 < max.length; i2++) {
int headerWidth = this.mFieldHeaders.get(i2).getWidth();
Log.i("DIALOG", max[i2] + "\t" + ((Object) this.mFieldHeaders.get(i2).getText()) + MaskedEditText.SPACE + headerWidth);
if (max[i2] < headerWidth) {
max[i2] = headerWidth;
}
}
for (int i3 = 0; i3 < this.mFields.size(); i3++) {
for (int j2 = 0; j2 < this.mFields.get(i3).size(); j2++) {
this.mFields.get(i3).get(j2).setWidth(max[j2]);
}
}
for (int i4 = 0; i4 < this.mFieldHeaders.size(); i4++) {
this.mFieldHeaders.get(i4).setWidth(max[i4]);
}
}
public void setOnClickListener(OnClickListener onClickListener) {
this.mOnClickListener = onClickListener;
}
public void setOnDoubleClickListener(OnDoubleClickListener onDoubleClickListener) {
this.mOnDoubleClickListener = onDoubleClickListener;
}
public ArrayList<ArrayList<TextView>> getFields() {
return this.mFields;
}
public int getItemCount() {
return this.mFieldTexts.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView mFieldBg;
public ArrayList<TextView> mFields = new ArrayList<>();
private final View mView;
public ViewHolder(View itemView) {
super(itemView);
this.mView = itemView;
this.mFieldBg = (ImageView) itemView.findViewById(R.id.rustate_dialog_item_bg);
ConstraintLayout field = itemView.findViewById(R.id.rustate_dialog_item_main);
for (int i = 1; i < field.getChildCount(); i++) {
this.mFields.add((TextView) field.getChildAt(i));
}
}
public View getView() {
return this.mView;
}
}
}
Ответы (2 шт):
Index: 4, Size: 4
Это означает, в массиве 4 элемента. Индексация элементов в массивах начинается с нуля (0). Соответственно, индекс Вашего первого элемента "0", а индекс последного четвертого элемента "3".
length хранит в себе количество элементов. (В вашем случае 4 элемента)
Когда вы просите элемента с 4им индексом (его там нет, у четвертого элекмента индекс: 3) java выбрасывает исключение.
РЕШЕНИЕ: Сделайте "length-1" в цикле!
Причину нашел! Проблема была в mHeadersLayout, тоесть там в самом лайоте создавалось 4 строки, когда в моем диалоге должно быть 5! Добавил строку, проблема решена! 