I'm new to android programming so you'll need to bear with me.
I'm trying to retrieve a column from parse server and display it in a ListView. So far i have produced the following code however I've encountered an issue. In my for loop it should fetch each item from the "name" column from the "Absences" class and add it to the ArrayList called "teachers".
The issue is the app crashes because the array is null (after printing it in the logs) and it therefore can't assign it to the ArrayAdapter. I believe the reason for this is that the objects are fetched in the background some time after the arrayadapter code is executed meaning its trying to display an empty array.
I'm assuming i need to delay it somehow - any ideas on what i should do?
Affected code inside the onCreate() method:
final ArrayList<String> teachers = new ArrayList<String>();
ParseQuery<ParseObject> query = ParseQuery.getQuery("Absences");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if(e == null){
for(ParseObject object : objects){
String name = String.valueOf(object.get("name"));
Log.i("teacherName", name);
teachers.add(name);
}
} else {
Log.i("Get data from parse", "There was an error getting data!");
e.printStackTrace();
}
}
});
Log.i("teacherOutput", teachers.toString());
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, teachers);
ListView lv = (ListView)findViewById(R.id.listView);
lv.setAdapter(arrayAdapter);
Many thanks in advance!
You need to learn what asynchronous means.
Your code should be something like:
final ListView lv = (ListView) findViewById(R.id.listView);
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
ArrayList<String> teachers = new ArrayList<String>();
for (ParseObject object : objects) {
String name = String.valueOf(object.get("name"));
Log.i("teacherName", name);
teachers.add(name);
}
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, teachers);
lv.setAdapter(arrayAdapter);
} else {
Log.i("Get data from parse", "There was an error getting data!");
e.printStackTrace();
}
}
});
Related
I have more than 153 objects stored in a parse server class called "HSK1". I want to display all the objects in a ListView but the below code only display 100 elements. Why is that?
I've checked the size of the array it only stores 100 objects.
ListView hsk1List;
CustomWordListAdapter adapter;
ArrayList<HskModel> words = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hsk1);
setTitle("HSK1 List");
hsk1List = findViewById(R.id.hsk1List);
adapter = new CustomWordListAdapter(words, getApplicationContext());
//Filling the ListView-
final ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("HSK1");
query.addAscendingOrder("identifiant");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if(e == null){
if(objects.size() > 0){
for(ParseObject object : objects){
words.add(new HskModel(object.get("identifiant").toString(),
object.get("character").toString(),
"(" + object.get("pinyin").toString()+ ")",
object.get("meaning").toString()));
}
hsk1List.setAdapter(adapter);
Log.i("WORDMAX", String.valueOf(objects.size()));
}
}else{
e.printStackTrace();
}
}
});
I expect output of 153 objects displayed in a list view but only 100 are stored in the array " objects "
Ok so the problem was that the default query limit is set to 100 objects. If that could help someone else. There is an implicit limit of 100
I have a Parse Object that has a value which contains an ArrayList of User Id's. I'm having trouble figuring out how to retrieve that entire ArrayList (NOT just 1 value from the list) My code looks something like this.. but always comes with errors (Array comes back empty):
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("Food");
query.whereEqualTo("objectId", parseId);
query.getFirstInBackground(new GetCallback<ParseObject>() {
#Override
public void done(ParseObject parseObject, ParseException e) {
if (e == null) {
ArrayList<String> list = (ArrayList<String>)
parseObject.get("userList");// This is where I don't know what to use to get the Array
}
else {
AlertDialog.Builder builder = new AlertDialog.Builder(ThisActivity.this);
builder.setTitle(R.string.error_title)
.setMessage("error")
.setPositiveButton("ok", null);
AlertDialog dialog = builder.create();
dialog.show();
}
}
});
I want to just load the array of user id's (from the object) and use the array elsewhere in this activity. All the other values in the object are String values and load just fine with the .getString.
I know I'm probably way off so any help would be appreciated.
//Try This To Retrieve All Records In Server using findInBackground()
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("Food");
query.whereEqualTo("objectId", parseId);
query.findInBackground(new GetCallback<ParseObject>() {
#Override
public void done(List<ParseObject> parseObject, ParseException e) {
if (e == null) {
for (int i = 0; i<parseObject.size(); i++){
ParseObject stObj = parseObject.get(i);
List<String>list = stObj.getList("userList");
//Transfer list content to array stockArr
String[] stockArr = new String[list.size()];
stockArr = list.toArray(stockArr);
//list contains userlist - To add to list without transferring content to array use next line of code below
list.add("Add This To The List");
//To save updated list use next two lines of code below
stObj.put("userList", list);
stObj.saveInBackground();
}
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(ThisActivity.this);
builder.setTitle(R.string.error_title)
.setMessage("error")
.setPositiveButton("ok", null);
AlertDialog dialog = builder.create();
dialog.show();
}
}
});
//Try This To Retrieve ONLY First Record In Server using getFirstInBackground()
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("Food");
query.whereEqualTo("objectId", parseId);
query.getFirstInBackground(new GetCallback<ParseObject>() {
#Override
public void done(List<ParseObject> parseObject, ParseException e) {
if (e == null) {
ParseObject stObj = parseObject.get(0);
List<String>list = stObj.getList("userList");
//Transfer list content to array stockArr
String[] stockArr = new String[list.size()];
stockArr = list.toArray(stockArr);
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(ThisActivity.this);
builder.setTitle(R.string.error_title)
.setMessage("error")
.setPositiveButton("ok", null);
AlertDialog dialog = builder.create();
dialog.show();
}
}
});
You should replace this line:
parseObject.get("userList");// This is where I don't know what to use to get the Array
to:
JSONArray array = parseObject.getJSONArray("userList");
And it shall work without any problem.
I think that you don't have to use getFirstInBackground (that retrieve only one element) but you have to use findInBackground (to retrieve all the objects).
I have a problem to update a listview, but doesn't work. Gives the NullPointerException on ".SetAdapter", does anyone know what can be?
Complete code: http://pastebin.com/AZdMi4sc
//Get filter from another fragment, using Interface, works fine.
public void setFilter(String tag) {
getFeedFilter(tag);
}
//Get only itens
private void getFeedFilter(String filter) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("FeedPost");
query.whereContains("Type", filter);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> responseList, ParseException e) {
if (e == null) {
List<Feed> items = new ArrayList<Feed>();
for(int i = 0; i < responseList.size(); i++) {
items.add(new Feed(responseList.get(i).getString("objectId"),
responseList.get(i).getString("Title"));
}
adapter = new FeedAdapter(getActivity(), items);
adapter.notifyDataSetChanged();
listView.setAdapter(adapter); // The error occurs here.
} else {
System.out.println("error: "+ e);
}
}
});
}
Logcat log:
04-27 03:52:23.175 4415-4415/com.fatos.application.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at com.fatos.application.app.fragment.FeedFragment$6.done(FeedFragment.java:256)
at com.parse.FindCallback.internalDone(FindCallback.java:45)
at com.parse.FindCallback.internalDone(FindCallback.java:31)
at com.parse.Parse$5$1.run(Parse.java:853)
.....
1) you should check if the adapter isn't null.this will fix your crash.
if(adapter!=null)
listView.setAdapter(adapter);
2) you should check if the items returned from response are ok, your problem might be there.
3) your code mixed up, you should init your views and set listeners on one method,
I always call init in fragment - OnCreateView ...
4) The problem might be with your listView, when you are using custom view make sure you give the full location of the custom listview class as your view instead of ListView.
Also, if you just update your adapter, you should not re create your adapter every time. create method in your adapter which set the new data. and just call adapter.notifyDataSetChanged();
For example:
In your adapter code add this:
public void setData(ArrayList<object> newData) {
this.data = newData;
}
then, in your activity notify adapter :
if(items!=null && items.size()>0) {
if(adapter==null){
adapter = new FeedAdapter(getActivity(), items);
}
else {
adapter.setData(yourArrayList);
adapter.notifyDataSetChanged();
}
else {
make toast for us or log to notice items are null...
}
if(adapter!=null)
listView.setAdapter(adapter);
I also think you should init your view and set listeners on your onCreateView method,
because everything is split in your code.
I am trying to display my list of alarms in the ListActivity but it does not work. There rows appear but there is no text visible. I'm not sure if it's retrieving the data from the HashMap and inserting into the rows correctly.
Here is my code:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm_list);
List<Alarm> list;
Database db = new Database(AlarmListActivity.this);
list = db.getAllAlarms();
List<HashMap<String, String>> alarmMap = new ArrayList<HashMap<String, String>>();
for (Alarm alarm: list) {
HashMap<String, String> map = new HashMap<String, String>();
map.put(Integer.toString(alarm.getID()), alarm.toString());
alarmMap.add(map);
}
if(!list.isEmpty() && list != null)
{
System.out.println("inside list");
System.out.println(list);
ListAdapter adapter = new SimpleAdapter(
AlarmListActivity.this,
alarmMap,
R.layout.list_item,
new String[] { "id", "hour"},
new int[] { R.id.id, R.id.time});
setListAdapter(adapter);
}
else
{
Toast.makeText(AlarmListActivity.this, "No Alarms Set",
Toast.LENGTH_SHORT).show();
}
}
This is what I get. You can vaguely see the lines of each row. But there is no text or anything. All the System.out.println() work as expected which print out the HashMap. It's just nothing is being displayed in the list. I've even added: android:text="Testing" to no avail
As I am a beginner to Android programming, I was trying to run some tutorials, but upon running the programs( the source code is available here: http://www.androidhive.info/2012/01/android-json-parsing-tutorial/ ) I got an error.
The program is supposed to read in data from a website and process it, but I think there is something wrong with the networking part.
I am fully aware there have been similar questions here on SO, yet I had no clue how to solve it, perhaps anyone could give solutions which I also can understand.
Strange NetworkOnMainThreadException in Android app?
This is a questions which was asked earlier and is identical to my problem, but I had no clue what they are trying to say there, i.e. "To fix you just need to move any thing that is touching the network to its own thread." makes no sense to me whatsoever..
Can anyone please shed some light on this?
Use an AsyncTask to move your network operation off of the main/ui thread and onto a background/worker thread.
Expanding on the example from the tutorial, wrap the JSON stuff inside of an anonymous AsyncTask:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new AsyncTask<Void, Void, JSONObject>() {
protected JSONObject doInBackground(Void... args) {
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
return jParser.getJSONFromUrl(url);
}
protected void onPostExecute(JSONObject json) {
// Hashmap for ListView
ArrayList<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();
try {
// Getting Array of Contacts
contacts = json.getJSONArray(TAG_CONTACTS);
// looping through All Contacts
for(int i = 0; i < contacts.length(); i++){
JSONObject c = contacts.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String email = c.getString(TAG_EMAIL);
String address = c.getString(TAG_ADDRESS);
String gender = c.getString(TAG_GENDER);
// Phone number is agin JSON Object
JSONObject phone = c.getJSONObject(TAG_PHONE);
String mobile = phone.getString(TAG_PHONE_MOBILE);
String home = phone.getString(TAG_PHONE_HOME);
String office = phone.getString(TAG_PHONE_OFFICE);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_ID, id);
map.put(TAG_NAME, name);
map.put(TAG_EMAIL, email);
map.put(TAG_PHONE_MOBILE, mobile);
// adding HashList to ArrayList
contactList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(this, contactList,
R.layout.list_item,
new String[] { TAG_NAME, TAG_EMAIL, TAG_PHONE_MOBILE }, new int[] {
R.id.name, R.id.email, R.id.mobile });
setListAdapter(adapter);
// selecting single ListView item
ListView lv = getListView();
// Launching new screen on Selecting Single ListItem
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String name = ((TextView) view.findViewById(R.id.name)).getText().toString();
String cost = ((TextView) view.findViewById(R.id.email)).getText().toString();
String description = ((TextView) view.findViewById(R.id.mobile)).getText().toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
in.putExtra(TAG_NAME, name);
in.putExtra(TAG_EMAIL, cost);
in.putExtra(TAG_PHONE_MOBILE, description);
startActivity(in);
}
});
}
}.execute((Void) null);
}