如何解决将过滤器应用于列表后,TextWatcher 和 ListView 元素的位置出现问题
我正在开发一个 android 应用程序,该应用程序显示一个列表视图,其中包含来自 sql 数据库的数据。
单击列表视图元素后,将打开一个包含有关它的信息的新活动。
我已经实现了一个 Textwatcher
来在列表中进行搜索,并且列表已更新为它应该可以工作。
问题是,当我单击更新列表的列表元素时,它会打开一个带有旧位置数据的活动,例如单击 Zinn ID:939。它会打开一个带有 Altbach ID:940 数据的新活动。
在 TextWatcher
工作后更新元素位置并将其传递到 onItemClick
方法的最佳方法是什么?或者如何在 TextWatcher
工作后获取更新的列表?
提前致谢!
那是我的课。
public class LibraryActivity extends AppCompatActivity implements View.OnClickListener {
static String db_name = "test_stolpersteine_db.sqlite";
StolpersteineDAO stolpersteinedao;
List<Stolpersteine> stolpersteine_list;
ListView list_view;
private ArrayAdapter<CharSequence> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_library);
////////////////////////////// Database ////////////////////////////////////////////////////
final File dbFile = this.getDatabasePath(db_name); // we create a database path
if (!dbFile.exists()) { // we checking if the directory is existing
try {
copyDatabaseFile(dbFile.getAbsolutePath()); // method to copy the database
} catch (IOException e) {
e.printstacktrace();
}
}
////// Database
startDatabase();
stolpersteine_list = stolpersteinedao.getAllStolpersteine();
list_view = findViewById(R.id.list);
adapter = createAdapterHtml(stolpersteine_list);
list_view.setAdapter(adapter);
////////////////////////////// Database ////////////////////////////////////////////////////
//////////////////////////// Buttons ///////////////////////////////////////////////////////
Button button_home = findViewById(R.id.button_home);
Button button_map = findViewById(R.id.button_map);
Button button_library = findViewById(R.id.button_library);
button_home.setonClickListener(this);
button_map.setonClickListener(this);
button_library.setonClickListener(this);
button_library.setEnabled(false);
/////////////////////////// Buttons ////////////////////////////////////////////////////////
EditText theFilter = findViewById(R.id.edit_text);
theFilter.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence,int start,int count,int after) {
}
@Override
public void onTextChanged(CharSequence charSequence,int before,int count) {
(LibraryActivity.this).adapter.getFilter().filter(charSequence);
}
@Override
public void afterTextChanged(Editable charSequence) {
}
});
//// OnClickListener
list_view.setonItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent,View view,int position,long id) {
String url = stolpersteine_list.get(position).getURL();
Intent i = new Intent(getApplicationContext(),RecordActivity.class);
i.putExtra("url",url);
i.putExtra("first_name",stolpersteine_list.get(position).getFirst_Name());
i.putExtra("name",stolpersteine_list.get(position).getName());
startActivity(i);
} // end of listener
});
} // end of onCreate method
////////////////////////////// Database ////////////////////////////////////////////////////////
private void copyDatabaseFile(String destinationPath) throws IOException {
InputStream assetsDB = this.getAssets().open(db_name);
OutputStream dbOut = new FileOutputStream(destinationPath);
byte[] buffer = new byte[1024];
int length;
while ((length = assetsDB.read(buffer)) > 0) {
dbOut.write(buffer,length);
}
dbOut.flush();
dbOut.close();
} //end of copyDatabaseFile method
private ArrayAdapter<CharSequence> createAdapterHtml(List<Stolpersteine> s_list) {
Spanned[] html_array = new Spanned[s_list.size()];
for (int i = 0; i < s_list.size(); i++) {
html_array[i] = Html.fromHtml(
s_list.get(i).getName()
+ " "
+ "ID: "+ s_list.get(i).getID() + "<br></i>"
+ s_list.get(i).getHouse_Number() +" "
+ s_list.get(i).getHouse_Number_Extension() + "</i>");
}
ArrayAdapter<CharSequence> my_adapter =
new ArrayAdapter<CharSequence>(this,R.layout.list_item,html_array);
return my_adapter;
} // end of createAdapterHtml
private void startDatabase() {
AppDatabase database = Room.databaseBuilder(this,AppDatabase.class,db_name)
.allowMainThreadQueries()
.build();
stolpersteinedao = database.getStolpersteineDAO();
} // end of startDatabase method
////////////////////////////// Database ////////////////////////////////////////////////////////
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_home:
startActivity(new Intent(this,MainActivity.class));
break;
case R.id.button_map:
startActivity(new Intent(this,MapBoxActivity.class));
break;
case R.id.button_library:
startActivity(new Intent(this,LibraryActivity.class));
break;
}
}
} // end of class
解决方法
问题是onItemClick()
回调有过滤列表后的位置参数;即这个位置是相对于过滤列表而不是原始列表,尽管您需要从原始列表中获取实际位置。
要获取原始位置(不是过滤后的位置),您可以先获取过滤后的项目,然后使用原始列表中的 indexOf()
获取其位置。
要应用此设置,请将 list_view
OnItemClickListener
更改为:
//// OnClickListener
list_view.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent,View view,int position,long id) {
// Getting the clicked item from the filtered list
Stolpersteine filteredItem = (Stolpersteine) ((ListView) parent).getAdapter().getItem(position);
// Getting the original position
int originalPos = getList().indexOf(filteredItem);
// Use originalPos instead of position in your code:
String url = stolpersteine_list.get(originalPos).getURL();
Intent i = new Intent(getApplicationContext(),RecordActivity.class);
i.putExtra("url",url);
i.putExtra("first_name",stolpersteine_list.get(originalPos).getFirst_Name());
i.putExtra("name",stolpersteine_list.get(originalPos).getName());
startActivity(i);
} // end of listener
});
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。