Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android

justin z
justin z
11,042 Points

For some reason more than one point is being added to my scoreboard when I click the add button?

I am having this bizarre bug where sometimes when I click on the add button, instead of adding one point it will increase the number by more than one points, by like 5 or 2 or 8 or something, I think it may have something to do with my adapter...

package com.teamtreehouse.golfscoreboard.adapters;

import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; import android.widget.Toast;

import com.teamtreehouse.golfscoreboard.R; import com.teamtreehouse.golfscoreboard.models.ScoreKeeper; import com.teamtreehouse.golfscoreboard.ui.MainActivity;

import java.util.List;

public class GolfScoreAdapter extends RecyclerView.Adapter<GolfScoreAdapter.MyViewHolder>{

private List<ScoreKeeper> mScoreKeepers;
private ScoreKeeper mScoreKeeper;

public class MyViewHolder extends RecyclerView.ViewHolder {
    public TextView mHoleLabel, mPointLabel;
    public Button mAddButton, mSubButton;


    public MyViewHolder(View itemView) {
        super(itemView);
        mHoleLabel = (TextView) itemView.findViewById(R.id.holeLabel);
        mPointLabel = (TextView) itemView.findViewById(R.id.pointLabel);
        mAddButton = (Button) itemView.findViewById(R.id.addButton);
        mSubButton = (Button) itemView.findViewById(R.id.subButton);
    }


}

public GolfScoreAdapter(List<ScoreKeeper> scoreKeepers){
    mScoreKeepers = scoreKeepers;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.hole_score_row, parent, false);
    return new MyViewHolder(itemView);
}

@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
    mScoreKeeper = mScoreKeepers.get(position);
    int number = position + 1;
    String holes = "Hole "+number+":";
    int points = mScoreKeeper.getPoints();
    holder.mHoleLabel.setText(holes);
    holder.mPointLabel.setText(points+"");
    holder.mAddButton.setText("+");
    holder.mSubButton.setText("-");
    holder.mAddButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mScoreKeeper.addPoint();
            holder.mPointLabel.setText(mScoreKeeper.getPoints()+"");
        }
    });
    holder.mSubButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mScoreKeeper.decPoint();
            if(mScoreKeeper.getPoints()<0){mScoreKeeper.setPoints(0);}
            holder.mPointLabel.setText(mScoreKeeper.getPoints()+"");
        }
    });

}

@Override
public int getItemCount() {
    return mScoreKeepers.size();
}

}

Here is my ScoreKeeper class...

package com.teamtreehouse.golfscoreboard.models;

public class ScoreKeeper { private int mPoints;

public int getPoints() {
    return mPoints;
}

public ScoreKeeper(){
    mPoints=0;

}

public void addPoint(){
    mPoints++;
}

public void decPoint(){
    mPoints--;
}

public void setPoints(int points) {
    mPoints = points;
}

}

And here is my MainActivity class just in case you need it:

package com.teamtreehouse.golfscoreboard.ui;

import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.view.View; import android.view.Menu; import android.view.MenuItem;

import com.teamtreehouse.golfscoreboard.R; import com.teamtreehouse.golfscoreboard.adapters.GolfScoreAdapter; import com.teamtreehouse.golfscoreboard.models.ScoreKeeper;

import java.util.ArrayList; import java.util.List;

public class MainActivity extends AppCompatActivity {

private static final String PREFS_NAME = "preferences";
private static final String HOLE_NUM = "hole one";
private RecyclerView mRecyclerView;
private GolfScoreAdapter mAdapter;
private List<ScoreKeeper> mScoreKeepers;
private SharedPreferences mSharedPreferences;
private SharedPreferences.Editor mEditor;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    mSharedPreferences = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
    mEditor = mSharedPreferences.edit();
    mScoreKeepers = new ArrayList<ScoreKeeper>();
    getHoles();
    mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    mAdapter = new GolfScoreAdapter(mScoreKeepers);
    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
    mRecyclerView.setLayoutManager(mLayoutManager);
    mRecyclerView.setItemAnimator(new DefaultItemAnimator());
    mRecyclerView.setAdapter(mAdapter);


}



@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.clear_score) {
        mEditor.clear();
        mEditor.apply();
        for (ScoreKeeper sk : mScoreKeepers) {
            sk.setPoints(0);
        }
        mAdapter.notifyDataSetChanged();
        return true;
    }

    return super.onOptionsItemSelected(item);
}

private void getHoles(){
    ScoreKeeper sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);
    sk = new ScoreKeeper();
    mScoreKeepers.add(sk);

    for(int i =0;i<18;i++){
        mScoreKeepers.get(i).setPoints(mSharedPreferences.getInt(HOLE_NUM+i,0));
    }
}



@Override
protected void onPause() {
    super.onPause();
    for(int i=0;i<18;i++){
    mEditor.putInt(HOLE_NUM+i,mScoreKeepers.get(i).getPoints());
    mEditor.apply();
    }
}

}

Thanks!

1 Answer

Seth Kroger
Seth Kroger
56,413 Points

In your adapter you are storing the ScoreKeeper element from the list as a member variable then using that in the onClickListener's the problem with that approach is that it won't increment/decrement the score for the list item you're clicking, but the last item in the list that was bound to a holder.