Michael Cabus
Michael Cabus

Reputation: 121

ParseQueryAdapter; using class in Android

I feel like a broken record.

After many attempts, I have failed at getting a listview through Parse data to display a specific set of information.

Here is my model...this is all data from users:

@ParseClassName("Midwifefirm")
public class Midwifefirm extends ParseObject {



    public Midwifefirm() {
        // A default constructor is required.
    }

    //practice name
    public String getPracticeName() {
        return getString("practicename");
    }

    public void setPracticeName(String practicename) {
        put("practicename", practicename);
    }

    //education

    public String getEducation() {
        return getString("education");
    }

    public void setEducation(String education) {
        put("education", education);
    }

    //years in practice

    public String getYearsinPractice() {
        return getString("yearsinpractice");
    }

    public void setYearsinPractice(String yearsinpractice) {
        put("yearsinpractice", yearsinpractice);
    }

    //practice philosophy

    public String getPracticePhilosophy() {
        return getString("practicephilosophy");
    }

    public void setPracticePhilosophy(String practicephilosophy) {
        put("practicephilosophy", practicephilosophy);
    }

I have this adapter; I am wondering what to place in the query section, as I just want to pull the data into the ListView that is defined in the data model:

public class CustomMidwifeAdapter extends ParseQueryAdapter<Midwifefirm> {

    public CustomMidwifeAdapter(Context context) {
        super(context, new ParseQueryAdapter.QueryFactory<Midwifefirm>() {
            public ParseQuery<Midwifefirm> create() {
                // Here we can configure a ParseQuery to display
                // only top-rated meals.
                ParseQuery query = new ParseQuery("Midwives");

                return query;
            }
        });
    }


            @Override
            public View getItemView(Midwifefirm midwifefirm, View view, ViewGroup parent) {

                if (view == null) {
                    view = View.inflate(getContext(), R.layout.activity_midwife_result_list, null);

                }

                //use midwifefirm as item view/list

                super.getItemView(midwifefirm, view, parent);


                // find in layout the practice name
                TextView titleTextView = (TextView) view.findViewById(R.id.practicename);

                //in the midwifefirm data model, call getPracticename
                titleTextView.setText(midwifefirm.getString("practicename"));

                // Add education view
                TextView EducationView = (TextView) view.findViewById(R.id.education);

                EducationView.setText(midwifefirm.getString("education"));

                // Add yearsexperience view
                TextView ExperienceView = (TextView) view.findViewById(R.id.yearsinpractice);
                ExperienceView.setText(midwifefirm.getString("yearsinpractice"));

                //Add practice philosophy view
                TextView PracticePhilosophyView = (TextView) view.findViewById(R.id.practicephilosophy);
                PracticePhilosophyView.setText(midwifefirm.getString("practicephilosophy"));


                return view;
            }
}

And here is the Main Activity:

public class MidwifeResultList extends ListActivity {


    private ParseQueryAdapter<ParseObject> mainAdapter;

    private CustomMidwifeAdapter midwifeListAdapter;





    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        //initialize main ParseQueryAdapter
        mainAdapter = new ParseQueryAdapter<ParseObject>(this, Midwifefirm.class);

        //which keys in Midwife object
        mainAdapter.setTextKey("practicename");
        mainAdapter.setTextKey("education");
        mainAdapter.setTextKey("yearsinpractice");
        mainAdapter.setTextKey("practicephilosophy");


        // Initialize the subclass of ParseQueryAdapter
        midwifeListAdapter = new CustomMidwifeAdapter(this);


        // Default view is all meals
        setListAdapter(mainAdapter);



    }

Every time I run this, I get no results.

Thanks in advance for any help

Michael

Upvotes: 0

Views: 531

Answers (2)

async
async

Reputation: 1537

I can tell you why I think it fails now and I can tell you why I'm very sure it will fail after you sort out the current issue.

It seems that you're trying to use different classes

@ParseClassName("Midwifefirm")
public class Midwifefirm extends ParseObject {

and

ParseQuery query = new ParseQuery("Midwives");

You need to be consistent and use the same name. Either use Midwives or Midwifefirm for both. Let's assume you picked the latter. You're also saying

all that is stored in the user table...wasn't sure if I needed to create new tables.

The query above wants to get all entries of type Midwives. If there's no such type, it'll return nothing. So you have two options:

  1. In you Parse dashboard, reate a class Midwifefirm (don't forget to update the String inside @ParseClassName above) and store your Midwifefirm data in there. You don't need to change your query for this.
  2. Add a column to your ParseUser class, such as type, that you can set to Midwifefirm or whatever if that user is a Midwifefirm or whatever. Then in your query you need to add:

    ParseQuery query = new ParseQuery("Midwives");
    query.whereEquals("type", "Midwifefirm");
    

I greatly prefer the former.

Anyway, once your done that, the issue is that you're not using a custom view for this. You're relying on the one provided by Android by default for ListActivity. I am fairly sure it doesn't have any of the fields you're after, so you should create a custom view for this, then at the top of onCreate in your Activity make sure you use it

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.my_custom_view);

By the way, the following are redundant if you populate then in getItemView anyway:

mainAdapter.setTextKey("practicename");
mainAdapter.setTextKey("education");
mainAdapter.setTextKey("yearsinpractice");
mainAdapter.setTextKey("practicephilosophy");

One final advice: if you're still having issues, set breakpoints and do some investigations first. What you need to check is:

  1. Whether you get anything at all from Parse when you do your query. Your adapter has an useful addOnQueryLoadListener that you may use to check whether anything's been retrieved at all.
  2. If stuff is retrieved successfully, you need to check whether the list view is populated correctly. Again, use breakpoints, this time in getItemView maybe.

Upvotes: 1

Bart de Ruijter
Bart de Ruijter

Reputation: 952

I'm going to do a wild guess here using the lovely brainwrecking API help of Parse.com about ParseQueryAdapters

Before continuing, may I mind you that my experience with ParseQueryAdapters is a minimum but I think I have a basic knowledge about them + I have some experience with Parse on its own. ANYHOW,

As an example they use both these

final ParseQueryAdapter adapter = new ParseQueryAdapter(this, "Midwives");
adapter.setTextKey("name");

ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);

and

// Instantiate a QueryFactory to define the ParseQuery to be used for fetching items in this
 // Adapter.
 ParseQueryAdapter.QueryFactory<ParseObject> factory =
     new ParseQueryAdapter.QueryFactory<ParseObject>() {
       public ParseQuery create() {
         ParseQuery query = new ParseQuery("Midwives");
         return query;
       }
     };

 // Pass the factory into the ParseQueryAdapter's constructor.
 ParseQueryAdapter<ParseObject> adapter = new ParseQueryAdapter<ParseObject>(this, factory);
 adapter.setTextKey("name");

 // Perhaps set a callback to be fired upon successful loading of a new set of ParseObjects.
 adapter.addOnQueryLoadListener(new OnQueryLoadListener<ParseObject>() {
   public void onLoading() {
     // Trigger any "loading" UI
   }

   public void onLoaded(List<ParseObject> objects, ParseException e) {
     // Execute any post-loading logic, hide "loading" UI
   }
 });

 // Attach it to your ListView, as in the example above
 ListView listView = (ListView) findViewById(R.id.listview);
 listView.setAdapter(adapter);

To start of, the reason why I think nothing is loading inside your list has to do with a little mixup between the initilization of your ParseQueryAdapter and your custom adapter.

You configure the basic adapter, and also initialize a custom adapter but you don't do anything with the custom adapter, tho the custom adapter seems to contain the logics to load your data model.

I think what you're looking for is something like this:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    //initialize main ParseQueryAdapter
    mainAdapter = new CustomMidwifeAdapter<ParseObject>(this);

    //which keys in Midwife object
    mainAdapter.setTextKey("practicename");
    mainAdapter.setTextKey("education");
    mainAdapter.setTextKey("yearsinpractice");
    mainAdapter.setTextKey("practicephilosophy");

    // Default view is all meals
    setListAdapter(mainAdapter);
}

All you need to pass is the context (aka "this"), and the constructor of your custom class will handle the factory internal

super(context, new ParseQueryAdapter.QueryFactory<Midwifefirm>() {
        public ParseQuery<Midwifefirm> create() {
            // Here we can configure a ParseQuery to display
            // only top-rated meals.
            ParseQuery query = new ParseQuery("Midwives");

            return query;
        }
    });

Tho to be honest since you do:

new ParseQueryAdapter<ParseObject>(this, Midwifefirm.class);

I wonder if you'd need to change your "QueryFactory" to

super(context, new ParseQueryAdapter.QueryFactory<Midwifefirm>() {
            public ParseQuery<Midwifefirm> create() {
                // Here we can configure a ParseQuery to display
                // only top-rated meals.
                ParseQuery query = new ParseQuery(MidWifefirm.class);

                return query;
            }
        });

Where you pass a class to the the query rather than the tableName, but I could be wrong on that one.

Either way I hope this has helped in some way!

Upvotes: 1

Related Questions