Custom ListView Android, no results displayed in ListView - android

Updated code; however I am still getting no results when running the app.
I am using ParseQueryAdapter; I am querying the user, so am using ParseUser; it seems the first part is a query for all users of type midwife, then getting specific types of data I want, setting them to the TextViews
public class CustomMidwifeAdapter extends ParseQueryAdapter<ParseUser> {
public CustomMidwifeAdapter(Context context) {
// Use the QueryFactory to construct a PQA that will only show
// Todos marked as high-pri
super(context, new ParseQueryAdapter.QueryFactory<ParseUser>() {
public ParseQuery create() {
ParseQuery<ParseUser> query = new ParseQuery<ParseUser>("userType");
query.whereEqualTo("userType", "midwife");
query.findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(List<ParseUser> parseUsers, ParseException e) {
if (e == null ) {
//query was successful
}
else {
//Something went wrong
}
}
});
return query;
}
});
}
public View getItemView(ParseUser object, View view, ViewGroup parent) {
if (view == null) {
view = View.inflate(getContext(), R.layout.activity_midwife_result_list, null);
}
super.getItemView(object, view, parent);
// Add the practicename view
TextView titleTextView = (TextView) view.findViewById(R.id.practicename);
titleTextView.setText(object.getString("practicename"));
// Add education view
TextView EducationView = (TextView) view.findViewById(R.id.education);
EducationView.setText(object.getString("education"));
// Add yearsexperience view
TextView ExperienceView = (TextView) view.findViewById(R.id.yearsinpractice);
ExperienceView.setText(object.getString("yearsinpractice"));
//Add practice philosophy view
TextView PracticePhilosophyView = (TextView) view.findViewById(R.id.practicephilosophy);
PracticePhilosophyView.setText(object.getString("practicephilosophy"));
return view;
}
}
Here is the activity
public class MidwifeResultList extends Activity {
private ParseQueryAdapter<ParseObject> mainAdapter;
private CustomMidwifeAdapter midwifeListAdapter;
private ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_list)
//initialize main ParseQueryAdapter
mainAdapter = new ParseQueryAdapter<ParseObject>(this, "userType");
mainAdapter.setTextKey("practicename");
mainAdapter.setTextKey("education");
mainAdapter.setTextKey("yearsinpractice");
mainAdapter.setTextKey("practicephilosophy");
// Initialize the subclass of ParseQueryAdapter
midwifeListAdapter = new CustomMidwifeAdapter(this);
// Initialize ListView and set initial view to mainAdapter
listView = (ListView) findViewById(R.id.lvMidwives);
listView.setAdapter(mainAdapter);
mainAdapter.loadObjects();
}
I've checked my listview, and the id's seem to be correct. This is based on this example: https://parse.com/tutorials/parse-query-adapter

Related

Combine Activity and fragment into a class android

I want to ask,
I have 2 classes:
1. an activity class (to get data from json)
2. a fragment class (not to do something)
and I want to get data from json of activity via fragment class.
Can be combine Activity and Fragment in a class ? and how to do ?
I combined activity and fragment in a Fragment class, I have used a GridView to get data and display
JSON, execute the AsyncTask in the this Fragment
This is my code after updated 25/10:
public class FeedBackFragment extends Fragment {
ProgressDialog pDialog;
JSONParser jsonParser = new JSONParser();
MyAdapter adapter;
JSONArray manufacturers = null;
// manufacturers JSON url
private static final String URL_MANUFACTURERS ="MYURL";
public FeedBackFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.feedback_gridview_manufacturer, container, false);
GridView gridView = (GridView) view.findViewById(R.id.gridview);
gridView.setAdapter(new MyAdapter(getActivity(), manufacturersList));
gridView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3) {
// on selecting a single manufacturer
// CategoryCarActivity will be launched to show category car inside the manufacturer
Intent i = new Intent(getActivity(), CategoryCarActivity.class);
// send manufacturer id to activity to get list of cars under that manufacturer
String manufacturer_id = ((TextView) view.findViewById(R.id.manufacturer_id)).getText().toString();
i.putExtra("manufacturer_id", manufacturer_id);
startActivity(i);
}
});
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
// manufacturersList = new ArrayList<>();
new LoadAllManufacturers().execute();
}
class LoadAllManufacturers extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* After completing background task Dismiss the progress dialog
* **/
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
adapter.notifyDataSetChanged();
// dismiss the dialog after getting all manufacturers
if (pDialog.isShowing())
pDialog.dismiss();
}
}
private class MyAdapter extends BaseAdapter
{
// List<POJOManufacturer> listData = null;
LayoutInflater inflater;
Context context;
public MyAdapter(Context context, ArrayList<HashMap<String, String>> arrayList)
{
// this.context = context;
this.manufacturersList = arrayList;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
if (manufacturersList != null)
return manufacturersList.size();
return 0;
}
#Override
public Object getItem(int i)
{
if (manufacturersList != null)
return manufacturersList.get(i);
return null;
}
#Override
public long getItemId(int i)
{
if (manufacturersList != null)
return manufacturersList.get(i).hashCode();
return 0;
}
#Override
public View getView(int i, View convertView, ViewGroup viewGroup)
{
ViewHolder holder;
if (convertView == null)
{
convertView = inflater.inflate(R.layout.gridview_item, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.text);
holder.iconName = (ImageView) convertView.findViewById(R.id.picture);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.name.setText(this.manufacturersList.get(i).getClass().getName());
// holder.iconName.setImageResource(this.manufacturersList.get(i).image);
return convertView;
}
public class ViewHolder
{
TextView name;
ImageView iconName;
}
}
}
I have updated and added: manufacturerList = new ArrayList<>. everything seem is better, and it happen some issues in getView() method,
I have try and it's only display with 7 empty items in gridview, and not display content and image
So How fill data from Adapter into Gridview?
constructor ManufacturerFragment in class ManufacturerFragment cannot be applied to given types;
gridView.setAdapter() takes an adapter, not a Fragment
And new ManufacturerFragment() doesn't accept an Context.
I am not really sure why you think you need to create a new ManufacturerFragment within the Fragment class you already are in. Did you mean to do gridView.setAdapter(new MyAdapter(getActivity()))?
Also, your manufacturersList needs to be loaded into that adapter, so you'll need to figure that out.
And you need to use getActivity() instead of getActivity().getApplicationContext() in most places.
Then, you should only call new LoadAllManufacturers().execute(); in either onCreateView or onActivityCreated, not both. Otherwise, you're running two AsyncTasks.
Then, onPostExecute already runs on the UI thread, no need to use getActivity().runOnUiThread(new Runnable() {...
Once you do figure out how to put that ArrayList into the Adapter class, you'll want to call adapter.notifyDataSetChanged() within onPostExecute to tell the adapter to refresh the data, thereby updating the GridView to display the data.

How to add multiple items in Listview Android

I'm working on an Android application of booking medicine offline. I have used ListView for Cart, but whenever I add a new item in cart, my previous item get replaced.
L1 = imageacidity
L2 = imagecough
if(msg.toString().equals("L1")) {
adapter = new ContactImageAdapter(this, R.layout.list, imageacidity);
ListView dataList = (ListView) findViewById(R.id.list);
dataList.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
if(msg.toString().equals("L2"))
{
adapter = new ContactImageAdapter(this, R.layout.list, imagecough);
ListView dataList = (ListView) findViewById(R.id.list);
dataList.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
Here I have 5 elements in imageacidity and Imagecough Array. Whenever I select 1 item, it gets added in cart, but when I try to select another item it get replaced with new one.
You have to Add the element inside your adapter.
I will post a custom Adapter and show you how to add elements properly.
Adapter:
public class YourAdapter extends BaseAdapter {
List<String> itens;
private Context mContext;
private static LayoutInflater inflater = null;
public YourAdapter(Context context, List<String> itens){
this.itens = itens;
mContext = context;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return itens.size();
}
public String getItem(int position) {
return itens.get(position);
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.list_row, parent, false);
String msg = itens.get(position);
TextView tx = vi.findViewById(R.id.your_id);
tx.setText(msg);
return vi;
}
public void addItem(String item){
itens.add(item);
}
public void addItens(List<String> itens){
this.itens.addAll(itens);
}
}
ListView:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new CustomAdapter(this,yourListOfItens);
listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
}
You can set initial data on constructor of adapter, or use methods addItem and addAll on a click button for example.
The problem you are describing of the data being removed is happening because making a new ContactImageAdapter and calling setAdapter, which will completely remove the data that was already in the ListView.
If you want to properly implement the code in the question, you need something like this.
String msg = ""; // TODO: get this String value
ListView dataList = (ListView) findViewById(R.id.list);
// TODO: Define a single List to store the data and use that in *one* adapter
List<Contact> contacts = new ArrayList<Contact>();
adapter = new ContactImageAdapter(this, R.layout.list, contacts);
dataList.setAdapter(adapter);
// TODO: Replace this with the object to add to the adapter
Contact contact = null;
if(msg.equals("L1")) {
// TODO: Use whatever values you want for "L1"
int img = R.drawable.bati_acidity_1;
String name = "Amlapitta";
String price = "price 170";
contact = new Contact(img, name, price);
}
else if(msg.equals("L2")) {
// TODO: Use whatever values you want for "L2"
int img = R.drawable.bati_acidity_2;
String name = "Amlapitta2";
String price = "price 270";
contact = new Contact(img, name, price);
}
if (contact != null) {
contacts.add(contact);
adapter.notifyDataSetChanged();
}
Another problem is that you are calling notifyDataSetChanged without actually changing the datasets of imageacidity or imagecough.
You can use an algorithm (logic) on the InputListAdapter checking and verifying if there is a MedicineVO (Value Object Pattern) item on old list before the calling notyChange(..) method. In addition, you can wrapping the logic in other class such as MedicineLogic to improve the adapter readability.
See the sample code below:
public class MedicineInputListAdapter extends ArrayAdapter<MedicineVo> {
public static final int[] COLORS = new int[] { Color.WHITE, Color.BLUE };
private Context mContext;
private List<MedicineVo> medicineVos;
private MedicineVo medicineVoActual;
public BasePreOSPreventivaCorretivaInputListAdapter(Context context, int resource, List<MedicineVo> medicineVos) {
super(context, resource, medicineVos);
this.medicineVoActual = new MedicineVo();
this.medicineVos = new ArrayList<MedicineVo>();
this.medicineVos.addAll(medicineVos);
this.mContext = context;
}
private static class ViewHolder {
TextView mMedicineTextView;
//------------------------------------------------------
// others Android view components
//------------------------------------------------------
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null) {
//------------------------------------------------------
// mapper from xml to view and add itens to holder
//------------------------------------------------------
//------------------------------------------------------
// add event action to the mMedicineTextView
//------------------------------------------------------
viewHolder.mMedicineTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
TextView textView = (TextView) view;
MedicineVo medicineVo = (MedicineVo) textView.getTag();
boolean selected = medicineVo.getSelected();
if (selected) {
/*do it*/
}
refreshPreOSMaterialWhenUpdate(preOSMaterialVo);
}
});
convertView.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
//------------------------------------------------------
// get item and adjust color
//------------------------------------------------------
MedicineVo item = getItem(position);
/*do it*/
return convertView;
}
public void refreshMedicineListWhenUpdate(MedicineVo medicineVo){
List<MedicineVo> newMedicineVos = new ArrayList<MedicineVo>();
for (MedicineVo medicineVoOnList : medicineVos) {
if( StringUtils.isNull(medicineVoOnList.getId()) )
continue;
if( MedicineLogic.existsOnList(medicineVos, medicineVoOnList) )
continue;
/* others checks if necessary */
newMedicineVos.add(medicineVoOnList);
}
medicineVos.addAll(newMedicineVos);
}
}
If you can't select more but only one item of your ListView, this might help.As others have commented on the question, changing the adapter of a ListView can clear the selection too, but as I supposed the code you've posted is inside onCreate (or other kind of initialization) so setting the adapter there won't affect the selection (since there can't be selection without items... :) )

Parse.com Error: "This query has an outstanding network connection. You have to wait until it's done."

I am struggling with a very weird Parse (Parse.com) problem:
When I use the usual list.setAdapter(Adapter);, I get the Error: "This query has an outstanding network connection. You have to wait until it's done."
Here is my code:
private ParseQueryAdapter<ParseObject> Adapter;
private CommentListAdapter CommentListAdapter;
Adapter = new ParseQueryAdapter<ParseObject>(this, "Activity");
Adapter.setTextKey("title");
// Initialize the subclass of ParseQueryAdapter
CommentListAdapter = new CommentListAdapter(this);
// Initialize ListView and set initial view to Adapter
CommentList.setAdapter(Adapter);
Adapter.loadObjects();
if (CommentList.getAdapter() == Adapter) {
CommentList.setAdapter(CommentListAdapter);
CommentListAdapter.loadObjects();
}else{
CommentList.setAdapter(Adapter);
Adapter.loadObjects();
}
I get the error at "CommentList.setAdapter(Adapter);"
Here is my Adapter:
public class CommentListAdapter extends ParseQueryAdapter<ParseObject> {
private List<String> itemList;
private Context context;
public ParseImageView thumbnailFile;
public TextView UsernameView;
public TextView Comments;
public CommentListAdapter(Context context) {
// Use the QueryFactory to construct a PQA that will only show
// Todos marked as high-pri
super(context, new ParseQueryAdapter.QueryFactory<ParseObject>() {
public ParseQuery create() {
ParseQuery query = new ParseQuery("Activity");
query.whereEqualTo("photoId", CommentActivity.getPhoto());
query.whereEqualTo("type", "comment");
query.orderByAscending("created_at");
Log.e("Log", "Query: " + query.countInBackground().toString());
return query;
}
});
}
// Customize the layout by overriding getItemView
#Override
public View getItemView(ParseObject object, View v, ViewGroup parent) {
if (v == null) {
v = View.inflate(getContext(), R.layout.comment_list_items, null);
}
super.getItemView(object, v, parent);
Log.e("Log", "Comment: " + object.toString());
thumbnailFile = (ParseImageView) v.findViewById(R.id.user_thumbnail);
UsernameView = (TextView) v.findViewById(R.id.user_name);
Comments = (TextView) v.findViewById(R.id.comment);
String Content = object.toString();
Comments.setText(Content);
return v;
}
}
Please help me, this kind of error should occur in such a case, I don't know what to do..
If you need more of my code, just tell me.

Android How to implement AsyncTask in my custom Listview

When I ran my code I always get a log about Skipped 303 frames! The application may be doing too much work on its main thread. How to implement AsyncTask in this code below, and how to show a progressbar, while fetching data from one of my Parse.com's database. I would appreciate any help.
Here is my Activity's code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_doctors_name_list);
Bundle extras = getIntent().getExtras();
final String key = extras.getString("KEY");
ListView lvDoctorsName = (ListView) findViewById(R.id.lvDoctorsName);
ParseQueryAdapter.QueryFactory<ParseObject> factory = new ParseQueryAdapter.QueryFactory<ParseObject>() {
public ParseQuery create() {
ParseQuery query = new ParseQuery("doctors");
query.whereContains("name", key);
return query;
}
};
CustomLayout urgentAdapter = new CustomLayout(this, factory);
lvDoctorsName.setAdapter(urgentAdapter);
TextView empty = (TextView) findViewById(R.id.empty_list_item);
lvDoctorsName.setEmptyView(empty);
itemClickListener();
}
public void itemClickListener() {
ListView lvDoctorsName = (ListView) findViewById(R.id.lvDoctorsName);
lvDoctorsName.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ParseObject item = (ParseObject) parent.getAdapter().getItem(position);
String objectID = item.getObjectId().toString();
Intent i = new Intent();
i.setClass(getApplicationContext(), DoctorPage.class);
//i.putExtra("new_variable_name",value);
i.putExtra("objectID", objectID);
startActivity(i);
}
});
}
And here my custom layout:
public class CustomLayout extends ParseQueryAdapter<ParseObject> {
public CustomLayout(Context context, QueryFactory<ParseObject> queryFactory) {
super(context, queryFactory);
}
#Override
public View getItemView(ParseObject object, View v, ViewGroup parent) {
if (v == null) {
v = View.inflate(getContext(), R.layout.row, null);
}
super.getItemView(object, v, parent);
TextView titleTextView = (TextView) v.findViewById(R.id.text1);
titleTextView.setText(object.getString("name"));
TextView titleTextView2 = (TextView) v.findViewById(R.id.text2);
titleTextView2.setText(object.getString("city"));
return v;
}
One problem I see is that you are calling findViewById() every time getItemView() is called; findViewById() is an expensive operation. You should implement something like the ViewHolder pattern to avoid this.
By the looks of the Parse documentation they take care of the AsyncTask for you. So that's not the problem.
Depending on the size of your data set, Emmanuel's answer with findViewById is correct.
To answer how to show a progress bar you can read the documentation on the ParseQueryAdapter, which lets you hook into loading / done loading triggers.
https://parse.com/docs/android/api/com/parse/ParseQueryAdapter.html
// 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
}
});

How to get data from another class using ParseQueryAdapter (Android + Parse)

I'm trying to display the username and a photo in a a list view using the ParseQueryAdapter. I have the classes: User and Post.
I set it up here:
String[] postsObjectIds = some_string_array
ParseQueryAdapter<Post> adapter = new ParseQueryAdapter<Post>(getActivity(), new ParseQueryAdapter.QueryFactory<Post>() {
public ParseQuery<Post> create() {
ParseQuery<Post> query = Post.getQuery();
query.include("User");
query.whereContainedIn("objectId", Arrays.asList(postsObjectIds));
return query;
}
});
adapter.setTextKey("username");
adapter.setImageKey("photo");
adapter.setPlaceholder(getResources().getDrawable(R.drawable.some_drawable));
ListView listView = (ListView) rootView.findViewById(R.id.post_list_view);
listView.setAdapter(adapter);
The Post class has a column called photo and the User class has a column called username. The list view isn't displaying the username.
Do I have to implement a custom adapter?
Is there a quick fix?
I found an answer on the Parse Help Forum:
ParseQueryAdapter setTextKey for relational object
The accepted answer says to use a custom ParseQueryAdapter<T> and Override the getItemView.
For example, in my Fragment's onCreateView method, I initialized the adapter and set it (postsObjectIds is some String[]):
PostViewListViewAdapter adapter = new PostViewListViewAdapter(getActivity(), postsObjectIds);
ListView listView = (ListView) rootView.findViewById(R.id.post_list_view);
listView.setAdapter(adapter);
Here's my adapter (PostViewListViewAdapter):
public class PostViewListViewAdapter extends ParseQueryAdapter<Post> {
private final String[] mPostsObjectIds;
public PostViewListViewAdapter(Context context, final String[] postsObjectIds) {
super(context, new ParseQueryAdapter.QueryFactory<Post>(){
public ParseQuery<Post> create() {
ParseQuery<Post> query = Post.getQuery();
query.include("User");
query.whereContainedIn("objectId", Arrays.asList(postsObjectIds));
return query;
}
});
this.mPostsObjectIds = postsObjectIds;
}
#Override
public View getItemView(Post post, View v, ViewGroup parent) {
if(v == null) {
v = View.inflate(getContext(), R.layout.list_item_post_view, null);
}
super.getItemView(post, v, parent);
final TextView usernameTextView = (TextView) v.findViewById(R.id.username_text_view);
post.getCreator().fetchIfNeededInBackground(new GetCallback<ParseUser>() {
#Override
public void done(ParseUser user, ParseException e) {
usernameTextView.setText(user.getUsername());
}
});
return v;
}
}

Categories

Resources