我正在学习Android编程并创建REST客户端。我已经用Postman检查了服务器,它工作正常。在Android端,我创建了一个AutoCompleteTextView
,它被通过REST接收的数据填充,这不能正常工作。例如,如果我键入'A',则不会出现列表,但如果我键入'Ap',然后删除'p',则会出现一些选项。我检测到它正在正确接收数据,但AutoCompleteTextView
中使用的适配器没有清除,也没有正确更新。你能告诉我我错过了什么吗?
下面是我的MainActivity类:
package com.example.connectdb;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import androidx.appcompat.app.AppCompatActivity;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private static final String BASE_URL = "http://192.168.0.154:8080/autocomplete/json";
private AutoCompleteTextView autoCompleteTextView;
private ArrayAdapter<String> adapter;
private String[] arr = {};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
autoCompleteTextView = findViewById(R.id.autoCompleteTextView);
adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, arr);
autoCompleteTextView.setThreshold(1);
autoCompleteTextView.setAdapter(adapter);
autoCompleteTextView.addTextChangedListener(textWatcher);
}
private final TextWatcher textWatcher = new TextWatcher() {
private ExecutorService executor = Executors.newSingleThreadExecutor();
private Handler handler = new Handler(Looper.getMainLooper());
private List<String> strings;
public void execute(String string) {
executor.execute(new Runnable() {
@Override
public void run() {
strings = backgroundWork(string);
handler.post(new Runnable() {
@Override
public void run() {
changeAdapter(strings);
}
});
}
});
}
private List<String> backgroundWork(String string) {
List<String> results = new ArrayList<>();
try {
URL url = new URL(BASE_URL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(false);
connection.addRequestProperty("Content-Length", Integer.toString(6+string.length()));
connection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.connect();
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
writer.write("query="+string);
writer.flush();
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append('\n');
}
bufferedReader.close();
inputStream.close();
JSONArray jsonArray = new JSONArray(stringBuilder.toString());
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
results.add(jsonObject.getString("interpretation"));
}
}
} catch (IOException | JSONException e) {
Log.e(TAG, "Error occurred while searching", e);
}
return results;
}
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
String text = autoCompleteTextView.getText().toString().trim();
if (!text.isEmpty()) execute(text);
}
};
public void changeAdapter(List<String> strings) {
if (adapter != null) {
adapter.clear();
if (strings != null) adapter.addAll(strings);
adapter.notifyDataSetChanged();
}
}
}
activity_main.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<AutoCompleteTextView
android:id="@+id/autoCompleteTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:hint="Search..."
android:imeOptions="actionDone"
android:inputType="textAutoComplete|textCapWords" />
</RelativeLayout>
AndroidManifest.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.ConnectDB"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
1条答案
按热度按时间h5qlskok1#
代码没问题,但需要一个
AutoCompleteTextView
的适配器,根本没有过滤,应该用它来代替ArrayAdapter
。因为我用ChatGPT创建了NoFilterAdapter
,所以我不在这里上传代码。