我目前正在开发一个Android应用程序,可以从我的网站加载信息或使用存储在SQLite数据库中的信息。我试图在其中实现搜索功能,但我遇到了一个问题。
我的recyclerview中的数据在进行搜索时不会更新。我已经多次在谷歌上查了一下,但我仍然没有找到解决方案。这里有一个聪明人愿意帮助我吗?
MainActivity.java
public class MainActivity extends AppCompatActivity implements DienstAdapter.ListItemClickListener, NavigationView.OnNavigationItemSelectedListener {
private static final String DIENST_URL = "https://mywebsite.com/apps/test/dienstenapi.php";
private RecyclerView recyclerView;
private DienstAdapter adapter;
private List<Dienst> dienstList;
private SQLiteDatabase mDb;
private Cursor cursor;
private SharedPreferences sharedPreferences;
private NavigationView navigationView;
private View headerView;
private TextView gebruikersnaam;
private Resources res;
private SwipeRefreshLayout swiper;
private static Toast mToast = null;
private SearchView searchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = this.getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle(R.string.app_name);
}
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
headerView = navigationView.getHeaderView(0);
gebruikersnaam = headerView.findViewById(R.id.gebruikersnaam);
res = getResources();
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
setupPreferenceGebruikersnaam();
swiper = findViewById(R.id.swiper);
swiper.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
dienstList.clear();
loadDiensten();
}
});
dienstList = new ArrayList<>();
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
DienstDbHelper dbHelper = new DienstDbHelper(this);
mDb = dbHelper.getWritableDatabase();
loadDiensten();
}
@Override
protected void onDestroy() {
sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
super.onDestroy();
}
SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("example_text")){
setupPreferenceGebruikersnaam();
}
}
};
private void loadDienstenOnline() {
String moetInfoOphalen = sharedPreferences.getString("example_list", "1");
if (moetInfoOphalen.equals("1") || moetInfoOphalen.equals("0")) {
StringRequest stringRequest = new StringRequest(Request.Method.GET, DIENST_URL, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONArray diensten = new JSONArray(response);
for (int i = 0; i < diensten.length(); i++) {
JSONObject dienstObject = diensten.getJSONObject(i);
int id = dienstObject.getInt("id");
String naam = dienstObject.getString("naam");
String beschrijving = dienstObject.getString("beschrijving");
String categorie = dienstObject.getString("categorie");
double prijs = dienstObject.getDouble("prijs");
String afbeelding = dienstObject.getString("afbeelding");
dienstList.add(new Dienst(id, naam, beschrijving, categorie, prijs, afbeelding));
}
voegDienstenToeAanDb(mDb, dienstList);
adapter = new DienstAdapter(MainActivity.this, dienstList, MainActivity.this);
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_LONG).show();
}
});
Volley.newRequestQueue(this).add(stringRequest);
} else {
loadDienstenOffline();
Toast.makeText(MainActivity.this, R.string.instelling_blokkeert_ophalen_diensten, Toast.LENGTH_LONG).show();
}
}
private void loadDienstenOffline() {
cursor = getAlleDiensten();
if ((cursor != null) && (cursor.getCount() > 0)) {
omzettenCursorNaarDiensten(cursor);
adapter = new DienstAdapter(MainActivity.this, dienstList, MainActivity.this);
recyclerView.setAdapter(adapter);
} else {
dienstList.add(new Dienst(0, "", "", "", 0, ""));
adapter = new DienstAdapter(MainActivity.this, dienstList, MainActivity.this);
recyclerView.setAdapter(adapter);
recyclerView.setVisibility(View.GONE);
if (mToast != null)
mToast.cancel();
mToast.makeText(this, R.string.internet_werkt_niet, Toast.LENGTH_LONG).show();
}
}
private boolean internetIsBeschikbaar() {
ConnectivityManager cm =(ConnectivityManager) this.getSystemService(CONNECTIVITY_SERVICE);
assert cm != null;
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}
private void loadDiensten() {
recyclerView.setVisibility(View.VISIBLE);
if (internetIsBeschikbaar()) {
loadDienstenOnline();
} else {
loadDienstenOffline();
}
swiper.setRefreshing(false);
}
@Override
public void onListItemClick(String url, String naam) {
Intent intent = new Intent(MainActivity.this, DienstActivity.class);
intent.putExtra(Intent.EXTRA_TEXT, url);
intent.putExtra("DienstNaam", naam);
startActivity(intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
inflater.inflate(R.menu.search_menu, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setSearchableInfo(searchManager != null ? searchManager.getSearchableInfo(getComponentName()) : null);
searchView.setMaxWidth(Integer.MAX_VALUE);
// listening to search query text change
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
// filter recycler view when query submitted
adapter.getFilter().filter(query);
return false;
}
@Override
public boolean onQueryTextChange(String query) {
// filter recycler view when text is changed
adapter.getFilter().filter(query);
return false;
}
});
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
Intent startSettingsActivity = new Intent(this, SettingsActivity.class);
startActivity(startSettingsActivity);
return true;
} else if (id == R.id.action_search) {
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
// Handle the camera action
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
@Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
return;
}
if (!searchView.isIconified()) {
searchView.setIconified(true);
return;
}
super.onBackPressed();
}
private static void voegDienstenToeAanDb(SQLiteDatabase db, List<Dienst> diensten){
if(db == null){
return;
}
List<ContentValues> list = new ArrayList<>();
ContentValues cv;
for (Dienst d : diensten) {
cv = new ContentValues();
cv.put(DienstContract.DienstEntry.COLUMN_NAAM, d.getNaam());
cv.put(DienstContract.DienstEntry.COLUMN_BESCHRIJVING, d.getBeschrijving());
cv.put(DienstContract.DienstEntry.COLUMN_CATEGORIE, d.getCategorie());
cv.put(DienstContract.DienstEntry.COLUMN_PRIJS, d.getPrice());
cv.put(DienstContract.DienstEntry.COLUMN_AFBEELDING, d.getAfbeelding());
list.add(cv);
}
try
{
db.beginTransaction();
//clear the table first
db.delete (DienstContract.DienstEntry.TABLE_NAME,null,null);
//go through the list and add one by one
for(ContentValues c : list){
db.insert(DienstContract.DienstEntry.TABLE_NAME, null, c);
}
db.setTransactionSuccessful();
}
catch (SQLException e) {
//too bad :(
}
finally
{
db.endTransaction();
}
}
private Cursor getAlleDiensten() {
return mDb.query(
DienstContract.DienstEntry.TABLE_NAME,
null,
null,
null,
null,
null,
DienstContract.DienstEntry._ID
);
}
private void omzettenCursorNaarDiensten(Cursor c) {
int teller = 0, id;
String naam, beschrijving, categorie, afbeelding;
double prijs;
while (c.moveToPosition(teller)) {
id = Integer.parseInt(c.getString(c.getColumnIndex(DienstContract.DienstEntry._ID)));
naam = c.getString(c.getColumnIndex(DienstContract.DienstEntry.COLUMN_NAAM));
beschrijving = c.getString(c.getColumnIndex(DienstContract.DienstEntry.COLUMN_BESCHRIJVING));
categorie = c.getString(c.getColumnIndex(DienstContract.DienstEntry.COLUMN_CATEGORIE));
prijs = c.getDouble(c.getColumnIndex(DienstContract.DienstEntry.COLUMN_PRIJS));
afbeelding = c.getString(c.getColumnIndex(DienstContract.DienstEntry.COLUMN_AFBEELDING));
dienstList.add(new Dienst(id, naam, beschrijving, categorie, prijs, afbeelding));
teller++;
}
}
private void setupPreferenceGebruikersnaam() {
String text = String.format(res.getString(R.string.welkomsbericht), sharedPreferences.getString("example_text", "gebruiker"));
gebruikersnaam.setText(text);
}
}
DienstAdapter.java
public class DienstAdapter extends RecyclerView.Adapter<DienstAdapter.DienstViewHolder> implements Filterable {
private Context mContext;
private List<Dienst> dienstList;
private List<Dienst> dienstListFiltered;
private final ListItemClickListener mOnClickListener;
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
dienstListFiltered = dienstList;
} else {
List<Dienst> filteredList = new ArrayList<>();
for (Dienst row : dienstList) {
// name match condition. this might differ depending on your requirement
// here we are looking for name or phone number match
if (row.getNaam().toLowerCase().contains(charString.toLowerCase()) || row.getBeschrijving().contains(charSequence)) {
filteredList.add(row);
}
}
dienstListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = dienstListFiltered;
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
dienstListFiltered = (ArrayList<Dienst>) filterResults.values;
notifyDataSetChanged();
}
};
}
public interface ListItemClickListener {
void onListItemClick(String url, String naam);
}
DienstAdapter(Context mContext, List<Dienst> dienstList, ListItemClickListener listener) {
this.mContext = mContext;
this.dienstList = dienstList;
this.dienstListFiltered = dienstList;
mOnClickListener = listener;
}
@Override
public DienstViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.list_layout, null);
return new DienstViewHolder(view);
}
@Override
public void onBindViewHolder(DienstViewHolder holder, int position) {
Dienst dienst = dienstList.get(position);
holder.tv_naam.setText(dienst.getNaam());
holder.tv_beschrijving.setText(dienst.getBeschrijving());
holder.tv_categorie.setText(String.valueOf(dienst.getCategorie()));
holder.tv_prijs.setText(String.valueOf(dienst.getPrice()));
if (dienst.getPrice() != 0)
holder.tv_prijs.setText(String.format("€ %.2f", dienst.getPrice()));
else
holder.tv_prijs.setText("");
Glide.with(mContext).load(dienst.getAfbeelding()).into(holder.iv_afbeelding);
}
@Override
public int getItemCount() {
return dienstList.size();
}
public class DienstViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView iv_afbeelding;
TextView tv_naam, tv_beschrijving, tv_categorie, tv_prijs;
DienstViewHolder(View itemView) {
super(itemView);
iv_afbeelding = itemView.findViewById(R.id.iv_afbeelding);
tv_naam = itemView.findViewById(R.id.tv_naam);
tv_beschrijving = itemView.findViewById(R.id.tv_beschrijving);
tv_categorie = itemView.findViewById(R.id.tv_categorie);
tv_prijs = itemView.findViewById(R.id.tv_prijs);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
int clickedPosition = getAdapterPosition();
String url = dienstList.get(clickedPosition).getAfbeelding().replace(".png", ".html");
String naam = dienstList.get(clickedPosition).getNaam();
mOnClickListener.onListItemClick(url, naam);
}
}
}
答案 0 :(得分:1)
首先,getItemCount()
和onBindViewHolder()
应使用已过滤的列表dienstListFiltered
。
而您忘记更新FilterResults
的计数。
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
// Filter data ...
// ...
FilterResults filterResults = new FilterResults();
filterResults.values = dienstListFiltered;
filterResults.count = dienstListFiltered.size();
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
dienstListFiltered = (ArrayList<Dienst>) filterResults.values;
notifyDataSetChanged();
}
};
}
答案 1 :(得分:-1)
可以添加
notifyDataSetChanged();
后立即
filteredList.add(row);