我正在使用纽约时代电影评论API制作电影评论应用,API为我提供了一个字符串" src"使用图片网址,但有些评论会返回null。
我想在API返回null时使用图像资源或矢量声明,但我不知道如何。
MainActivity.java
package br.com.pedro.pedrodaumas;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TextInputEditText;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.inputmethod.InputMethodManager;
import android.widget.ListView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<Movie> movieList = new ArrayList<>();
private MovieArrayAdapter movieArrayAdapter;
private ListView movieListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
movieListView = (ListView) findViewById(R.id.movieListView);
movieArrayAdapter = new MovieArrayAdapter(this, movieList);
movieListView.setAdapter(movieArrayAdapter);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
TextInputEditText search_bar;
search_bar = (TextInputEditText) findViewById(R.id.search_bar);
URL url = createURL(search_bar.getText().toString());
if(url != null){
dismissKeyboard(search_bar);
GetMovieTask getLocalMovieTask = new GetMovieTask();
getLocalMovieTask.execute(url);
}else {
Snackbar.make(findViewById(R.id.coordinatorLayout), R.string.invalid_url,
Snackbar.LENGTH_LONG).show();
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void dismissKeyboard (View view){
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(),0);
}
private URL createURL (String movie){
String apiKey = getString (R.string.api_key);
String baseUrl = getString(R.string.nyt_url);
try{
String urlString = baseUrl + "?api_key=" + apiKey + "&query=" + URLEncoder.encode (movie, "UTF-8");
return new URL(urlString);
}
catch( Exception e){
e.printStackTrace();
}
return null;
}
private class GetMovieTask extends AsyncTask<URL, Void, JSONObject> {
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
protected JSONObject doInBackground(URL... params) {
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) params[0].openConnection();
int response = connection.getResponseCode();
if (response == HttpURLConnection.HTTP_OK){
StringBuilder builder = new StringBuilder ();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))){
String line;
while ((line = reader.readLine()) != null){
builder.append(line);
}
}
catch (IOException e){
Snackbar.make(findViewById(R.id.coordinatorLayout), R.string.read_error, Snackbar.LENGTH_LONG).show();
e.printStackTrace();
}
return new JSONObject(builder.toString());
}
}
catch (Exception e){
Snackbar.make(findViewById(R.id.coordinatorLayout), R.string.connect_error, Snackbar.LENGTH_LONG).show();
e.printStackTrace();
}
finally{
if (connection != null){
connection.disconnect();
}
}
return null;
}
protected void onPostExecute(JSONObject movie) {
convertJSONToArrayList (movie);
movieArrayAdapter.notifyDataSetChanged();
movieListView.smoothScrollToPosition(0);
}
}
private void convertJSONToArrayList (JSONObject forecast){
movieList.clear();
try{
JSONArray results = forecast.getJSONArray("results");
for (int i = 0; i < results.length(); i++) {
JSONObject movie = results.getJSONObject(i);
JSONObject multimedia = movie.getJSONObject("multimedia");
movieList.add(new Movie(movie.getString("display_title"),
movie.getString("publication_date"),
multimedia.getString("src")));
}
}
catch (JSONException e){
e.printStackTrace();
}
}
}
Movie.java
package br.com.pedro.pedrodaumas;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
public class Movie {
public final String title;
public final String publication_date;
public final String iconURL;
public Movie(String title,String publication_date, String iconName) {
this.title = title;
this.publication_date = publication_date;
this.iconURL = iconName;
}
}
MovieArrayAdapter.java
package br.com.pedro.pedrodaumas;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Build;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MovieArrayAdapter extends ArrayAdapter<Movie> {
private static class ViewHolder{
ImageView movieImage;
TextView description;
TextView publication_date;
}
private Map<String, Bitmap> bitmaps = new HashMap<>();
public MovieArrayAdapter (Context context, List<Movie>
forecast){
super (context, -1, forecast);
}
public View getView(int position, View convertView, ViewGroup parent) {
Movie review = getItem (position);
ViewHolder viewHolder;
if (convertView == null){
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.complete_review, parent, false);
viewHolder.movieImage = (ImageView)convertView.findViewById(R.id.movieImage);
viewHolder.description = (TextView)convertView.findViewById(R.id.description);
viewHolder.publication_date = (TextView)convertView.findViewById(R.id.publication_date);
convertView.setTag(viewHolder);
}
else{
viewHolder = (ViewHolder)convertView.getTag();
}
if (bitmaps.containsKey(review.iconURL)){
viewHolder.movieImage.setImageBitmap(bitmaps.get(review.iconURL));
}
else{
new LoadImageTask (viewHolder.movieImage).execute (review.iconURL);
}
Context context = getContext();
viewHolder.description.setText(review.title);
viewHolder.publication_date.setText(review.publication_date);
return convertView;
}
private class LoadImageTask extends AsyncTask<String, Void, Bitmap> {
private ImageView imageView;
public LoadImageTask (ImageView imageView){
this.imageView = imageView;
}
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
protected Bitmap doInBackground(String... params) {
Bitmap bitmap = null;
HttpURLConnection connection = null;
try{
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
try(InputStream inputStream = connection.getInputStream ()){
bitmap = BitmapFactory.decodeStream(inputStream);
bitmaps.put (params[0], bitmap);
}
catch (Exception e){
e.printStackTrace();
}
}
catch (Exception e){
e.printStackTrace();
}
finally{
connection.disconnect();
}
return bitmap;
}
protected void onPostExecute(Bitmap bitmap) {
imageView.setImageBitmap(bitmap);
}
}
}
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="br.com.pedro.pedrodaumas.MainActivity"
android:id="@+id/coordinatorLayout">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay"
android:elevation="@dimen/toolbar_elevation" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|end"
android:layout_marginTop="@dimen/fab_magin_top"
android:layout_marginEnd="@dimen/fab_margin"
android:layout_marginBottom="@dimen/fab_margin"
android:layout_marginStart="@dimen/fab_margin"
app:elevation="@dimen/rested_button_elevation"
android:src="@drawable/ic_action_search" />
</android.support.design.widget.CoordinatorLayout>
Content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="br.com.pedro.pedrodaumas.MainActivity"
tools:showIn="@layout/activity_main"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/view">
<android.support.design.widget.TextInputEditText android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/search_bar"
android:singleLine="true"
android:hint="@string/hint_text"
android:elevation="@dimen/rested_search_elevation"
tools:targetApi="lollipop" />
</android.support.design.widget.TextInputLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="@+id/movieListView"
android:layout_weight="1" />
</LinearLayout>
错误消息
07-31 18:10:46.464 585-1419/? W/audio_hw_primary: out_write() limiting sleep time 65759 to 46439
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: org.json.JSONException: Value null at multimedia of type org.json.JSONObject$1 cannot be converted to JSONObject
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at org.json.JSON.typeMismatch(JSON.java:100)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at org.json.JSONObject.getJSONObject(JSONObject.java:578)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at br.com.pedro.pedrodaumas.MainActivity.convertJSONToArrayList(MainActivity.java:157)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at br.com.pedro.pedrodaumas.MainActivity.access$300(MainActivity.java:34)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at br.com.pedro.pedrodaumas.MainActivity$GetMovieTask.onPostExecute(MainActivity.java:145)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at br.com.pedro.pedrodaumas.MainActivity$GetMovieTask.onPostExecute(MainActivity.java:110)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at android.os.AsyncTask.finish(AsyncTask.java:632)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at android.os.AsyncTask.access$600(AsyncTask.java:177)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at android.os.Looper.loop(Looper.java:136)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5021)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at java.lang.reflect.Method.invokeNative(Native Method)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at java.lang.reflect.Method.invoke(Method.java:515)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
07-31 18:10:46.784 3083-3083/br.com.pedro.pedrodaumas W/System.err: at dalvik.system.NativeStart.main(Native Method)
07-31 18:10:46.824 3083-3083/br.com.pedro.pedrodaumas D/android.widget.GridLayout: horizontal constraints: x2-x0>=1120, x1-x0>=80, x2-x0<=219 are inconsistent; permanently removing: x2-x0<=219.
07-31 18:10:47.114 3083-3109/br.com.pedro.pedrodaumas D/dalvikvm: GC_FOR_ALLOC freed 499K, 19% free 3670K/4488K, paused 0ms, total 0ms
答案 0 :(得分:0)
感谢cricket_007我能够通过添加
来解决我的问题if(movie.isNull("multimedia")){
movieList.add(new Movie(movie.getString("display_title"),
movie.getString("publication_date"),
"image", movie.getString("summary_short")));
到我的
convertJSONToArrayList
并添加
if(review.iconURL == "image"){
viewHolder.movieImage.setImageResource(R.drawable.ic_import_contacts_white_24dp);
}
在
if (bitmaps.containsKey(review.iconURL)){
viewHolder.movieImage.setImageBitmap(bitmaps.get(review.iconURL));
}
在MovieArrayAdapter上