将过滤器应用于列表后,TextWatcher 和 ListView 元素的位置出现问题
Problem with TextWatcher and position of ListView element after applying the filter to the list
我正在开发一个 android 应用程序,它显示一个列表视图,其中包含来自 SQL 数据库的数据。
单击列表视图元素后,会打开一个新的 Activity,其中包含有关它的信息。
我已经实施了 Textwatcher
来在列表中进行搜索,并且列表已按预期更新。
问题是,当我单击更新列表的列表元素时,它会打开一个 activity,其中包含旧位置的数据,例如通过单击 Zinn ID:939。它会打开一个新的 Activity 与 Altbach ID:940 数据。
TextWatcher
工作后更新元素位置并将其传递给 onItemClick
方法的最佳方法是什么?或者如何在 TextWatcher
工作后获取更新列表?
提前致谢!
那是我的 class.
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 start, 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, 0, 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
});
我正在开发一个 android 应用程序,它显示一个列表视图,其中包含来自 SQL 数据库的数据。
单击列表视图元素后,会打开一个新的 Activity,其中包含有关它的信息。
我已经实施了 Textwatcher
来在列表中进行搜索,并且列表已按预期更新。
问题是,当我单击更新列表的列表元素时,它会打开一个 activity,其中包含旧位置的数据,例如通过单击 Zinn ID:939。它会打开一个新的 Activity 与 Altbach ID:940 数据。
TextWatcher
工作后更新元素位置并将其传递给 onItemClick
方法的最佳方法是什么?或者如何在 TextWatcher
工作后获取更新列表?
提前致谢!
那是我的 class.
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 start, 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, 0, 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
});