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的主要内容,如果未能解决你的问题,请参考以下文章

android studio 怎么导入eclipse的文件

android eclipse如何查看耗时

怎样在eclipse中搭建android开发环境

Eclipse - 无法查看 Android Eclipse 插件

android studio 怎么打开eclipse

点击按钮后创建文本字段(Eclipse/Android)