简体   繁体   English

Eclipse Android:JSONAdapter无法更新ListView

[英]Eclipse Android: JSONAdapter not updating ListView

I'm following this tutorial: http://www.raywenderlich.com/56111/make-first-android-app-part-3 我正在关注本教程: 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. 我们正在将Async Http与JSONAdapter一起使用,并尝试在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: 这是我的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: 这是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: 这是row_book.xml,它是列表对象的外观:

<?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. 我希望我们能弄清楚为什么列表没有更新。

In DetailActivity.Java you need to declare variable like this 在DetailActivity.Java中,您需要像这样声明变量

 TextView myTextView;

Then inside the onCreate method you need to add this 然后在onCreate方法中,您需要添加此

String bookTitle = this.getIntent().getExtras().getString("bookTitle");

Still inside onCreate method you need to check if there is valid bookTitle 仍然在onCreate方法中,您需要检查是否存在有效的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 在activity_detail.xml中,您的xml文件中唯一缺少的是顶部的“ android:text =“ @ string / textview”“

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. 我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM