我正在使用Android Studio,而我的简单项目(使用API)遇到了问题。我正在尝试借助翻新从TVMazeAPI http://api.tvmaze.com获取图像和文本。这个想法是通过SearchView实现搜索功能。您输入一些标题,该应用会提供来自http://api.tvmaze.com/search/shows?q=girls的一些结果 当我尝试搜索某些节目时,没有显示图片和文字,并且应用程序崩溃了
调试器显示以下内容: 致命异常:主要 流程:com.kate_lebedeva.searchtheshow,PID:3815 java.lang.NullPointerException:尝试在空对象引用上调用接口方法'int java.util.List.size()' 在com.kate_lebedeva.searchtheshow.MovieAdapter.getItemCount(MovieAdapter.java:49)
错误与适配器中的以下行有关:
@Override
public int getItemCount() {
if(movieList != null){
return movieListFiltered.size();
} else {
return 0;
}
}
我无法解决这个问题。我是这个领域的新手。请给我一个建议。
应用gradle
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.github.bumptech.glide:glide:4.3.1'
implementation 'com.android.support:support-v4:28.0.0'
}
android清单
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kate_lebedeva.searchtheshow">
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme">
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</LinearLayout>
item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="wrap_content"
>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="160dp"
android:orientation="horizontal"
android:padding="8dp">
<ImageView
android:id="@+id/image"
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_marginRight="8dp"
android:scaleType="fitXY" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title"
android:textSize="16sp"
android:textStyle="bold"
/>
<TextView
android:id="@+id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:ellipsize="end"
android:maxLines="4"
android:text="summary"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
ApiInterface.java:
import retrofit2.Call;
import retrofit2.http.GET;
public interface ApiInterface {
@GET("search/shows?q=girls")
Call <List<Movie>> getMovies();
}
TvMazeApiClient.java
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class TvMazeApiClient {
public static String BASE_URL ="http://api.tvmaze.com/";
private static Retrofit retrofit;
public static Retrofit getClient(){
if(retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
主要活动:
public class MainActivity extends AppCompatActivity {
private SearchView searchView;
private RecyclerView recyclerView;
private MovieAdapter movieAdapter;
private List<Movie> movieList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
movieAdapter = new MovieAdapter();
recyclerView.setAdapter(movieAdapter);
movieList = new ArrayList<>();
ApiInterface apiService = TvMazeApiClient.getClient().create(ApiInterface.class);
Call<List<Movie>> call = apiService.getMovies();
call.enqueue(new Callback<List<Movie>>() {
@Override
public void onResponse(Call<List<Movie>> call, Response<List<Movie>> response) {
if(movieList != null) {
movieList = response.body();
Log.d("TAG", "Response = " + movieList);
movieAdapter.setMovieList(getApplicationContext(), movieList);
}
else{
Toast.makeText(MainActivity.this,"error", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<List<Movie>> call, Throwable t) {
Log.d("TAG","Response = "+t.toString());
Toast.makeText(MainActivity.this,t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.options_menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search)
.getActionView();
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
movieAdapter.getFilter().filter(query);
return false;
}
@Override
public boolean onQueryTextChange(String query) {
movieAdapter.getFilter().filter(query);
return false;
}
});
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_search) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onBackPressed() {
if (!searchView.isIconified()) {
searchView.setIconified(true);
return;
}
super.onBackPressed();
}}
适配器:
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MyViewHolder> implements Filterable {
private List<Movie> movieList;
private List<Movie> movieListFiltered;
private Context context;
public void setMovieList(Context context,final List<Movie> movieList){
this.context = context;
this.movieList = movieList;
this.movieListFiltered = movieList;
}
@Override
public MovieAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,parent,false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(MovieAdapter.MyViewHolder holder, int position) {
holder.title.setText(movieListFiltered.get(position).getTitle());
Glide.with(context).load(movieList.get(position).getImageUrl()).apply(RequestOptions.centerCropTransform()).into(holder.image);
}
@Override
public int getItemCount() {
if(movieList != null){
return movieListFiltered.size();
} else {
return 0;
}
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
movieListFiltered = movieList;
} else {
List<Movie> filteredList = new ArrayList<>();
for (Movie movie : movieList) {
if (movie.getTitle().toLowerCase().contains(charString.toLowerCase())) {
filteredList.add(movie);
}
}
movieListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = movieListFiltered;
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
movieListFiltered = (ArrayList<Movie>) filterResults.values;
notifyDataSetChanged();
}
};
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView title;
ImageView image;
public MyViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.title);
image = (ImageView)view.findViewById(R.id.image);
}
}
}
Movie.java
public class Movie {
private String title;
private String imageUrl;
public Movie(String title, String imageUrl) {
this.title = title;
this.imageUrl = imageUrl;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
}
答案 0 :(得分:0)
您应该添加对movieListFiltered的检查
if(movieList != null && movieListFiltered!=null){
return movieListFiltered.size();
}