Reputation: 11
I'm following this tutorial: http://www.raywenderlich.com/56111/make-first-android-app-part-3
We are using Async Http with JSONAdapter and attempting to show book data in ListView.
The problem is that when the "Search" button is clicked, nothing happens. The list doesn't even pop up.
Here is my code for 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());
}
});
}
}
Here is 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();
}
}
And here is row_book.xml which is what the list objects should look like:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="75dp">
<ImageView
android:id="@+id/img_thumbnail"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="25dp"
android:layout_centerVertical="true"
android:scaleType="centerInside"/>
<TextView
android:id="@+id/text_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/img_thumbnail"
android:layout_alignTop="@+id/img_thumbnail"
android:layout_marginLeft="25dp"/>
<TextView
android:id="@+id/text_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/text_title"
android:layout_alignLeft="@+id/text_title"/>
</RelativeLayout>
Thank you. I hope we can figure out why the list is not updating.
Upvotes: 1
Views: 205
Reputation: 21
In DetailActivity.Java you need to declare variable like this
TextView myTextView;
Then inside the onCreate method you need to add this
String bookTitle = this.getIntent().getExtras().getString("bookTitle");
Still inside onCreate method you need to check if there is valid bookTitle
if (bookTitle.length() > 0) {
myTextView = (TextView) findViewById(R.id.text_title);
myTextView.setText(String.valueOf(bookTitle));
}
In activity_detail.xml the only thing that was missing on your xml file is 'android:text="@string/textview"' at the top
Change this to look something like below. Have it in mind that you will need to edit layout position to suits your app.
<TextView
android:text="@string/textview"
android:id="@+id/text_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"/>
The book title should now show up. Follow the same procedure to display the author name. I hope this helps.
Upvotes: 1