在单击行时获取IndexOutOfBoundsException:索引:1,大小:1

时间:2018-09-15 20:32:34

标签: java android sqlite

我过去曾做过这项工作,但是现在我对代码进行了一些更改,现在,每当我从ListView删除一行并单击其余的一行时,我都会得到{{1} }。

这似乎仅在剩余一行时才发生。如果剩余一行以上,则不会出现此错误。

enter image description here 上图显示,当剩余多于一行时,不会发生错误。

我不确定为什么会发生这种情况,因为用于选择和删除行的代码都没有改变。

我检查了该网站上的其他帖子,但似乎与我所遇到的都不相似。

Android IndexOutOfBoundsException: Index: 1, Size: 1

OutOfBoundException index:1, size:1

java jtable removeRow : java.lang.IndexOutOfBoundsException: Index: 1, Size: 1

我已经在下面发布了我的代码。

Logcat:

IndexOutOfBoundsException: Index: 1, Size: 1

用于在列表视图中选择一行的代码:

java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at java.util.ArrayList.get(ArrayList.java:411)
        at ca.rvogl.tpbcui.views.LeagueAdapter$2.onClick(LeagueAdapter.java:116)
        at android.view.View.performClick(View.java:5637)
        at android.view.View$PerformClick.run(View.java:22429)
        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)

删除行的代码:

@Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        League league = leaguesList.get(position);
        int id = league.getId();
        String leagueId = String.valueOf(id);
        holder.id.setText(leagueId);
        holder.name.setText(league.getName());
        holder.basescore.setText(league.getBaseScore());
        holder.basescorepercentage.setText(league.getBaseScorePercentage());
        if (league.getAverage() != "") {
            holder.leagueAverage.setText(String.format("League Avg: %s", league.getAverage()));
        } else {
            holder.leagueAverage.setText(String.format("League Avg: %s", "0"));
        }
        //Formatting And Displaying Timestamp
        holder.timestamp.setText(formatDate(league.getTimestamp()));
        holder.buttonViewOption.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //creating a popup menu
                PopupMenu popup = new PopupMenu(context, holder.buttonViewOption);
                //inflating menu from xml resource
                popup.inflate(R.menu.league_options_menu);
                //adding click listener
                popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        switch (item.getItemId()) {
                            case R.id.profile:
                                ((MainActivity) context).showLeagueDialog(true, leaguesList.get(position), position);
                                break;
                            case R.id.delete:
                                ((MainActivity) context).deleteLeague(position);
                                break;
                        }
                        return false;
                    }
                });
                //displaying the popup
                popup.show();

            }
        });
        holder.name.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int leagueId = leaguesList.get(position).getId();
                Intent myIntent = new Intent(context, BowlerActivity.class);
                myIntent.putExtra("leagueId", leagueId);
                context.startActivity(myIntent);
            }
        });
    }

此行//Deleting League From SQLite Database And Removing The League Item From The List By Its Position public void deleteLeague(int position) { Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "Series will be deleted.", Snackbar.LENGTH_LONG) .setActionTextColor(Color.YELLOW) .setAction("OK", new View.OnClickListener() { @Override public void onClick(View v) { //Deleting The League From The Database db.deleteLeague(leaguesList.get(position)); //Removing League From The List leaguesList.remove(position); mAdapter.notifyItemRemoved(position); toggleEmptyLeagues(); } }); snackbar.show(); } 似乎发生了错误

对于解决此错误的任何帮助,将不胜感激。

BowlerActivity.java

int leagueId = leaguesList.get(position).getId();

这是它抱怨的那一行。在将onClick()移到适配器之前,此方法非常有效。

public class BowlerActivity extends AppCompatActivity {

    private BowlerAdapter mAdapter;
    private final List<Bowler> bowlersList = new ArrayList<>();
    private TextView noBowlersView;

    private DatabaseHelper db;

    private TextView leagueId;
    private String savedLeagueId;

    private TextView seriesleagueId;
    private String seriesLeagueId;
    private TextView bowlerAverage;
    private TextView bowlerHandicap;
    private String savedBowlerAverage;


    private static final String PREFS_NAME = "prefs";
    private static final String PREF_BLUE_THEME = "blue_theme";
    private static final String PREF_GREEN_THEME = "green_theme";
    private static final String PREF_ORANGE_THEME = "purple_theme";
    private static final String PREF_RED_THEME = "red_theme";
    private static final String PREF_YELLOW_THEME = "yellow_theme";


    @Override protected void onResume() {
        super.onResume();
        db = new DatabaseHelper( this );
        mAdapter.notifyDatasetChanged( db.getAllBowlers( savedLeagueId ) );
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        //Use Chosen Theme
        SharedPreferences preferences = getSharedPreferences( PREFS_NAME, MODE_PRIVATE );
        boolean useBlueTheme = preferences.getBoolean( PREF_BLUE_THEME, false );
        if (useBlueTheme) {
            setTheme( R.style.AppTheme_Blue_NoActionBar );
        }
        boolean useGreenTheme = preferences.getBoolean( PREF_GREEN_THEME, false );
        if (useGreenTheme) {
            setTheme( R.style.AppTheme_Green_NoActionBar );
        }
        boolean useOrangeTheme = preferences.getBoolean( PREF_ORANGE_THEME, false );
        if (useOrangeTheme) {
            setTheme( R.style.AppTheme_Orange_NoActionBar );
        }
        boolean useRedTheme = preferences.getBoolean( PREF_RED_THEME, false );
        if (useRedTheme) {
            setTheme( R.style.AppTheme_Red_NoActionBar );
        }
        boolean useYellowTheme = preferences.getBoolean( PREF_YELLOW_THEME, false );
        if (useYellowTheme) {
            setTheme( R.style.AppTheme_Yellow_NoActionBar );
        }

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bowler);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        Objects.requireNonNull( getSupportActionBar() ).setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);

        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(getApplicationContext(),MainActivity.class));
                finish();
                overridePendingTransition(0, 0);

            }
        });

        savedLeagueId = String.valueOf(getIntent().getIntExtra("leagueId",2));
        leagueId = findViewById(R.id.tvLeagueId);
        bowlerAverage = (TextView) findViewById(R.id.tvBowlerAverage);

                bowlerHandicap = (TextView) findViewById(R.id.tvBowlerHandicap);

        CoordinatorLayout coordinatorLayout = findViewById( R.id.coordinator_layout );
        RecyclerView recyclerView = findViewById( R.id.recycler_view );
        noBowlersView = findViewById(R.id.empty_bowlers_view);

        db = new DatabaseHelper(this);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.add_bowler_fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showBowlerDialog(false, null, -1);
            }
        });

        mAdapter = new BowlerAdapter(this, bowlersList);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        //recyclerView.addItemDecoration(new MyDividerItemDecoration(this, LinearLayoutManager.VERTICAL, 16));
        recyclerView.setAdapter(mAdapter);

        toggleEmptyBowlers();
    }

    //Inserting New Bowler In The Database And Refreshing The List
    private void createBowler(String leagueId, String bowlerName) {
        String bowlerAverage = "0";
        //Inserting Bowler In The Database And Getting Newly Inserted Bowler Id
        long id = db.insertBowler(leagueId, bowlerName, bowlerAverage);

        //Get The Newly Inserted Bowler From The Database
        Bowler n = db.getBowler(leagueId);

        if (n != null) {
            //Adding New Bowler To The Array List At Position 0
            bowlersList.add( 0, n );
            //Refreshing The List
            mAdapter.notifyDatasetChanged(db.getAllBowlers(savedLeagueId));
            //mAdapter.notifyDataSetChanged();
            toggleEmptyBowlers();
        }
    }

    //Updating Bowler In The Database And Updating The Item In The List By Its Position
    private void updateBowler(String bowlerName, int position) {
        Bowler n = bowlersList.get(position);

        //Updating Bowler Text
        n.setLeagueId(savedLeagueId);
        n.setName(bowlerName);

        //Updating The Bowler In The Database
        db.updateBowler(n);

        //Refreshing The List
        bowlersList.set(position, n);
        mAdapter.notifyItemChanged(position);

        toggleEmptyBowlers();
    }

    //Deleting Bowler From SQLite Database And Removing The Bowler Item From The List By Its Position
    public void deleteBowler(int position) {

        Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "Series will be deleted.", Snackbar.LENGTH_LONG)
                .setActionTextColor(Color.YELLOW)
                .setAction("OK", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //Deleting The Bowler From The Database
                        db.deleteBowler(bowlersList.get(position));
                        //Removing The Bowler From The List
                        bowlersList.remove(position);
                        mAdapter.notifyItemRemoved(position);
                        db.leagueAverageScore(savedLeagueId);
                        toggleEmptyBowlers();
                    }
                });
        snackbar.show();
    }


    //Opens Dialog With Edit/Delete Options

    private void showActionsDialog(final int position) {
        LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getApplicationContext());
        View view = View.inflate(this, R.layout.dialog_options_1, null);

        final AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(new ContextThemeWrapper(BowlerActivity.this, R.style.AppTheme));
        alertDialogBuilderUserInput.setView(view);
        alertDialogBuilderUserInput.setCancelable(true);

        final AlertDialog alertDialog = alertDialogBuilderUserInput.create();

        //Cancel
        final ImageButton cancel_btn = (ImageButton) view.findViewById(R.id.cancel);
        cancel_btn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                alertDialog.cancel();
            }
        });

        //Edit
        ImageButton edit_btn = (ImageButton) view.findViewById(R.id.edit);
        edit_btn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                showBowlerDialog(true, bowlersList.get(position), position);
                alertDialog.dismiss();
            }
        });

        ImageButton delete_btn = (ImageButton) view.findViewById(R.id.delete);
        delete_btn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "Bowler will be deleted.", Snackbar.LENGTH_LONG)
                        .setAction("OK", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                deleteBowler(position);
                            }
                        });

                snackbar.show();
                alertDialog.dismiss();
            }
        });
        Window window = alertDialog.getWindow();
        window.setGravity(Gravity.TOP);
        alertDialog.show();
    }

    //Show Alert Dialog With EditText Options to Enter/Edit A League
    //When shouldUpdate = true, It Will Automatically Display Old Bowler Name And Change The Button Text To UPDATE
    public void showBowlerDialog(final boolean shouldUpdate, final Bowler bowler, final int position) {
        LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getApplicationContext());
        final View view = View.inflate(this, R.layout.dialog_bowler, null);
        AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(new ContextThemeWrapper(BowlerActivity.this, R.style.AppTheme));
        alertDialogBuilderUserInput.setView(view);
        alertDialogBuilderUserInput.setCancelable(true);
        leagueId.setText(savedLeagueId);
        final EditText inputBowlerName = view.findViewById(R.id.etBowlerNameInput);
        TextView dialogTitle = view.findViewById(R.id.dialog_title);
        dialogTitle.setText(!shouldUpdate ? getString(R.string.lbl_new_bowler_title) : getString(R.string.lbl_edit_bowler_title));

        if (shouldUpdate && bowler != null) {
            leagueId.setText(bowler.getLeagueId());
            inputBowlerName.setText(bowler.getName());

        }
        alertDialogBuilderUserInput
                .setCancelable(false)
                .setPositiveButton(shouldUpdate ? "update" : "save", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialogBox, int id) {

                    }
                })
                .setNegativeButton("cancel",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialogBox, int id) {
                                dialogBox.cancel();
                            }
                        });
        ImageView bowlerName = (ImageView) view.findViewById (R.id.ivBowlerName);
        bowlerName.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {

                AlertDialog.Builder bowlerName = new AlertDialog.Builder(BowlerActivity.this);
                bowlerName.setMessage("Enter the name of the bowler to hold your new scores.");
                bowlerName.setCancelable(true);
                bowlerName.create();
                bowlerName.show();
            }
        });

        final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
        alertDialog.show();

        alertDialog.getButton( AlertDialog.BUTTON_POSITIVE).setOnClickListener( new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //Show Toast Message When No Text Is Entered
                if (TextUtils.isEmpty(inputBowlerName.getText().toString())) {
                    Snackbar.make( view, "Enter Bowler Name", Snackbar.LENGTH_LONG )
                            .setAction( "Action", null ).show();
                    return;
                } else {
                    alertDialog.dismiss();
                }

                //Check If User Is Updating Bowler
                if (shouldUpdate && bowler != null) {

                    //Updating Bowler By Its Id
                    updateBowler(inputBowlerName.getText().toString(), position);

                } else {
                    //Creating New Bowler
                    createBowler(leagueId.getText().toString(), inputBowlerName.getText().toString());

                }
            }
        });
    }

    //Toggling List And Empty Bowler View
    private void toggleEmptyBowlers() {
        //You Can Check bowlerList.size() > 0

        if (db.getBowlersCount() > 0) {
            noBowlersView.setVisibility( View.GONE);
        } else {
            noBowlersView.setVisibility( View.VISIBLE);
        }
    }

    @Override
    public void onRestart() {
        super.onRestart();
        //When BACK BUTTON is pressed, the activity on the stack is restarted
        //Do what you want on the refresh procedure here
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate( R.menu.menu_main, menu );
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            Intent intent = new Intent(this, SettingsActivity.class);
            startActivity(intent);
            overridePendingTransition(0, 0);
            return true;
        }

        return super.onOptionsItemSelected( item );
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);
        //Check If Request Code Is The Same As What Is Passed - Here It Is 1
        if(requestCode==1)
        {
            String savedLeagueId=data.getStringExtra("seriesLeagueId");
            String seriesBowlerId=data.getStringExtra("seriesBowlerId");
            bowlersList.addAll(db.getAllBowlers(savedLeagueId));
        }
    }

    @Override
    public void onBackPressed() {
        startActivity(new Intent(getApplicationContext(),MainActivity.class));
        finish();
        overridePendingTransition(0, 0);
    }
}

我真的希望有人可以帮助我解决此问题。我已经尝试了与其他stackoverflow帖子不同的几种方法,但仍然无法解决。

4 个答案:

答案 0 :(得分:1)

  proxy_host = "${element(split(":", var.http_proxy),0)}"
  proxy_port = "${element(split(":", var.http_proxy),1)}"

表示适配器将向上移动项目并为其设置动画。但是,这些物品不会重绘。

您可以通过删除任何项目后单击列表的最后一项来观察到这一点:您应该看到相同的崩溃。

然后,通过单击删除的项目之后的任何项目(最后一个项目除外),详细信息视图应显示下一个项目,而不是您单击的项目。

问题在于mAdapter.notifyItemRemoved(position); 不再相关,因为索引已更改。而是使用活页夹中已有的position的值。只需删除遮盖leagueId且应能正常工作的int leagueId

答案 1 :(得分:0)

问题在于视图已被绑定,并且该方法的位置:

    holder.name.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            int leagueId = leaguesList.get(position).getId(); // here position will still be 1 after deletion
            //...
        }
    });

属于旧索引。要修复此问题,请使用以前使用的相同对象。

    holder.name.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            int leagueId = league.getId(); //league object will be the same
            //...
        }
    });

答案 2 :(得分:0)

****试试这个****

@Override
protected void onBindViewHolder(@NonNull final BoardsViewHolder holder, final int position, @NonNull final Board model) {

    holder.setTitle(model.getBoardTitle());
    holder.setDesc(model.getBoardDesc());
    holder.setDate(model.getCreatedOn());
    holder.mDeleteBoardButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AlertDialog.Builder alert = new AlertDialog.Builder(mContext);
            alert.setTitle("Delete Board");
            alert.setMessage("This Board will be deleted forever");
            alert.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    final ProgressDialog loading = new ProgressDialog(mContext);
                    loading.setMessage("Deleting...");
                    loading.show();
                   getSnapshots().getSnapshot(position).getReference().delete().addOnCompleteListener(new OnCompleteListener<Void>() {
                       @Override
                       public void onComplete(@NonNull Task<Void> task) {

                           if (task.isSuccessful()){
                               notifyDataSetChanged();
                               loading.dismiss();

                           }else {
                               loading.dismiss();
                               Toast.makeText(mContext,"Something went wrong please try again later",Toast.LENGTH_LONG).show();
                           }

                       }
                   });



                }
            });
            alert.setNegativeButton("Keep", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
            alert.show();
        }
    });

答案 3 :(得分:-2)

这是从零开始的元素的问题。您的代码正在尝试访问不存在的元素索引。以调试模式启动您的应用,然后逐行查看发生了什么。 Android studio内置了出色的调试器,因此很容易一步一步地了解变量的情况。