hi i'm trying to create an list from a json feed that has a header for each date and then the content in underneath. however the json feed i have coming in arent organised in date order i have created a for loop that gets all the dates then checks for duplicates which gives me an array of dates from the feed. I then want to add a header view to my adapter for each date and i presume i then need to add another for loop to get the content under each date? problem is at the moment my header views
so my question is how can i create a list that adds header views based on a for loop and then adds other views underneath each header?
here is my function i'm running after an AsyncTask
public void FillData() throws JSONException{
ListView list = getListView();
list.scrollTo(0, 0);
list.setVerticalFadingEdgeEnabled(false);
list.setTextFilterEnabled(true);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE );
View header = inflater.inflate( R.layout.homeheader, list, false);
fixturesView = LayoutInflater.from(getBaseContext()).inflate(R.layout.fixturescell,
null);
//Log.v("MyFix", "fixturesArray = " + fixturesArray);
if(fixturesArray.length() < 1){
TextView emptytext = (TextView) fixturesView.findViewById(R.id.TextView02);
emptytext.setText("No Upcoming Fixtures Available");
}else{
try{
for(int t = 0; t < fixturesArray.length(); t++){
JSONObject matchDateDict = fixturesArray.getJSONObject(t);
String matchDate = matchDateDict.getString("matchdate");
if(matchDatesArray.length() != 0){
int lm = t - 1;
JSONObject lastDateDict = fixturesArray.getJSONObject(lm);
String lastMatchDate = lastDateDict.getString("matchdate");
Log.v("MyFix", "lastMatchDate " + lastMatchDate);
if(matchDate.equals(lastMatchDate)){
Log.v("MyFix", "2 are the same");
} else {
Log.v("MyFix", "add new matchdate to array");
matchDatesArray.put(matchDate);
}
} else {
Log.v("MyFix", "add new matchdate to array (first time only)");
matchDatesArray.put(matchDate);
}
}
Log.v("MyFix", "matchDatesArray = " + matchDatesArray);
}catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DateHeader = LayoutInflater.from(getBaseContext()).inflate(R.layout.redcell,
null);
adapter = new MergeAdapter();
for(int t = 0; t < matchDatesArray.length(); t++){
JSONObject mdheaderdict = matchDatesArray.getJSONObject(t);
String matchheader = mdheaderdict.getString("matchdate");
TextView matchdayheader = (TextView) DateHeader.findViewById(R.id.redheadertext);
matchdayheader.setText(matchheader);
adapter.addView(DateHeader);
}
}
setListAdapter(adapter);
}
heres an example of the json feed
fixturesdata{"code":200,"error":null,"data":{"fixtures":[{"kickoff":"15:00:00","matchdate":"2012-07-14","homescore":null,"awayscore":null,"attendance":null,"homepens":null,"awaypens":null,"division_id":"5059","division":"Testing 1","comp":"LGE","location":null,"fixture_note":null,"hometeam_id":"64930","hometeam":"Team 1","awayteam_id":"64933","awayteam":"Team 4"},{"kickoff":"15:00:00","matchdate":"2012-07-14","homescore":null,"awayscore":null,"attendance":null,"homepens":null,"awaypens":null,"division_id":"5059","division":"Testing 1","comp":"LGE","location":null,"fixture_note":null,"hometeam_id":"64935","hometeam":"Team 6","awayteam_id":"64937","awayteam":"Team 8"},{"kickoff":"15:00:00","matchdate":"2012-07-28","homescore":null,"awayscore":null,"attendance":null,"homepens":null,"awaypens":null,"division_id":"5059","division":"Testing 1","comp":"LGE","location":null,"fixture_note":null,"hometeam_id":"64930","hometeam":"Team 1","awayteam_id":"64931","awayteam":"Team 2"},{"kickoff":"15:00:00","matchdate":"2012-07-28","homescore":null,"awayscore":null,"attendance":null,"homepens":null,"awaypens":null,"division_id":"5059","division":"Testing 1","comp":"LGE","location":null,"fixture_note":null,"hometeam_id":"64930","hometeam":"Team 1","awayteam_id":"64931","awayteam":"Team 2"}]}}
What you want isn't to add the views in a loop, but to make a proper ListView with Sections. I recommend that you read this tutorial which includes sample code.
Sectioning your ListView
Related
i am using volley library for web api call and retrieving json data using for loop and setting that data on custom listview but listview only show two values of that data like if my loop run for 4 times only 2 or 4 numbered value is shown on listview .
Below is my code for fetching values from json data.
details=new ArrayList();
depart_adapter = new Result_dep_adapter(Result.this, android.R.layout.simple_list_item_2, details);
return_adapter = new Result_ret_adapter(Result.this, android.R.layout.simple_list_item_2, details);
departlist.setAdapter(depart_adapter);
returnlist.setAdapter(return_adapter);
try {
for (int k = 0; k < response.length(); k++) {
custom_result=new Custom_Result();
Log.i("response",","+ response.length());
JSONObject obj = response.getJSONObject(k);
JSONObject flight = obj.getJSONObject("Flights");
JSONArray array = flight.getJSONArray("Segments");
for (int i = 0; i < array.length(); i++) {
JSONObject depart = (JSONObject) array.get(i);
String departdate_time = depart.getString("DepartureTime");
String arrivedate_time = depart.getString("ArrivalTime");
Boolean returnflight=depart.getBoolean("IsReturnFlight");
duration=depart.getString("FlightDuration");
Log.i("segments",","+returnflight);
JSONObject Airline=depart.getJSONObject("Airline");
String Airline_code=Airline.getString("Name");
JSONObject Airlinename=depart.getJSONObject("MarketingCarrier");
String name=Airlinename.getString("Name");
Log.i("Airline code", Airline_code);
String[] departtime = departdate_time.split("T");
String[] arrivetime = arrivedate_time.split("T");
if (!returnflight) {
String ddate = departtime[0];
String dtime = departtime[1].substring(0, 5);
Log.i("time", dtime);
String duration = depart.getString("FlightDuration");
String Adate = arrivetime[0];
String Atime = arrivetime[1].substring(0, 5);
custom_result.setDepart_date(ddate);
custom_result.setDepart_time(dtime);
custom_result.setArrive_date(Adate);
custom_result.setArrive_time(Atime);
custom_result.setDep_duration(duration);
custom_result.setDep_Airline_name(name);
custom_result.setDep_Airline_code(Airline_code);
}else{
String Rdate = departtime[0];
String Rtime = departtime[1].substring(0, 5);//return depart time
Log.i("time", Rtime);
String return_duration = depart.getString("FlightDuration");
String ARdate = arrivetime[0];
String ARtime = arrivetime[1].substring(0, 5);
custom_result.setRet_arr_date(ARdate);
custom_result.setRet_arr_time(ARtime);
custom_result.setRet_dep_date(Rdate);
custom_result.setRet_dep_time(Rtime);
custom_result.setRet_duration(return_duration);
custom_result.setRet_Airline_name(name);
custom_result.setRet_Airline_code(Airline_code);
}
}
String stops = flight.getString("Stops");
JSONObject Fare = flight.getJSONObject("Fare");
String published_fare = Fare.getString("PublishedFare");
custom_result.setStops(stops);
custom_result.setPrice(published_fare);
details.add(custom_result);
}
I am new to android please help me ..
Thank you
This my adpater code
private class ViewHolder
{
ImageView Airline_logo;
TextView Airline_code,dep_time,dep_arr_time,dep_stops,dep_duration,
dep_price;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder=null;
// custom_result=Custom_Result.getCustom_result();
custom_result=getItem(position);
LayoutInflater inflater=(LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if(convertView==null)
{
convertView=inflater.inflate(R.layout.result_listview,null);
holder=new ViewHolder();
holder. Airline_logo=(ImageView) convertView.findViewById(R.id.dep_airlines_image);
holder.Airline_code=(TextView) convertView.findViewById(R.id.dep_airline_code);
holder.dep_time=(TextView) convertView.findViewById(R.id.dep_depart_time);
holder.dep_arr_time=(TextView) convertView.findViewById(R.id.dep_arrive_time);
holder.dep_stops=(TextView) convertView.findViewById(R.id.dep_stops_info);
holder.dep_duration=(TextView) convertView.findViewById(R.id.dep_duration);
holder.dep_price=(TextView) convertView.findViewById(R.id.dep_airline_price);
convertView.setTag(holder);
}else
{
holder=(ViewHolder)convertView.getTag();
}
String imagename=custom_result.getDep_Airline_code().toLowerCase();
String path="drawable/"+imagename;
// String logo=path.toLowerCase();
// String PACKAGE_name=getContext().getPackageName();
int imageresource=context.getResources().getIdentifier(path, null, context.getPackageName());
if(imageresource==0)
{
imageresource=R.drawable.flight_icon;
}
Drawable image=context.getResources().getDrawable(imageresource);
// holder. Airline_logo.setImageBitmap(BitmapFactory.decodeResource(getContext().getResources(),image));
holder.Airline_logo.setImageDrawable(image);
holder.Airline_code.setText(custom_result.getDep_Airline_name());
holder.dep_time.setText(custom_result.getDepart_time());
holder.dep_arr_time.setText(custom_result.getArrive_time());
holder.dep_stops.setText(custom_result.getStops());
holder.dep_duration.setText(custom_result.getDep_duration());
holder.dep_price.setText(custom_result.getPrice());
return convertView;
}
You are using android.R.layout.simple_list_item_2 as the layout for the row.
That layout only has 2 textviews so it cant show more than 2 values.
If you need to show more things you need to create your custom adapter from the BaseAdapter Class.
Then in the getView() method you can draw the row with anything you need.
Hope this helps.
recently, I've build a app that I can retrieve the results from the web via json. What it displays is a simple informations. I thought to myself, the custom listview looked simple with only texts, so what I want to do now is to add icons to the left side of the listitem for the first 3 list items only, but things turn complicated,since I've got the json data from the web. I'm finding it difficult to implement the logic to the current code. Afterall, All I want to do is to add icons to the first 3 itemlist. I've set up my sample code below (sorry for the untidy code!).
Is it possible to set the logic within the current code ? Or should I start over again ? Are there some solution ?
protected void onPostExecute(JSONObject jsonobject) {
try {
// Locate the array name in JSON
jsonarray = jsonobject.getJSONArray("infolist");
world = new ArrayList<InfoListData>();
// Create an array to populate the spinner
worldlist = new ArrayList<String>();
for (int i = 0; i < jsonarray.length(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
jsonobject = jsonarray.getJSONObject(i);
InfoListData worldpop = new InfoListData();
worldpop.set_loto_date(jsonobject.optString("loto_date"));
worldpop.set_info_id(jsonobject
.optString("takarakuji_id"));
worldpop.set_numbertimes(jsonobject.optString("id"));
worldpop.set_title(jsonobject.optString("title"));
world.add(worldpop);
worldlist.add(jsonobject.optString("title") + "\n"
+ jsonobject.optString("info_date"));
}
str = jsonarray.toString();
try{
JSONArray jArray = new JSONArray(str);
for (int i = 0; i < jArray.length(); i++) {
JSONObject json = null;
json = jArray.getJSONObject(i);
HashMap<String, String> map1 = new HashMap<String, String>();
// adding each child node to HashMap key => value
//altering the
map1.put("name", json.getString("name"));
String dates = json.getString("loto_date");
//dates= dates.replace("-", "year");
dates = replaceCharAt(dates ,4,"year");
dates = replaceCharAt(dates ,7,"month");
dates = dates+="day";
map1.put("info_date",dates);
String _titles = json.getString("title");
map1.put("title", "("+_titles+")");
// adding HashList to ArrayList//
arrList.add(map1);
}
} catch ( JSONException e) {
e.printStackTrace();
}
//I'm setting up the data in here,but I'm not sure how to set the icons to the
current code
ListView mySpinner = (ListView) findViewById(R.id.listviewpo);
//try the step 5 in here
if(!arrList.isEmpty()){
ListAdapter adapter = new SimpleAdapter(InfoListActivity.this, arrList,
R.layout.customlistforinfo, new String[] {"name", "title", "info_date"},
new int[] {R.id.infoname,R.id.infontitle, R.id.dayk});
mySpinner.setAdapter(adapter);
}
You would have to make your own custom adapter for the listview to add an image in the listview. You are going to want to extend ArrayAdapter. Here is some code I wrote a while back that does basically exactly what you are trying to do (I think). Hopefully this will help you out a bit. Cheers
import java.util.ArrayList;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class StandingsAdapter extends ArrayAdapter<ResidentialCollege>{
public StandingsAdapter(Context context, ArrayList<ResidentialCollege> colleges) {
super(context, R.layout.standings_row_layout, colleges);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.standings_row_layout, parent, false);
ResidentialCollege college = (ResidentialCollege) getItem(position);
TextView collegeView = (TextView) view.findViewById(R.id.standingsTextView);
collegeView.setText(getDisplayName(college.getName()));
TextView scoreView = (TextView) view.findViewById(R.id.tyngScore);
scoreView.setText("" + getDisplayScore(college.getScore()));
ImageView imageView = (ImageView) view.findViewById(R.id.resCollegeImage);
imageView.setImageResource(college.getImgResource());
return view;
}
//generate a string to display from a given residential college name to avoid
//long names messing up the display. E.G Johnathan Edwards
private String getDisplayName(String name) {
if(name.length() > 10){
return (name.substring(0, 7).toUpperCase() + " ...");
}
else return name.toUpperCase();
}
//to get rid of the .0's at the end of the scores that are integers.
//Came at the cost of allowing scores to have .5's forcing floating point numbers.
private String getDisplayScore(Double score){
if((score % 1) == 0){
return "" + score.intValue();
}
else{
return "" + score;
}
}
public void updateStandings(ArrayList<ResidentialCollege> newResList) {
this.clear();
for(ResidentialCollege res : newResList){
this.add(res);
}
this.notifyDataSetChanged();
}
//perform a simple insertion sort(only 12 elements, so should be fast enough)
public ArrayList<ResidentialCollege> sortByScore(ArrayList<ResidentialCollege> listToSort){
ArrayList<ResidentialCollege> sorted = new ArrayList<ResidentialCollege>();
sorted.add(listToSort.get(0));
listToSort.remove(0);
for(ResidentialCollege college : listToSort){
for(int i = 0; i < sorted.size(); i++){
if(college.getScore() >= sorted.get(i).getScore()){
sorted.add(i, college);
Log.d("inserted:", college.getName() + " " + "at position " + i);
break;
}
//add it to the end it has the lowest score seen so far.
else if(i == (sorted.size() - 1)){
sorted.add(college);
Log.d("appended:", college.getName() + " " + "at position" + i);
break;
}
}
}
return sorted;
}
}
I have a variable called current which holds the last clicked listview item data. The id of this data is to be used to query the db again for movies taht are similar.
The problem that current = id=17985, title=the matrix, year=1999 when all i need is the actual id-number. I have tried to use substring to only use the correct places of the string. This works for the matrix since its id is exactly 5 digits long, but as soon as i try to click movie with higher/lower amount of digits in its id of course it trips up.
String id = current.substring(4,9).trim().toString(); does not work for all movies.
Heres some code:
// search method: this is necessary cause this is the method thats first used and where the variable current is set. This is also the only method using three lines for getting data - id, title and year.
protected void search() {
data = new ArrayList<Map<String, String>>();
list = new ArrayList<String>();
EditText searchstring = (EditText) findViewById(R.id.searchstring);
String query = searchstring.getText().toString().replace(' ', '+');
String text;
text = searchquery(query);
try {
JSONObject res = new JSONObject(text);
JSONArray jsonArray = res.getJSONArray("movies");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
item = new HashMap<String, String>(2);
item.put("id",jsonObject.getString("id"));
item.put("title",jsonObject.getString("title"));
item.put("year", jsonObject.getString("year"));
data.add(item);
}
} catch (Exception e) {
e.printStackTrace();
}
aa = new SimpleAdapter(SearchTab.this, data,
R.layout.mylistview,
new String[] {"title", "year"},
new int[] {R.id.text1,
R.id.text2});
ListView lv = (ListView) findViewById(R.id.listView1);
lv.setAdapter(aa);
lv.setDividerHeight(5);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
Map<String, String> s = data.get((int) id);
current = s.toString();
}});
}
// similar method: this tries to build a list from the fetched data from "current"-string. As you can see i try to use 4,9 to only get right numbers, but this fails with others. Best would be to only to be ble to get the ID which I cant seem to do. The toast is just to see what is beeing fetched, much like a system out print.
protected void similar() {
data = new ArrayList<Map<String, String>>();
list = new ArrayList<String>();
String id = current.substring(4,9).trim().toString();
Toast.makeText(getApplicationContext(), id, Toast.LENGTH_SHORT).show();
String text;
text = similarquery(id);
try {
JSONObject res = new JSONObject(text);
JSONArray jsonArray = res.getJSONArray("movies");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
item = new HashMap<String, String>(2);
item.put("title",jsonObject.getString("title"));
item.put("year", jsonObject.getString("year"));
data.add(item);
}
} catch (Exception e) {
e.printStackTrace();
}
aa = new SimpleAdapter(SearchTab.this, data,
R.layout.mylistview2,
new String[] {"title", "year"},
new int[] {R.id.text1,
R.id.text2});
ListView lv = (ListView) findViewById(R.id.listView1);
lv.setAdapter(aa);
lv.setDividerHeight(5);
}
Use current.split(",")[0].split("=")[1]
edit - assuming of course that id is always the first in the comma separated list and will always be a name value pair delimited by '='
If you want to solve it via substring then you shouldn't use a predefined .substring(4,9). Use something like that:
String item = "id=17985, title=the matrix, year=1999";
String id = item.substring(item.indexOf("id=") + 3, item.indexOf(" ", item.indexOf("id=") + 3) - 1);
System.out.println("Your ID is: " + id);
// Works also for "test=asdf, id=17985, title=the matrix, year=1999"
It gets the String between "id=" and the next " " (space).
Hi i have created an array of dates and i'm wanting to add a header view for each of these dates i'm then gonna run another for loop that will add other views underneath each header. at the moment i'm just wanting to add the header views but currently nothing is showing on screen. so my question is How can i programmatically add views within a for loop?
heres my code
public void FillData() throws JSONException{
ListView list = getListView();
list.scrollTo(0, 0);
list.setVerticalFadingEdgeEnabled(false);
list.setTextFilterEnabled(true);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE );
View header = inflater.inflate( R.layout.homeheader, list, false);
fixturesView = LayoutInflater.from(getBaseContext()).inflate(R.layout.fixturescell,
null);
//Log.v("MyFix", "fixturesArray = " + fixturesArray);
if(fixturesArray.length() < 1){
TextView emptytext = (TextView) fixturesView.findViewById(R.id.TextView02);
emptytext.setText("No Upcoming Fixtures Available");
}else{
try{
for(int t = 0; t < fixturesArray.length(); t++){
JSONObject matchDateDict = fixturesArray.getJSONObject(t);
String matchDate = matchDateDict.getString("matchdate");
if(matchDatesArray.length() != 0){
int lm = t - 1;
JSONObject lastDateDict = fixturesArray.getJSONObject(lm);
String lastMatchDate = lastDateDict.getString("matchdate");
Log.v("MyFix", "lastMatchDate " + lastMatchDate);
if(matchDate.equals(lastMatchDate)){
Log.v("MyFix", "2 are the same");
} else {
Log.v("MyFix", "add new matchdate to array");
matchDatesArray.put(matchDate);
}
} else {
Log.v("MyFix", "add new matchdate to array (first time only)");
matchDatesArray.put(matchDate);
}
}
Log.v("MyFix", "matchDatesArray = " + matchDatesArray);
}catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DateHeader = LayoutInflater.from(getBaseContext()).inflate(R.layout.redcell,
null);
adapter = new MergeAdapter();
for(int t = 0; t < matchDatesArray.length(); t++){
JSONObject mdheaderdict = matchDatesArray.getJSONObject(t);
String matchheader = mdheaderdict.getString("matchdate");
TextView matchdayheader = (TextView) DateHeader.findViewById(R.id.redheadertext);
matchdayheader.setText(matchheader);
adapter.addView(DateHeader);
}
}
setListAdapter(adapter);
}
}
i think this is what you are searching for
http://code.google.com/p/android-amazing-listview/
ListView with section headers and auto-loading of next pages (i.e. "Loading..." on the last item)
Im looking to run a query on my external database, i got all the coding done up to this point. Although the coding works, I need it to put the "name" and the "cphone" in an array of some sort so i can add it to the custom list adapter as a double row.
'''''''''''''''''''''''''''''''''''
name
'''''''''''''''''''''''''''''''''''
cphone
'''''''''''''''''''''''''''''''''''
to this
'''''''''''''''''''''''''''''''''''
name cphone
'''''''''''''''''''''''''''''''''''
Log.d("RESULT", result);
try {
JSONArray jArray = new JSONArray(result);
ArrayList<String> items = new ArrayList<String>();
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
String name = json_data.getString("username");
String cphone = json_data.getString("password");
items.add(name);
items.add(cphone);
Log.d(name, "Sever Output");
}
ArrayAdapter<String> mArrayAdapter = new ArrayAdapter<String>(
getdata.this, R.layout.stashrow, items);
ListView sList = (ListView) findViewById(R.id.liststash);
sList.setAdapter(mArrayAdapter);
} catch (Exception e) {
Log.e("errorLog", "Error makingView: " + e.toString());
}
the problem stands in the item.add(), i can only put one value in at a time so it makes it 2 different lines. If I try adding another textview to the stashrow, it errors out. Is there a better way of doing this?
The basic ArrayAdapter isn't configured to do very much. If you're content with the simple formatting of
'''''''''''''''''''''''''''''''''''
name cphone
'''''''''''''''''''''''''''''''''''
Then you might as well just concatenate the strings together:
String name = json_data.getString("username");
String cphone = json_data.getString("password");
String user = name + " " + cphone;
items.add(user);
For anything more complicated then that, you're better off defining your own data object (like a User for instance, with a getName() and getCPhone()) and then subclassing ArrayAdapter to translate the objects in the array into the well formatted ListView you really want - like so:
public class MyAdapter extends ArrayAdapter<User> {
// Constructor, etc
...
#Override
public void getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
final LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.stashrow, null);
}
User user = items.get(position)
TextView name = (TextView) findViewById(R.id.stash_row_name);
TextView chpone = (TextView) findViewById(R.id.stash_row_cphone);
name.setText(user.getName());
cphone.setText(user.getCPhone());
}
Hope that helps!