将类变量传递给自定义侦听器

时间:2017-05-23 22:25:36

标签: java android

我很喜欢我的编程。

我会尽力解释我的问题: 目前我有一个存储数据的类,并具有getter / setter方法。 该类中有几个变量,主要是布尔值/整数和一些浮点数。

在我的MainActivty布局中,我有一个简单的文本视图,搜索栏和编辑文本。 看起来像这样: https://i.stack.imgur.com/jeZW6.png

现在,我创建了两个自定义Listener。一个OnSeekBarChangeListener和一个TextWatcher。他们所做的是,如果我更改搜索栏上的值,它会将edittext的文本设置为搜索栏的进度。另一个将搜索栏的进度设置为相应编辑文本的输入值。

textwatcher类的构造函数将EditText,SeekBar和我的数据类“Config”的对象作为参数。 seekbar的监听器只获取EditText和Config对象作为参数。 我想让听众尽可能保持模块化,因为我必须重复使用它们。

显然,如果主布局中有多行,我必须在配置对象的不同变量中保存不同的搜索栏进度和编辑文本输入。

这就是我的问题,我根本无法弄清楚如何将配置对象的不同变量传递给侦听器,即在下面的代码中我创建一个Config对象“defaultConfig”,该对象具有int VKCode。我希望能够告诉听众它应该保存到对象中的特定变量。

我的代码:

配置类:

public class Config {
    private int VKCode;

    public Config() {
    }

    public int getVKCode() {
        return VKCode;
    }

    public void setVKCode(int VKCode) {
        this.VKCode = VKCode;
    }

}

MainActivity:

public class MainActivity extends AppCompatActivity {

private SeekBar sbVKCode;
private EditText etVKCode;
private Config defaultConfig;


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

    sbVKCode = (SeekBar) findViewById(R.id.sb_vkcode);
    etVKCode = (EditText) findViewById(R.id.et_vkcode);
    etVKCode.setText(Integer.toString(0));

    defaultConfig = new Config();

    sbVKCode.setOnSeekBarChangeListener(new CustomSeekBarChangeListener(etVKCode,defaultConfig));
    etVKCode.addTextChangedListener(new CustomTextChangeListener(etVKCode, sbVKCode,defaultConfig));
  }
}

CustomSeekBarChangeListener:

public class CustomSeekBarChangeListener implements SeekBar.OnSeekBarChangeListener {

private EditText editText;
private Config config;

public CustomSeekBarChangeListener(EditText e, Config c) {
    editText = e;
    config = c;
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {

}

@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
    config.setVKCode(progress); //I want to be able to set to which variable it saves the progress within the config class
    editText.setText(Integer.toString(progress));
    Log.i("VKCode", Integer.toString(progress));
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {

   }
}

自定义TextWatcher:

public class CustomTextChangeListener implements TextWatcher {
private Handler handler;
private Runnable runnable;
private Config config;
private EditText editText;
private SeekBar seekBar;

public CustomTextChangeListener(EditText e, SeekBar sb, Config c) {
    handler = new Handler();
    editText = e;
    seekBar = sb;
    config = c;
    runnable = new Runnable() {
        @Override
        public void run() {
            if (editText.getText().toString() != "") {
                try {
                    int prog = Integer.parseInt(editText.getText().toString());
                    seekBar.setProgress(prog);
                    config.setVKCode(prog); //Here the same, i want to be able to set the variable it saves prog in via. the constructor of this TextWatcher
                    Log.i("VKCODE","" + config.getVKCode());
                } catch (NumberFormatException ex) {
                }
            }
        }
    };
}


@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    handler.removeCallbacks(runnable);
}

@Override
public void afterTextChanged(Editable s) {
    handler.postDelayed(runnable,500);
   }
}

我希望我的解释有意义,我想实现完全独立的侦听器,我可以在任何SeekBar / EditText上使用它,并能够告诉它应该保存进度/输入的变量。

我真的很感激任何帮助。

欢呼声

1 个答案:

答案 0 :(得分:0)

好吧,我想我得到了你想要做的事情,让我们看看你是否能理解&使用这个方案:

package nl.owlstead.stackoverflow;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class ListenerToConfiguredVariable {

    // this could also be some kind of SeekBar or it could simply call it
    private final Handler handlerSeekBar = new Handler() {

        @Override
        public void handleValue(String value) {
            System.out.println("SeekBar : " + value);
        }

    };

    // this could also be some kind of EditText or it could simply call it
    private final Handler handlerEditText = new Handler() {

        @Override
        public void handleValue(String value) {
            System.out.println("EditText : " + value);
        }

    };

    private Map<String, Handler> map;

    {
//        createMapManually();
        createMapUsingReflection();
    }

    private void createMapManually() {
        Map<String, Handler> theMap = new HashMap<>();
        theMap.put("handlerSeekBar", handlerSeekBar);
        theMap.put("handlerEditText", handlerEditText);
        map = java.util.Collections.unmodifiableMap(theMap);
    }

    private void createMapUsingReflection() {
        Map<String, Handler> theMap = new HashMap<>();

        // iterate over all fields
        Field[] declaredFields = this.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            // we only want the handlers, not any other field
            if (field.getType().isAssignableFrom(Handler.class)) {
                try {
                    theMap.put(field.getName(), (Handler) field.get(this));
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    throw new IllegalStateException(e);
                }
            }
        }
        map = java.util.Collections.unmodifiableMap(theMap);
    }

    interface Handler {
        void handleValue(String value);
    }

    public static class Config {
        public String getConfiguredVariable() {
            return "handlerSeekBar";
        }
    }

    public ListenerToConfiguredVariable() {
        Config config = new Config();
        // the for loop simulates reading all the values from the XML file
        for (int i = 0; i < 10; i++) {
            // this would be inside the listener
            String var = config.getConfiguredVariable();
            Handler handler = map.get(var);
            handler.handleValue(Integer.toString(i));
        }
    }

    public static void main(String[] args) {
        new ListenerToConfiguredVariable();
    }
}

它使用Map到不同的处理程序,并在给定配置字符串的情况下调用处理程序。