![](/img/trans.png)
[英]Align Bitmap Image inside ImageView - CS50 Pokedex Android
[英]CS50 Android Track Filter will not run in device despite building without errors
我正在尝试在 Pokedex 应用程序中实现过滤器 function,尽管应用程序“构建”没有任何错误,但当我 go 在虚拟 ZE84E30B9390CDB64DB6DB2C9AB87846 中运行它时,请停止在虚拟 ZE84E30B9390CDB64DB6DB2C9AB87846 . 由于我的代码构建正确,我无法真正弄清楚为什么它会继续在虚拟设备上崩溃。 任何帮助将不胜感激!
这是我的 PokedexAdapter.java 文件,在底部添加了过滤器 function:
package edu.harvard.cs50.pokedex;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;
public class PokedexAdapter extends RecyclerView.Adapter<PokedexAdapter.PokedexViewHolder> implements Filterable {
public static class PokedexViewHolder extends RecyclerView.ViewHolder {
public LinearLayout containerView;
public TextView textView;
PokedexViewHolder(View view) {
super(view);
containerView = view.findViewById(R.id.pokedex_row);
textView = view.findViewById(R.id.pokedex_row_text_view);
containerView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Pokemon current = (Pokemon) containerView.getTag();
Intent intent = new Intent(v.getContext(), PokemonActivity.class);
intent.putExtra("url", current.getUrl());
v.getContext().startActivity(intent);
}
});
}
}
private List<Pokemon> pokemon = new ArrayList<>();
private RequestQueue requestQueue;
PokedexAdapter(Context context) {
requestQueue = Volley.newRequestQueue(context);
loadPokemon();
}
public void loadPokemon() {
String url = "https://pokeapi.co/api/v2/pokemon?limit=151";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
JSONArray results = response.getJSONArray("results");
for (int i = 0; i < results.length(); i++) {
JSONObject result = results.getJSONObject(i);
String name = result.getString("name");
pokemon.add(new Pokemon(
name.substring(0, 1).toUpperCase() + name.substring(1),
result.getString("url")
));
}
notifyDataSetChanged();
} catch (JSONException e) {
Log.e("cs50", "Json error", e);
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("cs50", "Pokemon list error", error);
}
});
requestQueue.add(request);
}
@NonNull
@Override
public PokedexViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.pokedex_row, parent, false);
return new PokedexViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull PokedexViewHolder holder, int position) {
Pokemon current = pokemon.get(position);
holder.textView.setText(current.getName());
holder.containerView.setTag(current);
}
@Override
public int getItemCount() {
return pokemon.size();
}
@Override
public Filter getFilter() {
return new PokemonFilter();
}
private class PokemonFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
// implement your search here!
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
//returns whole list if nothing is entered
results.values = pokemon;
results.count = pokemon.size();
}
else {
List<Pokemon> filteredPokemon = new ArrayList<>();
for (Pokemon name : pokemon) {
if (name.getName().toUpperCase().startsWith(constraint.toString().toUpperCase())) {
filteredPokemon.add(name);
results.values = filteredPokemon; // you need to create this variable!
results.count = filteredPokemon.size();
}
}
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
List<Pokemon> filtered = (List<Pokemon>) results.values;
notifyDataSetChanged();
}
}
}
下面是它在 MainActivity.java 中的实现方式:
package edu.harvard.cs50.pokedex;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.SearchView;
public class MainActivity extends AppCompatActivity implements SearchView.OnQueryTextListener {
private RecyclerView recyclerView;
private PokedexAdapter adapter; //private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recycler_view);
adapter = new PokedexAdapter(getApplicationContext());
layoutManager = new LinearLayoutManager(this);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(layoutManager);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setOnQueryTextListener(this);
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
@Override
public boolean onQueryTextSubmit(String newText) {
adapter.getFilter().filter(newText);
return false;
}
}
@Override
public void onBindViewHolder(@NonNull PokedexViewHolder holder, int position) {
if (filtered.isEmpty()) {
Pokemon current = pokemon.get(position);
holder.textView.setText(current.getName());
holder.containerView.setTag(current);
}else{
Pokemon current = filtered.get(position);
holder.textView.setText(current.getName());
holder.containerView.setTag(current);
}
}
@Override
public int getItemCount() {
if (filtered.isEmpty()) {
return pokemon.size();
}else {
return filtered.size();
}
}
在您的 pokedex 适配器中使用它
我有一个类似的问题,这是由以下原因引起的:
@Override
public int getItemCount() {
return pokemon.size();
}
我相信可能会发生口袋妖怪没有被启动,因此没有返回值(或等于“null”)
我添加了一个 if 语句,如果 pokemon 是 null,它将只返回 0
@Override
public int getItemCount() {
if (pokemon != null) {
return pokemon.size();
} else {
return 0;
}
}
我还将变量名称 pokemon 更改为包含过滤项目的数组列表的变量名称。
问题(可能)在您的进口中。 你有:
import android.widget.SearchView;
在您的 MainActivity 中。 当我将该导入更改为以下内容时:
import androidx.appcompat.widget.SearchView;
一切似乎都奏效了。 如果这不起作用,那么我不知道。
您必须做的另一件事是将 onBindViewHolder 和 getItemCount 中的变量“pokemon”更改为您存储名为“filtered”的过滤数据的变量。
并且必须更改 import android.widget.SearchView; 正如另一个人所说。
cs50 建议使用
@Override
protected void publishResults(CharSequence charSequence, FilterResults results) {
filtered = (List<Pokemon>) results.values;
notifyDataSetChanged();
}
但是,如果您注意到,android studio 会通过以灰色突出显示来提示您filtered
从未使用过。
我一直在研究代码,试图找出问题所在。 代码编译并运行没有任何错误的事实只是意味着过滤已成功执行(老实说,我不是 100% 确定,我只是在猜测)但由于某种原因没有显示搜索结果。
在注意到filtered
后显示为灰色后,我尝试了运气并用pokemon
替换了filtered
,因为发布的原始列表是pokemon
。
我最终得到的是
@Override
protected void publishResults(CharSequence charSequence, FilterResults results) {
pokemon = (List<Pokemon>) results.values;
notifyDataSetChanged();
}
现在一切正常。
我也确实像第二个答案所建议的那样更新了我的导入
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.