Bri*_*ian 6 android textwatcher
我正在编写一个使用和外部连接USB条形码/ RFID扫描仪的应用程序.正在扫描的数据是"复合"数据.这是一个例子:
=+03000=W12560712345600=%2800&>0090452359
Run Code Online (Sandbox Code Playgroud)
那是来自复合数据扫描.数据中的分隔符是等号(=)或&符号(&).第一位=+03000说扫描中有三个数据部分:
=W12560712345600
=%2800
&>0090452359
Run Code Online (Sandbox Code Playgroud)
该数据可以具有从1到N的任意数量的数据部分.
在我的Android应用程序中,我有一个包含三个EditText元素的表单.我需要对这个复合扫描数据做的是使用分隔符将其分解,并将每个数据粘贴到适当的EditText字段中.
经过多次痛苦之后,我已经意识到我不能只操纵标准输入,并且我需要TextWatcher在我的一个EditText字段上使用捕获扫描数据以便我可以操作它.
我的问题是我无法弄清楚如何做到这一点.这是我有的:
activity_main.xml中
<LinearLayout>
<TextView />
<EditText android:id="@+id/datafield01" />
<EditText android:id="@+id/datafield02" />
<EditText android:id="@+id/datafield03" />
<Button />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText dataField01 = (EditText)findViewById(R.id.datafield01);
EditText dataField02 = (EditText)findViewById(R.id.datafield02);
EditText dataField02 = (EditText)findViewById(R.id.datafield03);
dataField01.addTextChangedListener(editTextWatcher);
}
TextWatcher editTextWatcher = new TextWatcher(){
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after){
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count){
}
@Override
public void afterTextChanged(CharSequence s){
}
};
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试捕获CharSequence到StringBuffer- 使用before,on和afterTextChanged - 所以我可以操纵它并将它放入正确的EditText元素,但我没有成功.
修改了MainActivity.java
public class MainActivity extends AppCompatActivity {
private StringBuffer stringBuffer;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
stringBuffer = new StringBuffer();
EditText dataField01 = (EditText)findViewById(R.id.datafield01);
EditText dataField02 = (EditText)findViewById(R.id.datafield02);
EditText dataField02 = (EditText)findViewById(R.id.datafield03);
dataField01.addTextChangedListener(editTextWatcher);
System.out.println(stringBuffer.toString());
}
TextWatcher editTextWatcher = new TextWatcher(){
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after){
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count){
stringBuffer.append(s);
}
@Override
public void afterTextChanged(CharSequence s){
}
};
}
Run Code Online (Sandbox Code Playgroud)
每当我试着去System.out.println(stringbuffer);那里什么都没有.
扫描的代码不提供换行符或任何其他类型的分隔符,它已经结束,数据部分的数量可以是1到N,但每个数据部分确实具有已知的固定长度.
必须有其他人做这样的事情,但我的谷歌搜索没有结果.
那么,有什么方法可以完成我想做的事情,还是我完全没有运气?
谢谢.
我确信有一种方法可以通过某些TextWatcher实现来做到这一点;当您看到分隔符等时切换焦点。
但我认为,当您知道拥有条形码扫描仪的所有输入时,处理起来会更容易。然后您可以简单地解析数据并将其放在适当的位置。
因此,关键是要弄清楚何时拥有所有扫描仪输入,以便可以解析它。
下面是一些使用我从查看 AndroidFilter适配器类中学到的技巧的代码。有一个延迟机制,可以对多次快速按键仅过滤一次。(遗憾的是,它是谷歌私有的,所以我们凡人不应该使用这个有用的功能。)
由于您的扫描仪显然就像键盘一样,因此按键暂停应该意味着扫描仪已完成输入。让我们用它来确定扫描何时完成。
首先,我们将定义一个回调接口,因为我是一个 IoC 类型的人:
interface ScanProcessor {
void process(CharSequence input);
}
Run Code Online (Sandbox Code Playgroud)
现在我们将定义一个Handler类。该处理程序将在主(UI)线程上运行,因此我们不能让处理器太忙。
public static class InputDelayHandler extends Handler {
private static final int INPUT_MESSAGE = 0x20170308;
private static final int PROCESS_MESSAGE = 0x20170309;
// You'll have to tweak this value to ensure all input is entered,
// while the app remains responsive to the scan
private static final long DELAY_MS = 250;
private CharSequence mInput;
private ScanProcessor mScanProcessor;
InputDelayHandler(ScanProcessor scanProcessor) {
super(); // associate the handler with the Looper for the current thread
mScanProcessor = scanProcessor;
}
void setInput(CharSequence input) {
// removing this message is the key to how this works
// since it's delayed, we can cancel before input is complete.
removeMessages(PROCESS_MESSAGE);
removeMessages(INPUT_MESSAGE);
Message inputMessage = obtainMessage(INPUT_MESSAGE);
inputMessage.obj = input;
sendMessage(inputMessage);
Message startMessage = obtainMessage(PROCESS_MESSAGE);
sendMessageDelayed(startMessage, DELAY_MS);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case INPUT_MESSAGE:
// remember the last input
mInput = (CharSequence) msg.obj;
break;
case PROCESS_MESSAGE:
// callback
if (/*mInput looks like valid scan data*/) {
mScanProcessor.process(mInput);
}
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
具有EditText字段的类应该保留对处理程序的引用。
private InputDelayHandler mHandler;
Run Code Online (Sandbox Code Playgroud)
现在你TextWatcher只需要告诉处理程序发生了什么事:
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mHandler.setInput(s);
}
Run Code Online (Sandbox Code Playgroud)
这将它们联系在一起:
mHandler = new InputDelayHandler(new ScanProcessor() {
@Override void process(CharSequence input) {
// parse the input, set the EditText fields, etc.
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
340 次 |
| 最近记录: |