通过 Adapter/TextWatcher 更新几个 ListView 的单个 EditText
Single EditText that updates few ListViews via Adapter/TextWatcher
我有一个视图,其中我将单个 EditText 和屏幕分成两部分(2 个 ListView)。我想将数据输入到 EditText 并使用此数据以不同的方式更新两个 ListView。例如,对于第一个 ListView,以我的输入开头的单词。到第二个 ListView 去包含我输入的单词。
我制作了两个不同的自定义 ListAdapter 来实现所需的功能。然后我将它们添加到我的 EditText 对象中,错误就开始了。如果我只使用一个适配器,一切正常。
那么我如何将两个适配器用于单个 EditText 以不同的方式更新 2 个 ListView。
这是我的代码。
ListView lv;
ListView lv2;
ArrayAdapter<String> adapterForSearch;
ArrayAdapter<String> adapterForTurkishSearch;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.dictionary_screen);
mContext = this;
List<Map<String,?>> dictionaryTopics = new LinkedList<>();
dictionaryTopics.add(createItem("Я ТЫ МЫ ВЫ", formWordCouplesSet(words.getMeU())));
dictionaryTopics.add(createItem("Animals", formWordCouplesSet(words.getAnimals())));
// create our list and custom adapter
SeparatedListAdapter adapter = new SeparatedListAdapter(this);
adapter.addSection("Turkish Dictionary", new SimpleAdapter(this, dictionaryTopics, R.layout.list_complex,
new String[]{ITEM_TITLE, ITEM_CAPTION}, new int[]{R.id.list_complex_title, R.id.list_complex_caption}));
list = (ListView) findViewById(R.id.dictionary_topics);
list.setAdapter(adapter);
list.setClickable(true);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
for(int index=0; index<((ViewGroup)view).getChildCount(); ++index) {
View nextChild = ((ViewGroup)view).getChildAt(index);
if (index >0) {
if (checkVisibility(nextChild))
{
nextChild.setVisibility(View.GONE); dimCounter--; checkDimCounter();
}
else {
nextChild.setVisibility(View.VISIBLE); dimCounter++; checkDimCounter();
}
}
}
}
});
//Search Implementation
inputSearch = (EditText) findViewById(R.id.inputSearch);
lv = (ListView) findViewById(R.id.list_view);
lv2 = (ListView) findViewById(R.id.list_view2);
adapterForSearch = new MyAdapter<>(this, R.layout.list_item2, R.id.product_name, wordCombos);
adapterForTurkishSearch = new MyTurkishAdapter<>(this, R.layout.list_item2, R.id.product_name, wordCombos);
TextWatcher watcher1;
watcher1 = new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
if (cs.length() == 0)
{
lv.setAdapter(null);
}
else {
lv.setAdapter(adapterForSearch);
adapterForSearch.getFilter().filter(cs);
}
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}
@Override
public void afterTextChanged(Editable arg0) {
}
};
TextWatcher watcher2;
watcher2 = new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
if (cs.length() == 0)
{
lv2.setAdapter(null);
}
else {
lv2.setAdapter(adapterForTurkishSearch);
adapterForTurkishSearch.getFilter().filter(cs);
}
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}
@Override
public void afterTextChanged(Editable arg0) {
}
};
inputSearch.addTextChangedListener(watcher1);
inputSearch.addTextChangedListener(watcher2);
}
一个 EditText 只允许一个注册的 TextChangedListener,因此最后一个,"watcher2" 将是最终被使用的那个,因为它是最后一组。您应该找到一种方法将两个 onTextChanged() 块中的代码合并到一个 TextWatcher 中,并且只设置那个。
https://developer.android.com/reference/android/widget/TextView.html#addTextChangedListener(android.text.TextWatcher)
您可能还想考虑更改设置适配器的方式,这可能意味着您必须更改自定义适配器中的一些逻辑,但由于您没有 post 它们的代码,我无法判断你肯定。理想情况下,列表视图的适配器应该设置在 TextWatcher 之外的某个地方。然后在您的 onTextChanged() 代码中,您应该执行 adpater.notifyDataSetChanged(); 在您 运行 过滤列表视图的代码之后更新列表视图,这应该在 onTextChanged() 内部而不是在适配器中完成。
我有一个视图,其中我将单个 EditText 和屏幕分成两部分(2 个 ListView)。我想将数据输入到 EditText 并使用此数据以不同的方式更新两个 ListView。例如,对于第一个 ListView,以我的输入开头的单词。到第二个 ListView 去包含我输入的单词。
我制作了两个不同的自定义 ListAdapter 来实现所需的功能。然后我将它们添加到我的 EditText 对象中,错误就开始了。如果我只使用一个适配器,一切正常。
那么我如何将两个适配器用于单个 EditText 以不同的方式更新 2 个 ListView。
这是我的代码。
ListView lv;
ListView lv2;
ArrayAdapter<String> adapterForSearch;
ArrayAdapter<String> adapterForTurkishSearch;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.dictionary_screen);
mContext = this;
List<Map<String,?>> dictionaryTopics = new LinkedList<>();
dictionaryTopics.add(createItem("Я ТЫ МЫ ВЫ", formWordCouplesSet(words.getMeU())));
dictionaryTopics.add(createItem("Animals", formWordCouplesSet(words.getAnimals())));
// create our list and custom adapter
SeparatedListAdapter adapter = new SeparatedListAdapter(this);
adapter.addSection("Turkish Dictionary", new SimpleAdapter(this, dictionaryTopics, R.layout.list_complex,
new String[]{ITEM_TITLE, ITEM_CAPTION}, new int[]{R.id.list_complex_title, R.id.list_complex_caption}));
list = (ListView) findViewById(R.id.dictionary_topics);
list.setAdapter(adapter);
list.setClickable(true);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
for(int index=0; index<((ViewGroup)view).getChildCount(); ++index) {
View nextChild = ((ViewGroup)view).getChildAt(index);
if (index >0) {
if (checkVisibility(nextChild))
{
nextChild.setVisibility(View.GONE); dimCounter--; checkDimCounter();
}
else {
nextChild.setVisibility(View.VISIBLE); dimCounter++; checkDimCounter();
}
}
}
}
});
//Search Implementation
inputSearch = (EditText) findViewById(R.id.inputSearch);
lv = (ListView) findViewById(R.id.list_view);
lv2 = (ListView) findViewById(R.id.list_view2);
adapterForSearch = new MyAdapter<>(this, R.layout.list_item2, R.id.product_name, wordCombos);
adapterForTurkishSearch = new MyTurkishAdapter<>(this, R.layout.list_item2, R.id.product_name, wordCombos);
TextWatcher watcher1;
watcher1 = new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
if (cs.length() == 0)
{
lv.setAdapter(null);
}
else {
lv.setAdapter(adapterForSearch);
adapterForSearch.getFilter().filter(cs);
}
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}
@Override
public void afterTextChanged(Editable arg0) {
}
};
TextWatcher watcher2;
watcher2 = new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
if (cs.length() == 0)
{
lv2.setAdapter(null);
}
else {
lv2.setAdapter(adapterForTurkishSearch);
adapterForTurkishSearch.getFilter().filter(cs);
}
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}
@Override
public void afterTextChanged(Editable arg0) {
}
};
inputSearch.addTextChangedListener(watcher1);
inputSearch.addTextChangedListener(watcher2);
}
一个 EditText 只允许一个注册的 TextChangedListener,因此最后一个,"watcher2" 将是最终被使用的那个,因为它是最后一组。您应该找到一种方法将两个 onTextChanged() 块中的代码合并到一个 TextWatcher 中,并且只设置那个。 https://developer.android.com/reference/android/widget/TextView.html#addTextChangedListener(android.text.TextWatcher)
您可能还想考虑更改设置适配器的方式,这可能意味着您必须更改自定义适配器中的一些逻辑,但由于您没有 post 它们的代码,我无法判断你肯定。理想情况下,列表视图的适配器应该设置在 TextWatcher 之外的某个地方。然后在您的 onTextChanged() 代码中,您应该执行 adpater.notifyDataSetChanged(); 在您 运行 过滤列表视图的代码之后更新列表视图,这应该在 onTextChanged() 内部而不是在适配器中完成。