将过滤器应用于列表后,TextWatcher 和 ListView 元素的位置出现问题
Posted
技术标签:
【中文标题】将过滤器应用于列表后,TextWatcher 和 ListView 元素的位置出现问题【英文标题】:Problem with TextWatcher and position of ListView element after applying the filter to the list 【发布时间】:2021-04-18 23:13:21 【问题描述】:我正在开发一个 android 应用程序,它显示一个包含 SQL 数据库数据的列表视图。
单击列表视图元素后,将打开一个包含有关它的信息的新 Activity。
我已经实现了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 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
【问题讨论】:
请提供您如何过滤列表 我使用 Textwatcher 自动过滤列表。我也可以使用带有 getSearchResult 方法的 DAO public interface StolpersteineDAO @Query("SELECT * FROM stolpersteine_table ORDER BY name ASC") public List问题是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
);
【讨论】:
以上是关于将过滤器应用于列表后,TextWatcher 和 ListView 元素的位置出现问题的主要内容,如果未能解决你的问题,请参考以下文章