0

I receive a JSON array from the server that looks like this,

[{"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"}]

I want to take this information and put it into a listview

This is my code that is suppose to process this JSON aray and put it into a 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);
}

I am currently only trying to place the name into the listview, when I run this code what happens is only the first array gets put into the listview. So there is only one list item and it has the name Spanish 101.

Why aren't the other array names being put into the listview?

Application Adapter

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;
    }
}

Get and Set

package com.example.library;

public class Application {
    private String title;

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

MainActivity that has ListView

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
6
  • Can you provide a part of your code, where you set apps list to adapter? Commented Mar 3, 2015 at 17:04
  • Plus I cannot see you calling getTitle() anywhere in your code. You should post full code to get proper help. Commented Mar 3, 2015 at 17:05
  • All code has been added Commented Mar 3, 2015 at 17:13
  • after this ApplicationAdapter adapter = new ApplicationAdapter(this, data); // set the adapter to list setListAdapter(adapter); call adapter.notifyDataSetChanged(). may be it'l work. Commented Mar 3, 2015 at 17:25
  • @ShifarShifz I tried adapter.notifyDataSetChanged() it did not fix it. Commented Mar 3, 2015 at 17:33

2 Answers 2

1

This is how i deal with ListView and CustomAdapter

in onCreate() of Activity

        //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();

My Custom Adapter

    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;
        }


    }

and the layout

    <?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>

and the 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>

and all the above codes can make a listView with items like this

ListViewSingleItem

Sign up to request clarification or add additional context in comments.

Comments

0

Use ViewHolder design pattern in your getView(...):

@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;

} 

4 Comments

Tried this code, it said convertView was always null.
sorry my mistake, it should be v replace convertView in setTag and getTag, I just modified answer
The code runs but im still only getting the first name
So that could be your List<Application> items problem, try to debug to check how many items in your list, maybe just one

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.