2017-05-23 91 views
0

即時通訊有點卡住了我的編程。將類變量傳遞給自定義偵聽器

我會盡我所能解釋我的問題: 目前我有一個類存儲數據和getter/setter方法。 該班有幾個變數,主要是布爾/整數和一些浮點數。

在我的MainActivty佈局中,我有一個簡單的textview,seekbar和edittext。 看起來像這樣: https://i.stack.imgur.com/jeZW6.png

現在,我創建了兩個自定義偵聽器。一個OnSeekBarChangeListener和一個TextWatcher。他們所做的是,如果我更改seekbar上的值,它會將edittext的文本設置爲seekbar的進度。另一個將seekbar的進度設置爲相應編輯文本的輸入值。

textwatcher類的構造函數獲取EditText,SeekBar和我的數據類「Config」的一個對象作爲參數。 seekbar的偵聽器僅獲取EditText和Config對象作爲參數。 我想保持聽衆儘可能模塊化,因爲我將不得不重複使用它們。

顯然,如果在主佈局中有多於一行,我必須在配置對象的不同變量中保存不同的seekbar進度和edittext輸入。

這裏是我的問題,我根本無法弄清楚如何將配置對象的不同變量傳遞給偵聽器,即在下面的代碼中創建一個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); 
    } 
} 

我希望我的解釋是有道理的,我想實現,我可以使用在任何搜索欄/ EditText上,並能夠告訴它什麼變量應該進度/輸入保存到完全獨立的聽衆。

我真的很感謝這方面的幫助。

歡呼

+0

你想設置變量的使用時間?在構造函數中使用映射並傳遞鍵值怎麼樣?這會回答你的問題嗎?如果你想選擇一個特定的setter或field,你可能必須使用反射;我沒有看到你沒有辦法做到這一點(除非你單獨調用每個setter,例如從一個大的'switch')。 –

+0

那麼我最終試圖實現的是,我將能夠從服務器解析xml文件(〜2000行),並將約1000個不同的變量保存到配置對象。該應用程序的目的是編輯一個XML由不同的Windows應用程序使用的配置。每個變量都會在佈局中包含這些行中的一行,可以使用布爾值的textview/switch或者ints/float的textview/seekbar/edittext。所以我可能會設置監聽器在他們使用的片段/活動的oncreate。而且,因爲我剛剛進入java/android它可能是最容易使用一個大開關。 –

+0

在這種情況下,使用「HashMap」這樣的Map就是最好的選擇。你不去1000線路交換機。對於重複性的任務,你使用你的電腦,而不是相反。 –

回答

0

OK,我想我得到了你正在嘗試做的,讓我們看看如果你能理解&使用此方案:

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(); 
    } 
} 

它使用一個映射到不同的處理程序,它調用給定配置字符串的處理程序。

+0

請注意,這確實使用某種間接方式。你當然也可以讓你的Config實例直接返回一個配置好的處理程序。但字符串更容易放入Config實例中。 –

+0

嘿,非常感謝!我重寫了應用程序的數據層,它更容易按照你的方式做! –

相關問題