Eclipse Android:JSONAdapter 未更新 ListView
Posted
技术标签:
【中文标题】Eclipse Android:JSONAdapter 未更新 ListView【英文标题】:Eclipse Android: JSONAdapter not updating ListView 【发布时间】:2014-12-29 00:40:15 【问题描述】:我正在关注本教程:http://www.raywenderlich.com/56111/make-first-android-app-part-3
我们正在使用带有 JSONAdapter 的 Async Http 并尝试在 ListView 中显示图书数据。
问题是当点击“搜索”按钮时,什么也没有发生。该列表甚至没有弹出。
这是我的 MainActivity.java 代码:
package com.example.newapp;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import org.json.JSONObject;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ShareActionProvider;
import android.widget.TextView;
import android.widget.Toast;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.JsonHttpResponseHandler;
public class MainActivity extends Activity implements View.OnClickListener, OnItemClickListener
TextView mainTextView;
Button mainButton;
EditText mainEditText;
ListView mainListView;
JSONAdapter mJSONAdapter;
ArrayList mNameList = new ArrayList();
ShareActionProvider mShareActionProvider;
private static final String PREFS = "prefs";
private static final String PREF_NAME = "name";
SharedPreferences mSharedPreferences;
private static final String QUERY_URL = "http://openlibrary.org/search.json?q=";
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainEditText = (EditText)findViewById(R.id.main_edittext);
mainTextView = (TextView)findViewById(R.id.main_textview);
mainButton = (Button)findViewById(R.id.main_button);
mainButton.setOnClickListener(this);
mainListView = (ListView)findViewById(R.id.main_listview);
mainListView.setOnItemClickListener(this);
displayWelcome();
// 10. Create a JSONAdapter for the ListView
mJSONAdapter = new JSONAdapter(this, getLayoutInflater());
// Set the ListView to use the ArrayAdapter
mainListView.setAdapter(mJSONAdapter);
@Override
public boolean onCreateOptionsMenu(Menu menu)
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
MenuItem shareItem = menu.findItem(R.id.menu_item_share);
if (shareItem != null)
mShareActionProvider = (ShareActionProvider)shareItem.getActionProvider();
setShareIntent();
return true;
private void setShareIntent()
if (mShareActionProvider != null)
// create an Intent with the contents of the TextView
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Android Development");
shareIntent.putExtra(Intent.EXTRA_TEXT, mainTextView.getText());
// Make sure the provider knows
// it should work with that Intent
mShareActionProvider.setShareIntent(shareIntent);
@Override
public void onClick(View v)
queryBooks(mainEditText.getText().toString());
mainEditText.setText("");
@Override
public void onItemClick(AdapterView parent, View view, int position, long id)
// Log the item's position and contents
// to the console in Debug
public void displayWelcome()
mSharedPreferences = getSharedPreferences(PREFS, MODE_PRIVATE);
String name = mSharedPreferences.getString(PREF_NAME, "");
if (name.length() > 0)
Toast.makeText(this, "Welcome back, " + name + "!", Toast.LENGTH_SHORT).show();
else
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Hello!");
alert.setMessage("What is your name?");
final EditText input = new EditText (this);
alert.setView(input);
alert.setPositiveButton("OK", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int whichButton)
String inputName = input.getText().toString();
SharedPreferences.Editor e = mSharedPreferences.edit();
e.putString(PREF_NAME, inputName);
e.commit();
Toast.makeText(getApplicationContext(), "Welcome, " + inputName + "!",
Toast.LENGTH_LONG).show();
);
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int whichButton)
// TODO Auto-generated method stub
);
alert.show();
private void queryBooks(String searchString)
String urlString = "";
try
urlString = URLEncoder.encode(searchString, "UTF-8");
catch (UnsupportedEncodingException e)
e.printStackTrace();
Toast.makeText(this, "Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
AsyncHttpClient client = new AsyncHttpClient();
client.get(QUERY_URL + urlString, new JsonHttpResponseHandler()
public void onSuccess (JSONObject jsonObject)
//Display a Toast message
//to announce your succcess
Toast.makeText(getApplicationContext(), "Success!", Toast.LENGTH_LONG).show();
mJSONAdapter.updateData(jsonObject.optJSONArray("docs"));
public void onFailure (int statusCode, Throwable throwable, JSONObject error)
Toast.makeText(getApplicationContext(), "Error: " + statusCode + " " +
throwable.getMessage(), Toast.LENGTH_LONG).show();
Log.e("omg android", statusCode + " " + throwable.getMessage());
);
这里是 JSONAdapter.java:
package com.example.newapp;
import org.json.JSONArray;
import org.json.JSONObject;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
public class JSONAdapter extends BaseAdapter
private static final String IMAGE_URL_BASE = "http://covers.openlibrary.org/b/id/";
Context mContext;
LayoutInflater mInflater;
JSONArray mJsonArray;
public JSONAdapter (Context context, LayoutInflater inflater)
mContext = context;
mInflater = inflater;
mJsonArray = new JSONArray();
@Override
public int getCount()
return mJsonArray.length();
@Override
public JSONObject getItem(int position)
return mJsonArray.optJSONObject(position);
@Override
public long getItemId(int position)
// TODO Auto-generated method stub
return position;
@Override
public View getView(int position, View convertView, ViewGroup parent)
ViewHolder holder;
// check if the view already exists
// if so, no need to inflate and findViewById again!
if (convertView == null)
// Inflate the custom row layout from your XML.
convertView = mInflater.inflate(R.layout.row_book, null);
// create a new "Holder" with subviews
holder = new ViewHolder();
holder.thumbnailImageView = (ImageView) convertView.findViewById(R.id.img_thumbnail);
holder.titleTextView = (TextView) convertView.findViewById(R.id.text_title);
holder.authorTextView = (TextView) convertView.findViewById(R.id.text_author);
// hang onto this holder for future recyclage
convertView.setTag(holder);
else
// skip all the expensive inflation/findViewById
// and just get the holder you already made
holder = (ViewHolder) convertView.getTag();
// Get the current book's data in JSON form
JSONObject jsonObject = (JSONObject) getItem(position);
// See if there is a cover ID in the Object
if (jsonObject.has("cover_i"))
// If so, grab the Cover ID out from the object
String imageID = jsonObject.optString("cover_i");
// Construct the image URL (specific to API)
String imageURL = IMAGE_URL_BASE + imageID + "-S.jpg";
// Use Picasso to load the image
// Temporarily have a placeholder in case it's slow to load
Picasso.with(mContext).load(imageURL).placeholder(R.drawable.ic_books).into(holder.thumbnailImageView);
else
// If there is no cover ID in the object, use a placeholder
holder.thumbnailImageView.setImageResource(R.drawable.ic_books);
// Grab the title and author from the JSON
String bookTitle = "";
String authorName = "";
if (jsonObject.has("title"))
bookTitle = jsonObject.optString("title");
if (jsonObject.has("author_name"))
authorName = jsonObject.optJSONArray("author_name").optString(0);
// Send these Strings to the TextViews for display
holder.titleTextView.setText(bookTitle);
holder.authorTextView.setText(authorName);
return convertView;
private static class ViewHolder
public ImageView thumbnailImageView;
public TextView titleTextView;
public TextView authorTextView;
public void updateData(JSONArray jsonArray)
// update the adapter's dataset
mJsonArray = jsonArray;
notifyDataSetChanged();
这里是 row_book.xml,它是列表对象的样子:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_>
<ImageView
android:id="@+id/img_thumbnail"
android:layout_
android:layout_
android:layout_alignParentLeft="true"
android:layout_marginLeft="25dp"
android:layout_centerVertical="true"
android:scaleType="centerInside"/>
<TextView
android:id="@+id/text_title"
android:layout_
android:layout_
android:layout_toRightOf="@+id/img_thumbnail"
android:layout_alignTop="@+id/img_thumbnail"
android:layout_marginLeft="25dp"/>
<TextView
android:id="@+id/text_author"
android:layout_
android:layout_
android:layout_below="@+id/text_title"
android:layout_alignLeft="@+id/text_title"/>
</RelativeLayout>
谢谢。我希望我们能弄清楚为什么列表没有更新。
【问题讨论】:
在“queryBooks”函数中设置一个断点,调试应用程序并查看该函数是否被调用 【参考方案1】:在 DetailActivity.Java 中你需要像这样声明变量
TextView myTextView;
然后在 onCreate 方法里面你需要添加这个
String bookTitle = this.getIntent().getExtras().getString("bookTitle");
仍然在 onCreate 方法中,您需要检查是否有有效的 bookTitle
if (bookTitle.length() > 0)
myTextView = (TextView) findViewById(R.id.text_title);
myTextView.setText(String.valueOf(bookTitle));
在 activity_detail.xml 中,您的 xml 文件中唯一缺少的是 'android:text="@string/textview"' 在顶部
将其更改为如下所示。请记住,您需要编辑布局位置以适合您的应用。
<TextView
android:text="@string/textview"
android:id="@+id/text_title"
android:layout_
android:layout_
android:layout_marginTop="25dp"/>
现在应该会显示书名。按照相同的步骤显示作者姓名。我希望这会有所帮助。
【讨论】:
以上是关于Eclipse Android:JSONAdapter 未更新 ListView的主要内容,如果未能解决你的问题,请参考以下文章