【问题标题】:Multiple Switch Buttons多个开关按钮
【发布时间】:2018-01-23 13:48:31
【问题描述】:

我是Android开发新手,有一个关于多个开关按钮的问题,如何智能地检索值,并使这些数据可用于其他活动?

目前,我实现了按钮状态的保存和当前活动中找到的信息的检索,如下所示:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    switchButtonOne = findViewById(R.id.switchButtonOne);
    switchButtonOne.setChecked(true);

    switchButtonTwo = findViewById(R.id.switchButtonTwo);
    switchButtonTwo.setChecked(false);

    //...... (In total there are 5 switch buttons)

    //switchButtonOne
    switchButtonOne.setOnCheckedChangeListener((compoundButton, isChecked) -> {
        if(isChecked){
            stringArrayList.add("1");
        }else {
            stringArrayList.remove("1");
        }
        getArray(stringArrayList);
        //SAVE
        sharedPreferences[0] = PreferenceManager
                .getDefaultSharedPreferences(getApplicationContext());
        SharedPreferences.Editor editor = sharedPreferences[0].edit();
        editor.putBoolean("1", switchButtonOne.isChecked());
        editor.commit();
    });
    switchButtonOne.setChecked(sharedPreferences[0].getBoolean("1", false));

    //switchButtonTwo
    switchButtonTwo.setOnCheckedChangeListener((compoundButton, isChecked) -> {
        if(isChecked){
            stringArrayList.add("2");
        }else {
            stringArrayList.remove("2");
        }
        getArray(stringArrayList);
        //SAVE
        sharedPreferences[0] = PreferenceManager
                .getDefaultSharedPreferences(getApplicationContext());
        SharedPreferences.Editor editor = sharedPreferences[0].edit();
        editor.putBoolean("2", switchButtonTwo.isChecked());
        editor.commit();
    });
    //.......
}

我确信有一种更有效的方法来实现这一点,我很高兴能够获得有效的资源来学习在活动之间提供信息和活动状态的最佳实践。

提前致谢

【问题讨论】:

  • 我不明白是什么问题,你能用更好的方式解释你想做什么吗?
  • 你好,约翰!我想知道如何使这段代码更小更好。我认为代码太长且重复。我想做的另一件事是保存切换按钮状态并使其可用于其他活动,因为这些按钮将是一个过滤器,稍后将获取一个 json 文件以将结果过滤到其他活动中(这是设置活动)

标签: java android listview android-fragments


【解决方案1】:

一种选择是对所有五个按钮仅使用一个侦听器。你可以这样做:

public class MyActivity extends Activity implements CompoundButton.OnCheckedChangeListener {
    Switch[] buttons;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        buttons = new Switch[5];
        Switch switchButtonOne = findViewById(R.id.switchButtonOne);
        switchButtonOne.setOnCheckedChangeListener(this);
        switchButtonOne.setChecked(sharedPreferences[0].getBoolean("1", false));
        buttons[0] = switchButtonOne;

        Switch switchButtonTwo = findViewById(R.id.switchButtonTwo);
        switchButtonTwo.setOnCheckedChangeListener(this);
        switchButtonTwo.setChecked(sharedPreferences[1].getBoolean("2", false));
        buttons[1] = switchButtonTwo;

        //...... (In total there are 5 switch buttons)
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        int index;
        switch (buttonView.getId()) {
            case R.id.switchButtonOne:
                index = 0;
                break;
            case R.id.switchButtonTwo:
                index = 1;
                break;
                ...
        }
        if (isChecked) {
            stringArrayList.add(String.valueOf(index + 1));
        } else {
            stringArrayList.remove(String.valueOf(index + 1));
        }
        getArray(stringArrayList);
        //SAVE
        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        SharedPreferences.Editor editor = sharedPreferences[index].edit();
        editor.putBoolean(String.valueOf(index + 1), buttons[index].isChecked());
        editor.commit();
    }
}

此时代码并没有比你的短很多,但是,一旦你添加了其他三个按钮,你就会发现所有按钮的代码都变得更短更简洁了。

如果SharedPreferences 有一个BooleanArray,那就太好了,但是,这样的类不存在。可以找到解决方法here

编辑

再次查看您的问题和完整代码,我建议采用不同的方法。你根本不需要任何OnCheckedChangeListener。只需在活动离开时保存按钮的状态 (onPause) 并在活动恢复后恢复状态 (onResume)。副作用是代码变得更短。

public class MainActivity extends Activity {
    Switch[] buttons;
    int numberOfButtons = 5;
    SharedPreferences sharedPreferences;

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

        buttons = new Switch[numberOfButtons];
        sharedPreferences = getSharedPreferences("YourPreferenceName", MODE_PRIVATE);

        for (int i = 0; i < numberOfButtons; i++) {
            buttons[i] = findViewById(getResources().getIdentifier("switchButton" + String.valueOf(i + 1), "id", getPackageName()));
        }
    }

    public void onPause() {
        super.onPause();
        for (int i = 0; i < numberOfButtons; i++) {
            SharedPreferences.Editor editor = sharedPreferences.edit();
            editor.putBoolean(String.valueOf(i + 1), buttons[i].isChecked());
            editor.apply();
        }
    }

    public void onResume(){
        super.onResume();
        for (int i = 0; i < numberOfButtons; i++) {
            buttons[i].setChecked(sharedPreferences.getBoolean(String.valueOf(i + 1), false));
        }
    }
}

请注意,在您的布局 xml 中,您必须将开关的 ID 更改为以下内容:switchButton1, ..., switchButton5

【讨论】:

  • 我真的很喜欢你的代码!这正是我想要的!但是当我单击活动时会发生错误。显然它正在返回 null isChecked() 虚拟方法。你能告诉我为什么会这样吗?再次感谢@kalabalik java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.widget.Switch.isChecked()' on a null object reference
  • 出现在倒数第二行? index 出现时是什么?
  • 错误消息的要点是不是,它返回的不是布尔值而不是布尔值null,而是调用isChecked 的对象是null
  • 我尝试调试代码以查看它在哪个索引中给出错误但未实现!当我删除 setChecked() 时出现另一个错误:java.lang.ArrayIndexOutOfBoundsException: length=1; index=1 完整代码:link
  • onCreate,你应该给每个布尔值一个从1到5的键。否则这个代码不再工作:editor.putBoolean(String.valueOf(index + 1), buttons[index].isChecked());但是,这不会是错误的来源消息。
【解决方案2】:

您可以为整个活动实现CompoundButton.OnCheckedChangeListener,然后为您使用的所有开关设置监听器。在单个回调onCheckedChanged 中处理所有开关。

public class SwitchActivity extends Activity implements CompoundButton.OnCheckedChangeListener {
    Switch switchButtonOne;
    Switch switchButtonTwo;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {

        super.onCreate(savedInstanceState, persistentState);
        switchButtonOne = findViewById(R.id.switchButtonOne);
        switchButtonOne.setChecked(true);

        switchButtonTwo = findViewById(R.id.switchButtonTwo);
        switchButtonTwo.setChecked(false);

        switchButtonOne.setOnCheckedChangeListener(this);
        switchButtonTwo.setOnCheckedChangeListener(this);
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        switch (buttonView.getId()) {
            case R.id.switchButtonOne:
                //Handle Code for switchButtonOne
                break;
            case R.id.switchButtonTwo:
                //Handle Code for switchButtonOne
                break;
        }
    }
}

【讨论】:

    猜你喜欢
    • 2021-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-05
    • 2012-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多