Search code examples
androidarraylistandroid-listviewjsouplistadapter

Trouble implementing a custom list into custom array list into custom array adapter all from jsoup


The title sounds a bit confusing, but I'm parsing information from a website and storing it in arraylist<string>. Once I get ArrayList<String> mPictures = new GetTeachers().execute("div.post_thumb_clean img", "src").get(); to store the results of the asynctask that I'm using, I use ArrayList<Teacher> = mTeachers and mTeachers.add(new Teacher(Splash.mNames, Splash.mEmails, Splash.mPictures)); to implement in my TeacherAdapter. The problem is that whenever I run all of this, only one listitem shows up instead of the 11 or so that were supposed to. I think the problem occurs in my Teacher.class that I use as a listitem. Well, I'm not sure how to phrase all of this since I'm learning on my own and I'm not sure if I have the terminology right, but I'm going to post excerpts from each file necessary below. Thanks! Also, sorry for the crapload of code, feel free to edit the heck out of it.

AsyncTask (GetTeachers.class)

public class GetTeachers extends AsyncTask<String, Void, ArrayList<String>> {

    public static ArrayList<Teacher> mTeachers;
    protected final ArrayList<String> mInfo = new ArrayList<String>();

    @Override
    protected ArrayList<String> doInBackground(String... param) {
        try {
            Document doc = Jsoup.connect("http://www.androidpolice.com/")
                    .timeout(10000).userAgent("Mozilla").get();
            Elements elements = doc.select(param[0]);
            for (Element element : elements) {
                mInfo.add(element.absUrl(param[1]));
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return mInfo;
    }

    @Override
    protected void onPostExecute(ArrayList<String> result) {
        super.onPostExecute(result);
        mTeachers = new ArrayList<Teacher>();
        mTeachers.add(new Teacher(Splash.mNames, Splash.mEmails,
                Splash.mPictures));
    }

}

Teacher.class

public class Teacher {
    String mName, mEmail, mPicture;

    public Teacher() {

    }

    public Teacher(ArrayList<String> n, ArrayList<String> e, ArrayList<String> p) {

        StringBuilder sbn = new StringBuilder();
        for (String mN : n) {
            sbn.append(mN);
            mName = mN;
        }
        StringBuilder sbe = new StringBuilder();
        for (String mE : e) {
            sbe.append(mE);
            mEmail = mE;
        }
        StringBuilder sbp = new StringBuilder();
        for (String mP : p) {
            sbp.append(mP);
            mPicture = mP;
        }
    }

    public String getName() {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }

    public String getEmail() {
        return mEmail;
    }

    public void setEmail(String email) {
        mEmail = email;
    }

    public String getPicture() {
        return mPicture;
    }

    public void setPicture(String picture) {
        mPicture = picture;
    }

}

TeacherAdapter.class:

public class TeacherAdapter extends ArrayAdapter<Teacher> {

    Typeface thin;
    private LayoutInflater mInflater;
    private ArrayList<Teacher> mTeacher;
    private int mViewResourceId;

    public TeacherAdapter(Context ctx, int viewResourceId,
            ArrayList<Teacher> teacher) {
        super(ctx, viewResourceId, teacher);

        mInflater = (LayoutInflater) ctx
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        thin = Typeface.createFromAsset(ctx.getAssets(), "RobotoThin.ttf");
        mViewResourceId = viewResourceId;

        mTeacher = teacher;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        convertView = mInflater.inflate(mViewResourceId, null);
        Teacher teacher = mTeacher.get(position);
        TextView teachername = (TextView) convertView
                .findViewById(R.id.teacher_name);
        TextView teacheremail = (TextView) convertView
                .findViewById(R.id.teacher_email);
        ImageView iv = (ImageView) convertView
                .findViewById(R.id.teacher_picture);

        teachername.setTypeface(thin);
        teacheremail.setTypeface(thin);
        AQuery aq = new AQuery(getContext());
        AQUtility.setDebug(false);

        teachername.setText(teacher.getName());
        teacheremail.setText(teacher.getEmail());
        aq.id(iv).image(teacher.getPicture(), false, true, 64, R.drawable.ic_contact_picture);

        return convertView;
    }
}

Except from Splash.class

    public static ArrayList<String> mNames, mEmails, mPictures = new ArrayList<String>();
        ...
        mPictures = new ArrayList<String>();
        mNames = new GetTeachers().execute("h3 a", "href").get();
        mEmails = new GetTeachers().execute("h3 a", "href").get();
        mPictures = new GetTeachers().execute("div.post_thumb_clean img",
                "src").get();

Solution

  • The problem is in the onPostExecute() method of your AsyncTask.

    mTeachers = new ArrayList<Teacher>();
    mTeachers.add(new Teacher(Splash.mNames, Splash.mEmails,
                Splash.mPictures));
    

    Here, you initialize the mTeachers list, but only add one Teacher object. I am not sure what Splash.mNames, Splash.mEmails and Splash.mPictures are.

    Now, in your adapter's getView() method, Teacher teacher = mTeacher.get(position); works for position zero. Since the size of mTeachers is one, only one item is displayed in your listview.

    Edit 1:

    Let's make some changes to your Adapter. Add the following above Typeface thin;:

    private ArrayList<String> mNames;
    private ArrayList<String> mEmails;
    private ArrayList<String> mPictures;
    

    Next, change the constructor from:

    public TeacherAdapter(Context ctx, int viewResourceId,
            ArrayList<Teacher> teacher)
    

    to:

    public TeacherAdapter(Context ctx, int viewResourceId,
            ArrayList<String> names, ArrayList<String> emails, ArrayList<String> pictures)
    

    This will go inside your constructor:

        super();
    
        mInflater = (LayoutInflater) ctx
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    
        thin = Typeface.createFromAsset(ctx.getAssets(), "RobotoThin.ttf");
        mViewResourceId = viewResourceId;
    
        mNames = names;
        mEmails = emails;
        mPictures = pictures;
    

    Your getView() will have the following:

        convertView = mInflater.inflate(mViewResourceId, null);
    
        TextView teachername = (TextView) convertView
                .findViewById(R.id.teacher_name);
        TextView teacheremail = (TextView) convertView
                .findViewById(R.id.teacher_email);
        ImageView iv = (ImageView) convertView
                .findViewById(R.id.teacher_picture);
    
        teachername.setTypeface(thin);
        teacheremail.setTypeface(thin);
        AQuery aq = new AQuery(getContext());
        AQUtility.setDebug(false);
    
        teachername.setText(mNames.get(position));
        teacheremail.setText(mEmails.get(position));
        aq.id(iv).image(mPictures.get(position), false, true, 64, R.drawable.ic_contact_picture);
    
        return convertView;
    

    Remove these lines from the onPostExecute() method:

        mTeachers = new ArrayList<Teacher>();
        mTeachers.add(new Teacher(Splash.mNames, Splash.mEmails,
                Splash.mPictures));
    

    The purpose if to provide the TeacherAdapter with 3 ArrayList in place of ArrayList. Set your adapter and update it(adapter.notifyDataSetChanged()).