0

I am trying to change the text on a button after setOnLongClickListener amd there are six buttons to choose from. Currently, regardless of which button I click, the list button is updated with the new text.

I think I have tried everything on this thread: setonlongclicklistener for several buttons at once

Eventually i hope to save these new button values to shared preferences so they are there when the app is next started.

public class MainActivity extends AppCompatActivity {

    private Button btn;
    Context context;
    final String[] task = new String[1];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        context = MainActivity.this;
        Resources r = getResources();
        String pName = getPackageName();

        String PREFERENCES_FILE_KEY = "com.example.buttondemo";
        String SECURE_PREFS_FILE_KEY = "com.example.buttonnames";

        // Declare shared preferences
        SharedPreferences sharedPreferences = this.getSharedPreferences(PREFERENCES_FILE_KEY, Context.MODE_PRIVATE);

        // get shared preferences for each button and apply the stored name to each button
        //String buttonText = sharedPreferences.getString("Value01", "Button_01");

        for (int i=1;i<=6;i++) {
            String buttonId = "button" + i;
            btn = (Button) findViewById(r.getIdentifier(buttonId, "id", pName));
            btn.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(final View v) {

                    task[0] = showAddItemDialog(MainActivity.this, btn);
                    //sharedPreferences.edit().putString(buttonId, task[0]).apply();
                    return true;
                }
            });
        }
    }


    private String showAddItemDialog(Context context, Button btnNew) {
        final EditText taskEditText = new EditText(context);
        taskEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(10)});
        final String[] task = new String[1];
        AlertDialog dialog = new AlertDialog.Builder(context)
                .setTitle("Enter New button value")
                .setMessage("Enter New button value:")
                .setView(taskEditText)
                .setPositiveButton("Update", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        task[0] = String.valueOf(taskEditText.getText());
                        btnNew.setText(String.valueOf(taskEditText.getText()));
                    }
                })
                .setNegativeButton("Cancel", null)
                .create();
        dialog.show();

        return task[0];
    }
}

Thanks.

Shay Kin
  • 2,539
  • 3
  • 15
  • 22
John
  • 787
  • 4
  • 11
  • 28

1 Answers1

0

What's happening is the btn variable is getting reassigned each iteration of your loop. Therefore once the long click listener fires, you are calling showAddItemDialog(this, btn) where btn is holding a reference to whatever it was set to in the last loop iteration (when i = 6).

So the behaviour you're experiencing makes sense. Hopefully this is enough to point you in the right direction.


As a side note, finding views based on dynamic ids that come from r.getIdentifier() might be a bit of a bad design choice and could open up bugs in the future. I would recommend simplifying it to just use R.id.button1, R.id.button2 etc. if possible.

Henry Twist
  • 5,666
  • 3
  • 19
  • 44
  • I had a feeling that was the cause of the problem. So do i move the loop inside the onLongClickListener? I was going this way, because there will be 15 buttons and with that 15 calls to sharedPreferenes to save these values. So it might get a big chunky. – John Mar 04 '21 at 18:34
  • Your loop is fine in concept, you just need to have `btn` as a local variable as opposed to a member of your class. – Henry Twist Mar 04 '21 at 18:46
  • Perfect, thank you. Button btn = (Button) findViewById(r.getIdentifier(buttonId, "id", pName)); I'll try this loop solution and the individual R.id.button1, R.id.button2 to see how it reads. – John Mar 04 '21 at 20:13