JSON没有正确加载到listview中 - Android

时间:2015-03-03 16:58:46

标签: android arrays json android-listview

我从服务器收到一个类似的JSON数组,

[{"id":"3","name":"Spanish 101","uid":"54f22e5c87cbd3.52439435","did":"fba6a04d1d6375fbdbb102953e984002"},
{"id":"4","name":"Calc","uid":"54f22e5c87cbd3.52439435","did":"fb7f4ba1eae22eb396dc7cbd465a10b4"},
{"id":"5","name":"Stats 250","uid":"54f22e5c87cbd3.52439435","did":"f6adca44250056c17fec56530faee7c9"}]

我想获取此信息并将其放入列表视图

这是我的代码,假设处理此JSON aray并将其放入listview

package com.example.library;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.AsyncTask;

public class FetchDataTask extends AsyncTask<String, Void, String>{
    private final FetchDataListener listener;
    private String msg;

    public FetchDataTask(FetchDataListener listener) {
        this.listener = listener;
    }

    @Override
    protected String doInBackground(String... params) {
        if(params == null) return null;

        // get url from params
        String url = params[0];

        try {
            // create http connection
            HttpClient client = new DefaultHttpClient();
            HttpGet httpget = new HttpGet(url);

            // connect
            HttpResponse response = client.execute(httpget);

            // get response
            HttpEntity entity = response.getEntity();

            if(entity == null) {
                msg = "No response from server";
                return null;
            }

            // get response content and convert it to json string
            InputStream is = entity.getContent();
            return streamToString(is);
        }
        catch(IOException e){
            msg = "No Network Connection";
        }

        return null;
    }

    @Override
    protected void onPostExecute(String sJson) {
        if(sJson == null) {
            if(listener != null) listener.onFetchFailure(msg);
            return;
        }

        try {
            // convert json string to json array
            JSONArray aJson = new JSONArray(sJson);
            // create apps list
            List<Application> apps = new ArrayList<Application>();

            for(int i=0; i<aJson.length(); i++) {
                JSONObject json = aJson.getJSONObject(i);
                Application app = new Application();
                app.setTitle(json.getString("name"));
                // add the app to apps list
                apps.add(app);
            }

            //notify the activity that fetch data has been complete
            if(listener != null) listener.onFetchComplete(apps);
        } catch (JSONException e) {
            msg = "Invalid response";
            if(listener != null) listener.onFetchFailure(msg);
            return;
        }
    }

    /**
     * This function will convert response stream into json string
     * @param is respons string
     * @return json string
     * @throws IOException
     */
    public String streamToString(final InputStream is) throws IOException{
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line = null;

        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
        }
        catch (IOException e) {
            throw e;
        }
        finally {
            try {
                is.close();
            }
            catch (IOException e) {
                throw e;
            }
        }

        return sb.toString();
    }
}

FetchDataListener

package com.example.library;
import java.util.List;

public interface FetchDataListener {
    public void onFetchComplete(List<Application> data);
    public void onFetchFailure(String msg);
}

我目前只是尝试将name放入listview,当我运行此代码时,只会将第一个数组放入listview。因此,只有一个列表项,它的名称为西班牙语101。

为什么其他数组名称不会被放入listview?

应用程序适配器

package com.example.library;
import java.text.NumberFormat;
import java.util.List;

import android.content.Context;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.example.R;

public class ApplicationAdapter extends ArrayAdapter<Application>{
    private List<Application> items;

    public ApplicationAdapter(Context context, List<Application> items) {
        super(context, R.layout.app_custom_list, items);
        this.items = items;
    }

    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;

        if(v == null) {
            LayoutInflater li = LayoutInflater.from(getContext());
            v = li.inflate(R.layout.app_custom_list, null);
        }

        Application app = items.get(position);

        if(app != null) {
            TextView titleText = (TextView)v.findViewById(R.id.titleTxt);

            if(titleText != null) titleText.setText(app.getTitle());

        }

        return v;
    }
}

获取并设置

package com.example.library;

public class Application {
    private String title;

    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
}

包含ListView的MainActivity

package com.example;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.example.R;
import com.example.library.Application;
import com.example.library.ApplicationAdapter;
import com.example.library.DatabaseHandler;
import com.example.library.FetchDataListener;
import com.example.library.FetchDataTask;
import com.example.library.UserFunctions;

import java.util.HashMap;
import java.util.List;

public class MainActivity extends ListActivity implements FetchDataListener {

    private ProgressDialog dialog;
    ProgressDialog  nDialog;
    AlertDialog.Builder dlgAlert;
    ListView listView ;
    TextView tv;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();

        tv = (TextView) findViewById(R.id.tv);
        nDialog  = new ProgressDialog(MainActivity.this);

        //Action bar information
        android.app.ActionBar mActionBar = getActionBar();
        assert mActionBar != null;
        mActionBar.setDisplayShowHomeEnabled(false);
        mActionBar.setDisplayShowTitleEnabled(false);
        LayoutInflater mInflater = LayoutInflater.from(this);
        View mCustomView = mInflater.inflate(R.layout.custom_actionbar, null);

        //FIX THISSSSS TO LOGOUT BUTTON
        RelativeLayout settingButton = (RelativeLayout) mCustomView
                .findViewById(R.id.settingButton);
        settingButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View view) {

                UserFunctions logout = new UserFunctions();
                logout.logoutUser(getApplicationContext());
                Intent startup = new Intent(getApplicationContext(), StartUp.class);
                startup.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(startup);
                finish();
            }
        });

        mActionBar.setCustomView(mCustomView);
        mActionBar.setDisplayShowCustomEnabled(true);

        //End action bar information

    }//End onCreate

    private void initView() {
        // show progress dialog
        DatabaseHandler db = new DatabaseHandler(getApplicationContext());
        HashMap user = new HashMap();
        user = db.getUserDetails();
        String uid = user.get("unique_id").toString();
        dialog = ProgressDialog.show(this, "", "Loading...");

        String url = "www.example.com";
        FetchDataTask task = new FetchDataTask(this);
        task.execute(url);
    }

    @Override
    public void onFetchComplete(List<Application> data) {
        // dismiss the progress dialog
        if(dialog != null)  dialog.dismiss();
        // create new adapter
        ApplicationAdapter adapter = new ApplicationAdapter(this, data);
        // set the adapter to list
        setListAdapter(adapter);
    }

    @Override
    public void onFetchFailure(String msg) {
        // dismiss the progress dialog
        if(dialog != null)  dialog.dismiss();
        // show failure message
        Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
    }

}//End Activity

2 个答案:

答案 0 :(得分:1)

这就是我处理ListView和CustomAdapter

的方式

在活动的onCreate()

        //Photos Model List
        photoList = new ArrayList<Photos>();

        //ListView
        lvGalleryPhotos = (ListView) parentView.findViewById(R.id.lvGalleryPhotos);

        //My CustomAdapter
        pgAdapter = new PhotoGalleryAdapter(photoList, getSherlockActivity());  


        //Setting adapter to GridView
        lvGalleryPhotos.setAdapter(pgAdapter);

        //Parsing JSON
        for(int i=0;i<10;i++){

                    //each result contains details about a image
                    JSONObject result = results.getJSONObject(i);

                    //Real Parsing
                    int width = result.getInt("width");
                    int height = result.getInt("height");
                    String title = result.getString("titleNoFormatting");
                    String url = result.getString("unescapedUrl");
                    //Make it workable so replace \u003d with =
                    String tbUrl = result.getString("tbUrl").replace("\u003d", "=");

                    //Creating photo object and inserting all collected information into it.
                    Photos photo = new Photos();
                    photo.setHeight(height);
                    photo.setWidth(width);
                    photo.setTitle(title);
                    photo.setURL(url);
                    photo.setTbUrl(tbUrl);

                    //Adding each Photo Object to PhotoList
                    photoList.add(photo);

                }       

        //Informing that data has changed
        pgAdapter.notifyDataSetChanged();

我的自定义适配器

    public class PhotoGalleryAdapter extends BaseAdapter {

        ImageLoader mImageLoader;
        List<Photos> photoList;
        Context mContext;
        BlowIt blw;
        LayoutInflater mLInflater;

        public PhotoGalleryAdapter(List<Photos> photoList,Context mContext){
            this.photoList = photoList;
            this.mContext = mContext;
            blw = new BlowIt(mContext);
        }

        @Override
        public int getCount() {
            return photoList.size();
        }

        @Override
        public Object getItem(int position) {

            return photoList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            //Creating layout inflater
            if(mLInflater==null){
                mLInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            }

            //Inflating Layout
            if(convertView==null){
                convertView = mLInflater.inflate(R.layout.gallery_single_photo,parent,false);
            }

            //Getting Object
            final Photos photo = photoList.get(position);

            //Single Image
            NetworkImageView nivGalleryPhoto = (NetworkImageView) convertView.findViewById(R.id.nivGalleryPhoto);
            TextView tvPhotoName = (TextView) convertView.findViewById(R.id.tvPhotoName);
            TextView tvPhotoDesc = (TextView) convertView.findViewById(R.id.tvPhotoDesc);

            final String photoDescr = photo.getHeight()+"x"+photo.getWidth();

            nivGalleryPhoto.setImageUrl(photo.getTbUrl(), mImageLoader);
            tvPhotoName.setText(photo.getTitle());
            tvPhotoDesc.setText(photoDescr);

            convertView.setTag(photo);
            convertView.setId(position);

            //This will trigger when ever the user clicks on a specific image
            convertView.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    //This will prompt automatically context menu
                    v.showContextMenu();

                }
            });





            return convertView;
        }


    }

和布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/llPhotosFragmentRoot"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

       <ListView 
           android:id="@+id/lvGalleryPhotos"
           android:layout_height="wrap_content"
           android:layout_width="match_parent"
           ></ListView>

    </LinearLayout>

和gallery_single_photo.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:padding="10dp"
    android:layout_height="wrap_content" >
    <!-- <com.android.volley.toolbox.NetworkImageView -->
    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/nivGalleryPhoto"   
        android:layout_height="90dp"
        android:scaleType="centerCrop"
        android:layout_width="75dp"
        android:contentDescription="@string/dummy_desc"
        />

    <TextView
        android:id="@+id/tvPhotoName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:textStyle="bold"
        android:layout_alignTop="@+id/nivGalleryPhoto"
        android:layout_marginLeft="5dp"
        android:layout_toRightOf="@+id/nivGalleryPhoto"
        android:text="Large Text"/>

    <TextView
        android:id="@+id/tvPhotoDesc"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/tvPhotoName"
        android:layout_below="@+id/tvPhotoName"
        android:text="Medium Text"
        android:textSize="13sp"
        android:textColor="@color/border_black" />

</RelativeLayout>

以上所有代码都可以使用这样的项目生成listView

ListViewSingleItem

答案 1 :(得分:0)

getView(...)中使用ViewHolder设计模式:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    ViewHolder holder;

    if(v == null) {
        LayoutInflater li = LayoutInflater.from(getContext());
        v = li.inflate(R.layout.app_custom_list, null);

        holder = new ViewHolder();
        holder.titleText = (TextView)v.findViewById(R.id.titleTxt);
        v.setTag(holder);
    }
    else
       holder = (ViewHolder) v.getTag()

    Application app = items.get(position);

    if(app != null) {

        if(titleText != null) 
            holder.titleText.setText(app.getTitle());

    }

    return v;
}


static class ViewHolder { 

     TextView titleText;

}