我有一个搜索栏,一个搜索按钮(因为我刚转换为使用onKeyPress并且还没有删除它)和一个TextView。
它运作良好,除了每个按键发出一个新的Search()调用,旧的调用不会停止运行。如果我键入太快或太长,应用程序崩溃。当onKeyPress()触发时,如何更好地管理我的线程或退出之前的Search()执行?
谢谢!
的AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="corp.dtc.tel" >
<application
android:allowBackup="true"
android:icon="@mipmap/tel_ico"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".TEL_Main_Activity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp" >
<EditText
android:id="@+id/search_box"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:hint="Enter Here"
android:inputType="text"
android:textSize="12sp"
android:layout_marginLeft="5dp"
android:layout_weight="1" />
<Button
android:id="@+id/search_button"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Search..."
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:onClick="Search"/>
</LinearLayout>
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:hint="List of Numbers will be here"
android:id="@+id/list_view"
android:maxLines="50"
android:scrollbars="vertical"
android:freezesText="true" />
</LinearLayout>
MainActivity.java
package corp.dtc.tel;
import android.content.Intent;
import android.graphics.Typeface;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.method.ScrollingMovementMethod;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.IOException;
public class TEL_Main_Activity extends ActionBarActivity {
TextView textView;
EditText editText;
Button button;
Employee[] list;
Employee[] employees;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getSupportActionBar();
actionBar.setLogo(R.mipmap.tel_ico);
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
LoadArray la = new LoadArray();
try {
employees = la.LoadArray(this, R.raw.droid);
} catch (IOException e) {}
setContentView(R.layout.activity_tel_main);
textView = (TextView) findViewById(R.id.list_view);
textView.setHorizontallyScrolling(true);
textView.setMovementMethod(new ScrollingMovementMethod());
textView.setTypeface(Typeface.MONOSPACE);
button = (Button) findViewById(R.id.search_button);
editText = (EditText) findViewById(R.id.search_box);
editText.addTextChangedListener(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) {
Search(findViewById(R.id.layout));
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
@Override
public void onResume() {
super.onResume();
try {
//check if any view exists on current view
Button style = ((Button) findViewById(R.id.search_button));
} catch (Exception e) {
Intent i = new Intent();
i.setClass(getApplicationContext(), TEL_Main_Activity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_tel_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void UpdateTextView () {
textView.setText(String.format("%-20s %10s %10s", list[0].name, list[0].number, list[0].support));
for (int x = 1 ; x < list.length & list[x] != null ; x++) {
textView.append("\n" +
(String.format("%-20s %12s %10s", list[x].name, list[x].number, list[x].support)));
}
}
public void Search(View view) {
textView.setText(null);
EditText line = (EditText) findViewById(R.id.search_box);
String[] tokens = line.getText().toString().split(" ");
if (tokens.length == 0)
{
//There was nothing in the search box.
}
else {
list = new Employee[50];
int listCtr = 0; //Keeps ctr for list[]
for (int dbCtr = 0 ; dbCtr < 5000 ; dbCtr++) {
System.out.println(dbCtr);
if (listCtr == 50)
break;
if (employees[dbCtr] == null)
{
//Should have less than 50 listed items and finished searching.
//Now it is okay to update the list view.
UpdateTextView();
break;
}
if (employees[dbCtr].contains(tokens))
{
list[listCtr] = employees[dbCtr];
listCtr++;
}
}
}
}
}
应用目的:搜索公司员工列表,显示结果。(必须显示少于51个结果)
答案 0 :(得分:0)
我不认为&#34;其他搜索没有停止运行&#34;真的很好地描述了这里出了什么问题。我没有看到任何&#34;线程。&#34;我认为问题在于您尝试进行搜索&#34; on keyPress,&#34;因此&#34; 每个 keyPress。&#34;
更好的方式来考虑你在这里尝试做的事情:&#34;我想自动按下按钮&#39;一旦用户停止输入。&#34;
所以,基本上,当用户开始按键时,你将启动一个计时器(如果这样的计时器还没有运行)设置为熄灭,比如说,1/2秒。然后,在任何情况下,您都会设置一个标记为true
,表示&#34;用户最近按了一个键。&#34;
当计时器熄灭时,它会检查此标志是否为true
。如果是这样,它会将标志设置为false
并重新安排计时器再次以1/2秒再次启动。否则,它会执行&#34;按下按钮&#34;过去,它会重置(单独)标志,表示计时器正在运行。
只要用户每1/2秒按下至少一个按键,定时器就会继续自行重新安排(并且,没有其他人会尝试启动定时器,因为他们可以看到定时器&#39; s运行)。但是,最终,计时器将看到按键已被按下的标志保持假半秒。当它按下按钮时,&#34;导致搜索发生。
对于彻底的解决方案,在执行搜索之后,计时器例程将检查&#34;键已被按下&#34;再次举起旗帜。如果它仍然 false
,则用户确实已停止输入,并且现在是时候展示这些搜索结果了。否则,计时器例程应该重新开始重新安排。
最终,用户将停止输入。计时器将运行搜索,并且在完成此操作后,将看到用户仍然没有输入更多内容。然后将显示结果(第一次)。