Football-data API JSON parsing error - java
I'm having difficulty in downloading footballing data from an (http://www.football-data.org). I am trying to download the English Premier League Table by creating a new Standing object for each team and adding them to an ArrayList.
I've set up my parser class, adapter class and my view.
The error I am getting is :
org.json.JSONException: org.json.JSONException: Value {"_links":{"self":{"href":"http:\/\/api.football-data.org\/v1\/soccerseasons\/426\/leagueTable\/?matchday=37"},"soccerseason":{"href":"http:\/\/api.football-data.org\/v1\/soccerseasons\/426"}},"leagueCaption":"Premier League 2016\/17","matchday":37,"standing":[{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/61"}},"position":1,"teamName":"Chelsea FC","crestURI":"http:\/\/upload.wikimedia.org\/wikipedia\/de\/5\/5c\/Chelsea_crest.svg","playedGames":36,"points":87,"goals":76,"goalsAgainst":29,"goalDifference":47,"wins":28,"draws":3,"losses":5,"home":{"goals":46,"goalsAgainst":13,"wins":15,"draws":0,"losses":2},"away":{"goals":30,"goalsAgainst":16,"wins":13,"draws":3,"losses":3}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/73"}},"position":2,"teamName":"Tottenham Hotspur FC","crestURI":"http:\/\/upload.wikimedia.org\/wikipedia\/de\/b\/b4\/Tottenham_Hotspur.svg","playedGames":35,"points":77,"goals":71,"goalsAgainst":23,"goalDifference":48,"wins":23,"draws":8,"losses":4,"home":{"goals":45,"goalsAgainst":8,"wins":16,"draws":2,"losses":0},"away":{"goals":26,"goalsAgainst":15,"wins":7,"draws":6,"losses":4}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/65"}},"position":3,"teamName":"Manchester City FC","crestURI":"https:\/\/upload.wikimedia.org\/wikipedia\/en\/e\/eb\/Manchester_City_FC_badge.svg","playedGames":36,"points":72,"goals":72,"goalsAgainst":38,"goalDifference":34,"wins":21,"draws":9,"losses":6,"home":{"goals":34,"goalsAgainst":16,"wins":10,"draws":7,"losses":1},"away":{"goals":38,"goalsAgainst":22,"wins":11,"draws":2,"losses":5}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/64"}},"position":4,"teamName":"Liverpool FC","crestURI":"http:\/\/upload.wikimedia.org\/wikipedia\/de\/0\/0a\/FC_Liverpool.svg","playedGames":36,"points":70,"goals":71,"goalsAgainst":42,"goalDifference":29,"wins":20,"draws":10,"losses":6,"home":{"goals":42,"goalsAgainst":18,"wins":11,"draws":5,"losses":2},"away":{"goals":29,"goalsAgainst":24,"wins":9,"draws":5,"losses":4}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/57"}},"position":5,"teamName":"Arsenal FC","crestURI":"http:\/\/upload.wikimedia.org\/wikipedia\/en\/5\/53\/Arsenal_FC.svg","playedGames":35,"points":66,"goals":68,"goalsAgainst":42,"goalDifference":26,"wins":20,"draws":6,"losses":9,"home":{"goals":34,"goalsAgainst":15,"wins":12,"draws":3,"losses":2},"away":{"goals":34,"goalsAgainst":27,"wins":8,"draws":3,"losses":7}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/66"}},"position":6,"teamName":"Manchester United FC","crestURI":"http:\/\/upload.wikimedia.org\/wikipedia\/de\/d\/da\/Manchester_United_FC.svg","playedGames":35,"points":65,"goals":51,"goalsAgainst":27,"goalDifference":24,"wins":17,"draws":14,"losses":4,"home":{"goals":24,"goalsAgainst":12,"wins":7,"draws":10,"losses":1},"away":{"goals":27,"goalsAgainst":15,"wins":10,"draws":4,"losses":3}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/62"}},"position":7,"teamName":"Everton FC","crestURI":"http:\/\/upload.wikimedia.org\/wikipedia\/de\/f\/f9\/Everton_FC.svg","playedGames":37,"points":61,"goals":61,"goalsAgainst":41,"goalDifference":20,"wins":17,"draws":10,"losses":10,"home":{"goals":42,"goalsAgainst":16,"wins":13,"draws":4,"losses":2},"away":{"goals":19,"goalsAgainst":25,"wins":4,"draws":6,"losses":8}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/74"}},"position":8,"teamName":"West Bromwich Albion FC","crestURI":"http:\/\/upload.wikimedia.org\/wikipedia\/de\/8\/8b\/West_Bromwich_Albion.svg","playedGames":36,"points":45,"goals":41,"goalsAgainst":46,"goalDifference":-5,"wins":12,"draws":9,"losses":15,"home":{"goals":27,"goalsAgainst":22,"wins":9,"draws":2,"losses":8},"away":{"goals":14,"goalsAgainst":24,"wins":3,"draws":7,"losses":7}},{"_links":{"team":{"href":"http:\/\/api.football-data.org\/v1\/teams\/1044"}},"position":9,"teamName":"AFC Bournemouth","crestURI":"https:\/
05-13 15:39:24.798 6021-6540/com.example.oisin.premierleaguesocial W/System.err: at org.json.JSON.typeMismatch(JSON.java:111)
05-13 15:39:24.798 6021-6540/com.example.oisin.premierleaguesocial W/System.err: at org.json.JSONArray.<init>(JSONArray.java:96)
05-13 15:39:24.798 6021-6540/com.example.oisin.premierleaguesocial W/System.err: at org.json.JSONArray.<init>(JSONArray.java:108)
05-13 15:39:24.798 6021-6540/com.example.oisin.premierleaguesocial W/System.err: at com.example.oisin.premierleaguesocial.Utilities.JSONParser.parse(JSONParser.java:75)
05-13 15:39:24.799 6021-6540/com.example.oisin.premierleaguesocial W/System.err: at com.example.oisin.premierleaguesocial.Utilities.JSONParser.doInBackground(JSONParser.java:56)
05-13 15:39:24.799 6021-6540/com.example.oisin.premierleaguesocial W/System.err: at com.example.oisin.premierleaguesocial.Utilities.JSONParser.doInBackground(JSONParser.java:27)
I've been trying to resolve the issue for a few hours, but can't fix it. I think I've set up my data types correctly. I decided to only try to get the Integer data types at first for the sake of simplicity.
Any help would be very much appreciated. Thank you.
public class JSONParser extends AsyncTask<Void, Void, Boolean> {
private Context c;
private String jsonData;
private RecyclerView rv;
private ProgressDialog pd;
private ArrayList<Standing> mLeagueTable = new ArrayList<>();
public JSONParser(Context c, String jsonData, RecyclerView rv) {
this.c = c;
this.jsonData = jsonData;
this.rv = rv;
}
#Override
protected void onPreExecute () {
super.onPreExecute();
pd = new ProgressDialog(c);
pd.setTitle("Parse");
pd.setMessage("Parsing..Please Wait");
pd.show();
}
#Override
protected Boolean doInBackground (Void...params){
return parse();
}
#Override
protected void onPostExecute (Boolean isParsed){
super.onPostExecute(isParsed);
pd.dismiss(); //Dismiss progress dialog.
if (isParsed) {
//BIND
rv.setAdapter(new TableAdapter(c, mLeagueTable)); //Pass in instance of adapter.
} else {
Toast.makeText(c, "Unable to Parse check your Log Output", Toast.LENGTH_SHORT).show();
}
}
private Boolean parse() {
try {
//JSONArray ja = new JSONArray(jsonData);
JSONArray ja = new JSONArray("standing");
JSONObject jo; //declare json OBJECT
mLeagueTable.clear(); //Clears the ArrayList.
Standing table; //Declare a table
for (int i = 0; i < ja.length(); i++) //iterating in JSONArray
{
jo = ja.getJSONObject(i);
int position = ja.getInt(Integer.parseInt("position"));
int points = ja.getInt(Integer.parseInt("points"));
int playedGames = ja.getInt(Integer.parseInt("playedGames"));
int goals = ja.getInt(Integer.parseInt("goals"));
int goalsAgainst = ja.getInt(Integer.parseInt("goalsAgainst"));
int goalDifference = ja.getInt(Integer.parseInt("goalDifference"));
table = new Standing(); //Create a new "User" object.
table.setPosition(position);
table.setPoints(points);
table.setPlayedGames(playedGames);
table.setGoals(goals);
table.setGoalsAgainst(goalsAgainst);
table.setGoalDifference(goalDifference);
mLeagueTable.add(table); //Add new Standing object to ArrayList mLeagueTable.
}
return true;
} catch (JSONException e) {
e.printStackTrace();
return false;
}
}
}
public class JSONDownloader extends AsyncTask<Void, Void, String> {
Context c;
String jsonURL;
RecyclerView rv;
ProgressDialog pd;
public JSONDownloader(Context c, String jsonURL, RecyclerView rv) {
this.c = c;
this.jsonURL = jsonURL;
this.rv = rv;
}
#Override
protected void onPreExecute() { //CALLED just before data is downloaded.
super.onPreExecute();
pd = new ProgressDialog(c);
pd.setTitle("Download JSON");
pd.setMessage("Downloading.... Please Wait!");
pd.show();
}
#Override
protected String doInBackground(Void... voids) {
return download();
}
#Override
protected void onPostExecute(String jsonData) {
super.onPostExecute(jsonData);
pd.dismiss();
if (jsonData.startsWith("Error"))
{
String error = jsonData;
Toast.makeText(c, error, Toast.LENGTH_SHORT).show();
} else {
//PARSER
new JSONParser(c, jsonData, rv).execute();
}
}
private String download() {
Object connection = Connector.connect(jsonURL);
if (connection.toString().startsWith("Error")) {
return connection.toString();
}
try {
HttpURLConnection con = (HttpURLConnection) connection; //Cast connection to HTTPConnection
if (con.getResponseCode() == con.HTTP_OK) {
//GET INPUT FROM STREAM
InputStream is = new BufferedInputStream(con.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer jsonData = new StringBuffer();
// READ
while ((line = br.readLine()) != null) {
jsonData.append(line + "\n");
}
//CLOSE RESOURCES
br.close();
is.close();
//RETURN JSON
return jsonData.toString();
} else {
return "Error " + con.getResponseMessage();
}
} catch (IOException e) {
e.printStackTrace();
return "Error " + e.getMessage();
}
}
}
public class MainActivity extends AppCompatActivity {
String jsonURL = "http://api.football-data.org/v1/soccerseasons/426/leagueTable";
public static final String TAG = "MainActivity";
//FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
private RecyclerView rv;
/*private ArrayList<Standing> mLeagueTable = new ArrayList<>(); //Initalise m
private TableAdapter mTableAdapter = new TableAdapter(mLeagueTable, this); */
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_table);
//Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
//setSupportActionBar(toolbar);
rv = (RecyclerView) findViewById(R.id.rv);
if (rv != null) {
rv.setLayoutManager(new LinearLayoutManager(this));
}
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); //Initialze FAB
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new JSONDownloader(MainActivity.this, jsonURL, rv).execute();
}
});
}
}
public class TableAdapter extends RecyclerView.Adapter<MyViewHolder>{
private ArrayList<Standing> mLeagueTable;
private Context c;
public TableAdapter(Context c, ArrayList<Standing> mLeagueTable) {
this.c = c;
this.mLeagueTable = mLeagueTable;
} //Constructor
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.tableitem, parent, false); //Inlfate the League Table model view.
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) { //BINDS THE data to the appropriote View
Standing s = mLeagueTable.get(position);
final int teamPosition = s.getPosition();
final String teamName = s.getTeamName();
final int playedGames = s.getPlayedGames();
final int goals = s.getGoals();
final int goalsAgainst = s.getGoalsAgainst();
final int goalDifference = s.getGoalDifference();
final int points = s.getPoints();
//holder.teamNameTxt.setText(teamName);
holder.teamPositionTxt.setText(teamPosition);
holder.playedGamesTxt.setText(playedGames);
//holder.teamImage.setImageResource(s.getTeamImage());
holder.goalsTxt.setText(goals);
holder.goalsAgainstTxt.setText(goalsAgainst);
holder.goalDifferenceTxt.setText(goalDifference);
holder.pointsTxt.setText(points);
// holder.wins.setText(s.getWins());
//holder.draws.setText(s.getDraws());
//holder.losses.setText(s.getLosses());
holder.setItemClickListener(new ItemClickListener() {
#Override
public void onItemClick(int pos) {
openActivity(teamPosition, playedGames, goals, goalsAgainst, goalDifference, points);
}
});
}
#Override
public int getItemCount() {return mLeagueTable.size();}
////open Activity
private void openActivity(int...details)
{
Intent i = new Intent(c, TableActivity.class);
i.putExtra("POSITION_KEY", details[0]);
//i.putExtra("TEAMNAME_KEY", details[1]);
i.putExtra("POINTS_KEY", details[2]);
i.putExtra("PLAYEDGAMES_KEY", details[3]);
i.putExtra("GOALS_KEY", details[4]);
i.putExtra("GOALSAGAINST_KEY", details[5]);
i.putExtra("GOALDIFFERENCE_KEY", details[6]);
c.startActivity(i);
}
}
tableitem.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/teamPositionTxt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#color/primary_text" />
<TextView
android:id="#+id/teamNameTxt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:textColor="#color/primary_text" />
<TextView
android:id="#+id/pointsTxt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#color/primary_text"
android:textStyle="bold" />
<TextView
android:id="#+id/playedGamesTxt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#color/primary_text" />
<TextView
android:id="#+id/goalsTxt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#color/primary_text" />
<TextView
android:id="#+id/goalsAgainstTxt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#color/primary_text" />
<TextView
android:id="#+id/goalDifferenceTxt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#color/primary_text" />
</LinearLayout>
1. Create a JSONObject from string jsonData.
2. Get JSONArray (standing) from JSONObject by using jsonObj.getJSONArray("standing").
3. Inside for loop, get int values from JsonObject using jo.getInt() instead of ja.getInt().
Here is the working code:
private Boolean parse() {
try {
JSONObject jsonObj = new JSONObject(jsonData);
JSONArray ja = jsonObj.getJSONArray("standing");
mLeagueTable.clear(); //Clears the ArrayList.
for (int i = 0; i < ja.length(); i++) //iterating in JSONArray
{
JSONObject jo = ja.getJSONObject(i);
int position = jo.getInt(Integer.parseInt("position"));
int points = jo.getInt(Integer.parseInt("points"));
int playedGames = jo.getInt(Integer.parseInt("playedGames"));
int goals = jo.getInt(Integer.parseInt("goals"));
int goalsAgainst = jo.getInt(Integer.parseInt("goalsAgainst"));
int goalDifference = jo.getInt(Integer.parseInt("goalDifference"));
Standing table = new Standing(); //Create a new "User" object.
table.setPosition(position);
table.setPoints(points);
table.setPlayedGames(playedGames);
table.setGoals(goals);
table.setGoalsAgainst(goalsAgainst);
table.setGoalDifference(goalDifference);
mLeagueTable.add(table); //Add new Standing object to ArrayList mLeagueTable.
}
return true;
} catch (JSONException e) {
e.printStackTrace();
return false;
}
}
Hope this will work~
Change
JSONArray ja = new JSONArray("standing");
for
JSONObject ja = new JSONObject(jsonData);
JSONObject jo = ja.getJSONObject("soccerseason");
The information is in jo, and now you can extract each field following the right structure of the JSONObject
Related
RecyclerView Not Displaying - Android
I am having a few problems with my RecyclerView in Android. When I run the project there is no display, only a white screen. Please help.. MainActivity Code: public class MainActivity extends AppCompatActivity { RecyclerView mRecyclerView; private RecyclerView.LayoutManager mLayoutManager; private MyAdapter mViewAdapter; List<News> news_list = new ArrayList<>(); #Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new ParseNewsJSON().execute(); mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView); mRecyclerView.setHasFixedSize(true); //mRecyclerView.setItemAnimator(new DefaultItemAnimator()); mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); mViewAdapter= new MyAdapter(news_list); mRecyclerView.setAdapter(mViewAdapter); } } MyAdapter Code: public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private List<News> newsArticleList; public class ViewHolder extends RecyclerView.ViewHolder{ public TextView title; //description, genre; public ViewHolder(View itemView) { super(itemView); title = (TextView) itemView.findViewById(R.id.textView_articleHeading); // description = (TextView) itemView.findViewById(R.id.textView_description); // image = (TextView) itemView.findViewById(R.id.rating); } } public MyAdapter (List<News> newsArticleList){ this.newsArticleList = newsArticleList; } #Override public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_main, parent, false); return new ViewHolder(itemView); } #Override public void onBindViewHolder(MyAdapter.ViewHolder holder, int position) { News news = newsArticleList.get(position); holder.title.setText(news.getHeading()); } #Override public int getItemCount() { return newsArticleList.size(); } } JSON Parsing Code: public class ParseNewsJSON extends AsyncTask<String, Void, String> { private final String JSON_URL = "https://newsapi.org/v2/top-headlines?sources=cnn&apiKey=c80ddd850a524fe5975cad881d6f4aba"; String result =""; ArrayList<String> article_heading = new ArrayList<>(); #Override protected String doInBackground(String... strings) { try { URL url = new URL(JSON_URL); HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); InputStream inputStream = httpURLConnection.getInputStream(); InputStreamReader reader = new InputStreamReader(inputStream); int data = reader.read(); while(data !=-1){ char current = (char) data; result += current; data = reader.read(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } #Override protected void onPostExecute(String s) { try { JSONObject jsonObject = new JSONObject(result); JSONArray jsonArray = jsonObject.getJSONArray("articles"); for(int i = 0; i<jsonArray.length(); i++){ News news = new News(); news.setHeading(String.valueOf(article_heading.add(jsonArray.getJSONObject(i).optString("title")))); // article_heading.add(jsonArray.getJSONObject(i).optString("title")); Log.d("news_JSON", article_heading.toString()); Log.d("news", news.getHeading().toString()); //article_heading.add(jsonArray.getJSONObject(i).optString("title")); } } catch (JSONException e) { e.printStackTrace(); } super.onPostExecute(s); } } News.Java: public class News { private String heading; //private String descrpiton; private String img; public String getHeading() { return heading; } public void setHeading(String heading) { this.heading = heading; } public String getImg() { return img; } public void setImg(String img) { this.img = img; } } I have read threw a few threads however they have not solved my issueThis is the output when I run the emulator activity_main.xml: android:layout_width="match_parent" android:layout_height="match_parent" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <android.support.v7.widget.RecyclerView android:layout_height="match_parent" android:layout_width="match_parent" android:id="#+id/recyclerView" xmlns:android="http://schemas.android.com/apk/res/android"> </android.support.v7.widget.RecyclerView> card_layout.xml: xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="#+id/card_view" android:layout_width="match_parent" android:layout_marginTop="15dp" android:layout_height="200dp" app:cardCornerRadius="25dp" > <LinearLayout android:layout_width="match_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="#+id/textView_articleHeading" android:layout_marginLeft="5dp" android:textStyle="bold" android:textColor="#000000" android:textSize="18sp" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:layout_height="0dp" android:layout_width="match_parent" android:layout_weight="1.0" android:id="#+id/rating" android:scaleType="center" /> <TextView android:id="#+id/textView_description" android:textSize="15sp" android:textColor="#000000" android:layout_marginBottom="5dp" android:layout_marginLeft="5dp" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
I think the problem is that your not adding any data in to your news_list ArrayList check in your ParseNewsJSON onPostExecute() method Make change in your ParseNewsJSON like below code #Override protected void onPostExecute(String s) { try { JSONObject jsonObject = new JSONObject(result); JSONArray jsonArray = jsonObject.getJSONArray("articles"); for(int i = 0; i<jsonArray.length(); i++){ News news = new News(); news.setHeading(String.valueOf(article_heading.add(jsonArray.getJSONObject(i).optString("title")))); // article_heading.add(jsonArray.getJSONObject(i).optString("title")); Log.d("news_JSON", article_heading.toString()); Log.d("news", news.getHeading().toString()); news_list.add(news); } } catch (JSONException e) { e.printStackTrace(); } mViewAdapter= new MyAdapter(news_list); mRecyclerView.setAdapter(mViewAdapter); mViewAdapter.notifyDataSetChanged(). super.onPostExecute(s); }
You have to add values to "news_list" in onPostExecute() of ParseNewsJSON class. And then notify the adapter. #Override protected void onPostExecute(String s) { try { JSONObject jsonObject = new JSONObject(result); JSONArray jsonArray = jsonObject.getJSONArray("articles"); for (int i = 0; i < jsonArray.length(); i++) { News news = new News(); news.setHeading(String.valueOf(article_heading.add(jsonArray.getJSONObject(i).optString("title")))); news_list.add(news); Log.d("news_JSON", article_heading.toString()); Log.d("news", news.getHeading().toString()); } mViewAdapter.notifyDataSetChanged(); } catch (JSONException e) { e.printStackTrace(); } super.onPostExecute(s); }
add your parse data to arraylist in onPostExecute() and notify adapter. #Override protected void onPostExecute(String s) { try { JSONObject jsonObject = new JSONObject(result); JSONArray jsonArray = jsonObject.getJSONArray("articles"); for (int i = 0; i < jsonArray.length(); i++) { News news = new News(); news.setHeading(String.valueOf(article_heading.add(jsonArray.getJSONObject(i).optString("title")))); news_list.add(news); } mViewAdapter.notifyDataSetChanged();//add this line } catch (JSONException e) { e.printStackTrace(); } super.onPostExecute(s); }
in main activity mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView); mRecyclerView.setHasFixedSize(true); //mRecyclerView.setItemAnimator(new DefaultItemAnimator()); mRecyclerView.setLayoutManager( new LinearLayoutManager(getApplicationContext())); mViewAdapter= new MyAdapter(new ArrayList<News>); mRecyclerView.setAdapter(mViewAdapter); in post execute method #Override protected void onPostExecute(String s) { try { JSONObject jsonObject = new JSONObject(result); JSONArray jsonArray = jsonObject.getJSONArray("articles"); for(int i = 0; i<jsonArray.length(); i++){ news_list.add(jsonArray.getJSONObject(i)); news.setHeading(String.valueOf(article_heading.add(jsonArray.getJSONObject(i).optString("title")))); //article_heading.add(jsonArray.getJSONObject(i).optString("title")) Log.d("news_JSON", article_heading.toString()); Log.d("news", news.getHeading().toString()); } mViewAdapter.add(news_list); } catch (JSONException e) { e.printStackTrace(); } super.onPostExecute(s); } in adapter change this #Override public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int position) { if (viewHolder instanceof ViewHolder){ ViewHolder holder = (ViewHolder) viewHolder; holder.displayDetails(newsArticleList.get(position)); } } add method in adapter public void addItems(List<News> items){ if ( items != null && items.size() > 0 ) { for (int i = 0; i < items.size(); i++) { newsArticleList.add(items.get(i)); notifyItemInserted(newsArticleList.size() - 1); } } }
Add objects to JSONObj
I want to add objects inside to JSONObj when onClick and display in another Activity inside of a ListView as a CardView. I tried something but nothing appears, no errors and I have no clue what's the problem. Here is my code for JSONObj: private void writeJSON(String metodaPlata) throws JSONException { String numeVanzator = SharedPreference.getString(this, SharedPreference.USER_DATA, SharedPreference.NUME_VANZATOR, ""); String jsonDataFromShared = SharedPreference.getString(this, SharedPreference.APP_DATA, SharedPreference.JSON_DATA, ""); JSONObject jsonData; JSONArray dateJSON; JSONObject obj; JSONArray arrayForList; if (jsonDataFromShared.equals("")) { jsonData = new JSONObject(); dateJSON = new JSONArray(); obj = new JSONObject(); arrayForList = new JSONArray(); JSONObject objListaSiModalitate = new JSONObject(); // arrayForList.put(stock_list.toString()); objListaSiModalitate.put("lista", new JSONArray(Util.getInstance().getVanzatorProduse())); objListaSiModalitate.put("metodaPlata", metodaPlata); obj.put("data", getDate(calendarData.getTimeInMillis())); obj.put("numeVanzator", numeVanzator); obj.put("numarClient", 0); obj.put("detaliiCos", objListaSiModalitate); dateJSON.put(obj); jsonData.put("jsonData", dateJSON.toString()); SharedPreference.putString(this, SharedPreference.APP_DATA, SharedPreference.JSON_DATA, jsonData.toString()); } else { jsonData = new JSONObject(jsonDataFromShared); dateJSON = jsonData.getJSONArray("jsonData"); obj = new JSONObject(); JSONObject objListaSiModalitate = new JSONObject(); objListaSiModalitate.put("metodaPlata", metodaPlata); obj.put("produseSelectate", listaProdusePreview.getAdapter().getCount()); int totalPrice = 0; for (VanzatorProduse v : Util.getInstance().getVanzatorProduse()) { int vPrice = Integer.parseInt(v.getPret()); totalPrice = totalPrice + vPrice; } obj.put("sumaProduse", totalPrice); obj.put("data", getDate(calendarData.getTimeInMillis())); obj.put("numeVanzator", numeVanzator); obj.put("numarClient", numarVanzare); obj.put("detaliiCos", objListaSiModalitate); dateJSON.put(obj); jsonData.put("jsonData", dateJSON); System.out.println("jsonData" + dateJSON); SharedPreference.putString(this, SharedPreference.APP_DATA, SharedPreference.JSON_DATA, jsonData.toString()); } } My JSONManager : //Create list of Cards because we need to show list for date selected public List<Card> readJSON(String dateFromCalendar) throws JSONException { String JSON = SharedPreference.getString(Util.get(), SharedPreference.APP_DATA, SharedPreference.JSON_DATA, ""); String numeVanzator = SharedPreference.getString(Util.get(), SharedPreference.USER_DATA, SharedPreference.NUME_VANZATOR,""); JSONObject jsonObj = new JSONObject(JSON); JSONArray contacts = jsonObj.getJSONArray("jsonData"); List<Card> listCard = null; Card card = null; listCard = new ArrayList<>(); for (int i =0; i< contacts.length();i++) { JSONObject c = contacts.getJSONObject(i); String data = c.getString("data"); if (data.equals(dateFromCalendar)){ String numeVanzato = c.getString("numeVanzator"); if (numeVanzato.equals(numeVanzator)){ String numarClient = c.getString("numarClient"); String sumaProduse = c.getString("sumaProduse"); String produseselectate = c.getString("produseSelectate"); card = new Card(numarClient, produseselectate, sumaProduse); listCard.add(card); } } } return listCard; }} Card Object : public class Card { public String numarCumparator; public String listaProduse; public String sumaProduse; public Card(String numarCumparator, String listaProduse, String sumaProduse) { this.numarCumparator = numarCumparator; this.listaProduse = listaProduse; this.sumaProduse = sumaProduse; } public Card() { } public String getNumarCumparator() { return numarCumparator; } public void setNumarCumparator(String numarCumparator) { this.numarCumparator = numarCumparator; } public String getListaProduse() { return listaProduse; } public void setListaProduse(String listaProduse) { this.listaProduse = listaProduse; } public String getSumaProduse() { return sumaProduse; } public void setSumaProduse(String sumaProduse) { this.sumaProduse = sumaProduse; } } Card Adapter : public class CardArrayAdapter extends ArrayAdapter<Card> { private static final String TAG = "CardArrayAdapter"; private List<Card> cardList = new ArrayList<Card>(); static class CardViewHolder { TextView line1; TextView line2; TextView line3; } public CardArrayAdapter(Context context, int textViewResourceId) { super(context, textViewResourceId); } #Override public void add(Card object) { cardList.add(object); super.add(object); } #Override public int getCount() { return this.cardList.size(); } #Override public Card getItem(int index) { return this.cardList.get(index); } #Override public View getView(int position, View convertView, ViewGroup parent) { View row = convertView; CardViewHolder viewHolder; if (row == null) { LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); row = inflater.inflate(R.layout.list_item_card, parent, false); viewHolder = new CardViewHolder(); viewHolder.line1 = (TextView) row.findViewById(R.id.txtViewNumarCumparator); viewHolder.line2 = (TextView) row.findViewById(R.id.listaProduse); viewHolder.line3 = (TextView) row.findViewById(R.id.sumaProduse); row.setTag(viewHolder); } else { viewHolder = (CardViewHolder)row.getTag(); } Card card = getItem(position); viewHolder.line1.setText(card.getNumarCumparator()); viewHolder.line2.setText(card.getListaProduse()); viewHolder.line3.setText(card.getSumaProduse()); return row; } public Bitmap decodeToBitmap(byte[] decodedByte) { return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length); } } Layout for Card: <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="15dp" android:paddingRight="15dp" android:descendantFocusability="beforeDescendants"> <RelativeLayout android:layout_width="match_parent" android:layout_height="100dp" android:descendantFocusability="afterDescendants" android:orientation="vertical" android:paddingBottom="15dp" android:paddingLeft="15dp" android:paddingRight="15dp" android:paddingTop="15dp"> <TextView android:id="#+id/txtViewNumarCumparator" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:text="NumarCumparator" /> <TextView android:id="#+id/listaProduse" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="#+id/txtViewNumarCumparator" android:layout_marginTop="10dp" android:text="NumarProduse" /> <TextView android:id="#+id/sumaProduse" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginTop="15dp" android:text="SumaProdsue" /> </RelativeLayout> Layout for ListView: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#color/gray_color"> <ListView android:id="#+id/listViewVanzatorActivity" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_above="#+id/btnAdaugaProduse" android:layout_below="#+id/textViewDataCurenta"/> </RelativeLayout> Hope you understand my question..
The standard way to send data from Activity to another is to pass parcelable data in the Intent bundle. Make card implement Parcelable Pass the items to the intent public void startSecondActivity(List<Card> cards) { Intent i = new Intent(this, SecondActivity.class); i.putParcelableArrayListExtra("EXTRA_CARDS", new ArrayList<Card>(cards)); startActivity(i); } Retrieve it like this in the second activity Bundle bundle = getIntent().getExtras(); List<Card> cards = (ArrayList<Card>)bundle.getParcelableArrayList("EXTRA_CARDS");
Parse API Data into TextView
I have a API link that has a json element named title, and I am trying to store that value into a textview. Here is what I have so far in my main activity code that is supposed to display the contained string: #Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); JSONObject jObject; try { jObject = new JSONObject("https://chex-triplebyte.herokuapp.com/api/cats?page=0"); String mResponse = jObject.getString("title"); TextView t = (TextView) findViewById(R.id.title_image); t.setText(mResponse); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } The API link I provided works so you can see the value title that I am trying to obtain.
try this: TextView t = (TextView) findViewById(R.id.title_image); try { url = new URL("https://chex-triplebyte.herokuapp.com/api/cats?page=0"); urlConnection = (HttpURLConnection) url .openConnection(); urlConnection.connect(); InputStream in = urlConnection.getInputStream(); reader = new BufferedReader(new InputStreamReader(in)); //InputStreamReader isw = new InputStreamReader(in); StringBuffer buffer = new StringBuffer(); String line = ""; while ((line = reader.readLine()) != null) { buffer.append(line); } String JsonResponse= buffer.toString(); JSONObject jsonobj = new JSONObject(JsonResponse); JSONArray jarray = jsono.getJSONArray("jsontitle"); for (int i = 0; i < jarray.length(); i++) { JSONObject object = jarray.getJSONObject(i); t.setText(object.getString("title")); } } catch (JSONException e) { e.printStackTrace(); } but you have to make sure you have a correct json format like this: {jsontitle:[{"title":"Space Keybaord Cat","timestamp":"2017-09-11T04:00:04Z","image_url":"https://triplebyte-cats.s3.amazonaws.com/space.jpg","description":"In space, no one can hear you purr."},{"title":"Jiji","timestamp":"2017-09-11T03:00:04Z","image_url":"https://triplebyte-cats.s3.amazonaws.com/jiji.png","description":"You'd think they'd never seen a girl and a cat on a broom before"},{"title":"Limecat","timestamp":"2017-09-11T02:00:04Z","image_url":"https://triplebyte-cats.s3.amazonaws.com/lime.jpg","description":"Destroyer of Clockspider and his evil followers, Limecat is the one true god."},{"title":"Astronaut Cat","timestamp":"2017-09-11T01:00:04Z","image_url":"https://triplebyte-cats.s3.amazonaws.com/astronaut.jpg","description":"Houston, we have a purroblem"},{"title":"Grumpy Cat","timestamp":"2017-09-11T00:00:04Z","image_url":"https://triplebyte-cats.s3.amazonaws.com/grumpy.jpg","description":"Queen of the RBF"},{"title":"Soviet cat","timestamp":"2017-09-10T23:00:04Z","image_url":"https://triplebyte-cats.s3.amazonaws.com/soviet.jpg","description":"In soviet Russia cat pets you!"},{"title":"Serious Business Cat","timestamp":"2017-09-10T22:00:04Z","image_url":"https://triplebyte-cats.s3.amazonaws.com/serious.jpg","description":"SRSLY GUISE"},{"title":"Sophisticated Cat","timestamp":"2017-09-10T21:00:04Z","image_url":"https://triplebyte-cats.s3.amazonaws.com/sophisticated.PNG","description":"I should buy a boat"},{"title":"Shironeko","timestamp":"2017-09-10T20:00:04Z","image_url":"https://triplebyte-cats.s3.amazonaws.com/shironeko.png","description":"The zen master kitty"},{"title":"Puss in Boots","timestamp":"2017-09-10T19:00:04Z","image_url":"https://triplebyte-cats.s3.amazonaws.com/puss.jpg","description":"Don't you dare do the litter box on me!"}]}
You need to make a network call first parse it to JSONArray first and then get the title from the JSON #Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView t = (TextView) findViewById(R.id.title_image); RequestQueue queue = Volley.newRequestQueue(this); String url ="https://chex-triplebyte.herokuapp.com/api/cats?page=0"; // Request a string response from the provided URL. StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { #Override public void onResponse(String response) { JSONArray jArray; try { jArray = new JSONArray(response); JSONObject jObject = jArray.getJSONObject(0); String mResponse = jObject.getString("title"); t.setText(mResponse); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }, new Response.ErrorListener() { #Override public void onErrorResponse(VolleyError error) { } }); // Add the request to the RequestQueue. queue.add(stringRequest); } But this will only show the first title in the response array If you want to show all titles appended then you can loop over the array JSONArray jArray; try { jArray = new JSONArray(response); String mResponse = ""; for(int i=0 ;i<jArray.length();i++){ JSONObject jObject = jArray.getJSONObject(i); mResponse += jObject.getString("title")+" "; } t.setText(mResponse); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } For using volley you need to include it in dependencies in build.gradle of app dependencies { . . compile 'com.android.volley:volley:1.0.0' . . }
Try this... MainActivity.java public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private String TAG = MainActivity.class.getSimpleName(); private ListView listView; List<RowItem> rowItems; #Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list); rowItems = new ArrayList<RowItem>(); listView = (ListView) findViewById(R.id.item_list); new GetList().execute(); } #Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast toast = Toast.makeText(getApplicationContext(), "Item " + (position + 1) + ": " + rowItems.get(position), Toast.LENGTH_SHORT); toast.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0); toast.show(); } class GetList extends AsyncTask<Void, Void, List<RowItem>> { #Override protected void onPreExecute() { super.onPreExecute(); Toast.makeText(MainActivity.this, "Json Data is downloading", Toast.LENGTH_LONG).show(); } #Override protected List<RowItem> doInBackground(Void... arg0) { HttpHandler sh = new HttpHandler(); // Making a request to url and getting response String url = "https://chex-triplebyte.herokuapp.com/api/cats?page=0"; String jsonStr = sh.makeServiceCall(url); Log.e(TAG, "Response from url: " + jsonStr); if (jsonStr != null) { try { JSONArray list = new JSONArray(jsonStr); for (int i = 0; i < list.length(); i++) { JSONObject c = list.getJSONObject(i); String title = c.getString("title"); String timestamp = c.getString("timestamp"); String image_url = c.getString("image_url"); String description = c.getString("description"); RowItem item = new RowItem(); item.setTitle(title); item.setTimestamp(timestamp); item.setImageUrl(image_url); item.setDescription(description); rowItems.add(item); } } catch (final JSONException e) { Log.e(TAG, "Json parsing error: " + e.getMessage()); runOnUiThread(new Runnable() { #Override public void run() { Toast.makeText(getApplicationContext(), "Json parsing error: " + e.getMessage(), Toast.LENGTH_LONG).show(); } }); } } else { Log.e(TAG, "Couldn't get json from server."); runOnUiThread(new Runnable() { #Override public void run() { Toast.makeText(getApplicationContext(), "Couldn't get json from server. Check LogCat for possible errors!", Toast.LENGTH_LONG).show(); } }); } return rowItems; } #Override protected void onPostExecute(List<RowItem> rowItems) { super.onPostExecute(rowItems); if (rowItems != null) { CustomListViewAdapter adapter = new CustomListViewAdapter(MainActivity.this, R.layout.list_item, rowItems); listView.setAdapter(adapter); } } } } CustomListViewAdapter.java public class CustomListViewAdapter extends ArrayAdapter<RowItem> { private Context context; public CustomListViewAdapter(Context context, int resourceId, List<RowItem> items) { super(context, resourceId, items); this.context = context; } /*private view holder class*/ private class ViewHolder { ImageView imageView; TextView txtTitle; TextView txtDesc; } public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; RowItem rowItem = getItem(position); LayoutInflater mInflater = (LayoutInflater) context .getSystemService(Activity.LAYOUT_INFLATER_SERVICE); if (convertView == null) { convertView = mInflater.inflate(R.layout.list_item, null); holder = new ViewHolder(); holder.txtDesc = (TextView) convertView.findViewById(R.id.description); holder.txtTitle = (TextView) convertView.findViewById(R.id.title); holder.imageView = (ImageView) convertView.findViewById(R.id.preview); convertView.setTag(holder); } else holder = (ViewHolder) convertView.getTag(); holder.txtDesc.setText(rowItem.getDescription()); holder.txtTitle.setText(rowItem.getTitle()); String url = rowItem.getImageUrl(); DownloadImageTask downloadImageTask = new DownloadImageTask(holder.imageView); downloadImageTask.execute(url); return convertView; } private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { ImageView bmImage; public DownloadImageTask(ImageView bmImage) { this.bmImage = bmImage; } protected Bitmap doInBackground(String... urls) { String urldisplay = urls[0]; Bitmap mIcon11 = null; try { InputStream in = new java.net.URL(urldisplay).openStream(); mIcon11 = BitmapFactory.decodeStream(in); } catch (Exception e) { Log.e("Error", e.getMessage()); e.printStackTrace(); } return mIcon11; } protected void onPostExecute(Bitmap result) { bmImage.setImageBitmap(result); } } } RowItem.java public class RowItem { private String title; private String timestamp; private String imageUrl; private String description; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getTimestamp() { return timestamp; } public void setTimestamp(String timestamp) { this.timestamp = timestamp; } public String getImageUrl() { return imageUrl; } public void setImageUrl(String imageUrl) { this.imageUrl = imageUrl; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } list_item.xml <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:id="#+id/linearLayout2"> <ImageView android:id="#+id/preview" android:layout_width="80dp" android:layout_height="80dp" app:srcCompat="#mipmap/ic_launcher" android:contentDescription="#string/app_name" /> <TextView android:id="#+id/title" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:layout_marginTop="16dp" android:text="#string/app_name" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="#+id/preview" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="#+id/description" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:text="#string/app_name" app:layout_constraintBottom_toBottomOf="#+id/preview" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="#+id/preview" app:layout_constraintTop_toBottomOf="#+id/title" /> </android.support.constraint.ConstraintLayout> HttpHandler.java public class HttpHandler { private static final String TAG = HttpHandler.class.getSimpleName(); public HttpHandler() { } public String makeServiceCall(String reqUrl) { String response = null; try { URL url = new URL(reqUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); // read the response InputStream in = new BufferedInputStream(conn.getInputStream()); response = convertStreamToString(in); } catch (MalformedURLException e) { Log.e(TAG, "MalformedURLException: " + e.getMessage()); } catch (ProtocolException e) { Log.e(TAG, "ProtocolException: " + e.getMessage()); } catch (IOException e) { Log.e(TAG, "IOException: " + e.getMessage()); } catch (Exception e) { Log.e(TAG, "Exception: " + e.getMessage()); } return response; } private String convertStreamToString(InputStream is) { BufferedReader reader = new BufferedReader(new InputStreamReader(is)); StringBuilder sb = new StringBuilder(); String line; try { while ((line = reader.readLine()) != null) { sb.append(line).append('\n'); } } catch (IOException e) { e.printStackTrace(); } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } return sb.toString(); } } activity_list.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="#+id/item_list" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> Note: item_list.xml has ConstraintLayout implementation. Result:
ListView onScroll add more items
private class getArticles extends AsyncTask<Void, Void, Void> { String url; getArticles(String paramUrl) { this.url = paramUrl; } #Override protected void onPreExecute() { super.onPreExecute(); mProgressDialog = new ProgressDialog(App.this); mProgressDialog.setMessage("Učitavanje artikala..."); mProgressDialog.setIndeterminate(false); mProgressDialog.setCancelable(false); mProgressDialog.show(); } #Override protected Void doInBackground(Void... params) { arraylist = new ArrayList<>(); try { Document document = Jsoup.connect(url).get(); Elements els = document.select("ul.category3 > li"); for (Element el : els) { HashMap<String, String> map = new HashMap<>(); Elements slika = el.select("div.category3-image > a > img"); Elements naslov = el.select("div.category3-text > a.main-headline"); Element datum_noformat = el.select("div.category3-text > div.headlines-info > ul.headlines-info > li").first(); Element datum = datum_noformat.html(datum_noformat.html().replaceAll("Posted ", "")); Elements desc = el.select("div.category3-text > p"); Elements link = el.select("div.category3-text > a.main-headline"); Element br_kom = el.select("div.category3-text > div.headlines-info > ul.headlines-info > li.comments-icon").first(); map.put("naslov", naslov.text()); map.put("datum", datum.text()); map.put("desc", desc.text()); map.put("ikona", slika.attr("src")); map.put("link", link.attr("abs:href")); map.put("brkom", br_kom.text()); arraylist.add(map); } } catch (IOException e) { e.printStackTrace(); } return null; } #Override protected void onPostExecute(Void result) { listview = (ListView) findViewById(R.id.listview); adapter = new ArtikliAdapter(App.this, arraylist); listview.setAdapter(adapter); mProgressDialog.dismiss(); } I searched for a lot of codes for onlistview scrolling, but didn't know how to implement it. The problem is, when I call my asynctask, I have an url param, like new getArticles("http://example.com").execute(); I want to implement an onscrolllistener, but it goes like this, my param is usually set to: http://www.example.com/category/categoryname/, so the second page goes like http://www.example.com/category/categoryname/page/2/, the third one goes http://www.example.com/category/categoryname/page/3/ and so on. Each page has got 7 items that need to be parsed. How could I implement onscrolllistener, because of the url param? Thanks in advance.
Base on this link, I have written following solution to add elements ( 30 elements at a time, i.e page size = 30) to listview asynchronously. Create a class named EndlessListView as follows: public class EndlessListView extends ListView implements OnScrollListener { private View footer; private boolean isLoading; private EndlessListener listener;// listner private EndlessAdapter endlessAdapter;// adapter. private int maxNoOfElement; public EndlessListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); this.setOnScrollListener(this); } public EndlessListView(Context context, AttributeSet attrs) { super(context, attrs); this.setOnScrollListener(this); } public EndlessListView(Context context) { super(context); this.setOnScrollListener(this); } public void setListener(EndlessListener listener) { this.listener = listener; } #Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (getAdapter() == null) return; if (getAdapter().getCount() == 0 || getAdapter().getCount() <= 5) return; int l = visibleItemCount + firstVisibleItem; if (l >= totalItemCount && !isLoading) { // It is time to add new data. We call the listener Log.e("LOAD", "DATA"); isLoading = true; listener.loadData(); } } public void setMaxElemnt(int maxNoOfElement) { this.maxNoOfElement = maxNoOfElement; } #Override public void onScrollStateChanged(AbsListView view, int scrollState) { } public void setLoadingView(int resId) { LayoutInflater inflater = (LayoutInflater) super.getContext() .getSystemService(Context.LAYOUT_INFLATER_SERVICE); footer = (View) inflater.inflate(resId, null); this.addFooterView(footer); } public void setAdapter(EndlessAdapter adapter) { super.setAdapter(adapter); this.endlessAdapter = adapter; } public void addNewData(List<Integer> data) { endlessAdapter.setData(data); endlessAdapter.notifyDataSetChanged(); isLoading = false; } public static interface EndlessListener { public void loadData(); } } After this we have to create the adapter for it,called EndlessAdapter public class EndlessAdapter extends BaseAdapter { private List<Integer> mIntegers; private Context context; public EndlessAdapter(Context context) { this.context = context; } public void setData(List<Integer> mIntegers) { this.mIntegers = mIntegers; } #Override public int getCount() { if (mIntegers == null) return 0; return mIntegers.size(); } #Override public Integer getItem(int index) { if (mIntegers == null) { return null; } else { return mIntegers.get(index); } } #Override public long getItemId(int arg0) { // TODO Auto-generated method stub return 0; } class ViewHolder { TextView textView; } #Override public View getView(int index, View view, ViewGroup viewGroup) { ViewHolder holder; if (view == null) { holder = new ViewHolder(); view = ((LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE)) .inflate(R.layout.rows, viewGroup, false); holder.textView = (TextView) view.findViewById(R.id.mtext); view.setTag(holder); } else { holder = (ViewHolder) view.getTag(); } holder.textView.setText(getItem(index) + ""); return view; } } Now in xml of the activity we could use EndlessListView(in com.example.stackoverflow package) as follows : <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <com.example.stackoverflow.EndlessListView android:id="#+id/endlessListView" android:layout_width="match_parent" android:layout_height="wrap_content" /> </RelativeLayout> After this step we need to make following change in the MainActivity public class MainActivity extends Activity implements EndlessListener { private EndlessAdapter adapter; private EndlessListView endlessListView; private List<Integer> data; private int gStartIndex = 30; #Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); endlessListView = (EndlessListView) findViewById(R.id.endlessListView); adapter = new EndlessAdapter(this); data = new ArrayList<Integer>(); endlessListView.setLoadingView(R.layout.footer); // endlessListView.showFooter(); endlessListView.setListener(this); endlessListView.setAdapter(adapter); gStartIndex = 0; fillData(gStartIndex); } private void fillData(int startIndex) { new AsyncLoadData().execute(startIndex); } #Override public void loadData() { fillData(gStartIndex); } private class AsyncLoadData extends AsyncTask<Integer, Integer, Void> { #Override protected Void doInBackground(Integer... params) { int gendIndex = params[0] + 30; gStartIndex = gendIndex; /*** * Here you could add your n/w code. To simulate the n/w comm. i am * adding elements to list and making it sleep for few sec. * */ for (int i = params[0]; i < gendIndex; i++) { publishProgress(i); } try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } #Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); data.add(values[0]); } #Override protected void onPostExecute(Void result) { endlessListView.addNewData(data); } } }
This custom ScrollListView that I just found has OnBottomReachedListener which you can implement from your Activity or Fragment and receive events when user hits the bottom of the page. You would also need to track the current page and when bottom is hit to download the next page. The latest data should be added to your existing ArrayList and you should call notifyDataSetChanged() on your adapter so ListView can render the new data. You don't have to create new adapter, you just need to update the data source which is your ArrayList. If you support orientation change you would must to save in onSaveInstanceState() your current page number so when Activity or Fragment is recreated it can continue from correct page. And you would have to keep the ArrayList data source safe of configuration changes because you don't want to downloaded it again. I would suggest using the Fragment with setRetainInstance() set to true to persist ArrayList. Here is my custom code for keeping data around using RetainFragment: /** * A simple non-UI Fragment that stores a single Object * and is retained over configuration changes. */ public class RetainFragment<E extends Object> extends Fragment { /** Object for retaining. */ private E mObject; /** * Empty constructor as per the Fragment documentation */ public RetainFragment() {} #Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Make sure this Fragment is retained over a configuration change setRetainInstance(true); } /** * Store a single object in this Fragment. * * #param object The object to store */ public void setObject(E object) { mObject = object; } /** * Get the stored object. * * #return The stored object */ public E getObject() { return mObject; } } Example of RetainFragment usage in your Activity: FragmentManager fm = getFragmentManager(); mRetainFragment = (RetainFragment<ArrayList>) fm.findFragmentByTag(RETAIN_FRAG); if (mRetainFragment == null) { mRetainFragment = new RetainFragment<>(); mRetainFragment.setObject(new ArrayList()); fm.beginTransaction().add(mRetainFragment, RETAIN_FRAG).commit(); } ArrayList yourArrayList = mRetainFragment.getObject(); // Now your ArrayList is saved accrossed configuration changes
here what you want fist add onscrolllistner to listview boolean loading_flage = false; yourlistview.setOnScrollListener(new OnScrollListener() { #Override public void onScrollStateChanged( AbsListView view, int scrollState) { // TODO Auto-generated method stub } #Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { final int lastItem = firstVisibleItem + visibleItemCount; if ((lastItem == totalItemCount) & loading_flage == false) { //this to prevent the list to make more than one request in time loading_flage = true; //you can put the index for your next page here loadMore(int page); } } }); and then in loading more after loading the page set the loading with false and parse the data add it to the data that you aleardy have //notify the adapter adapter.notifyDataSetChanged(); loading_flage = false;
You can achieve by adding the scrolllistener on listview and check condition if list last visible item is last in ArrayList then call the asynctask with incremented page number and update the listview,mean while add the view on listview and after getting the result from server remove the loading more view from the listview like this - AndroidListViewLoadMoreActivity.java public class AndroidListViewLoadMoreActivity extends Activity { ArrayList<Country> countryList; MyCustomAdapter dataAdapter = null; int page = 0; boolean loadingMore = false; View loadMoreView; #Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ListView listView = (ListView) findViewById(R.id.listView1); loadMoreView = ((LayoutInflater)this .getSystemService(Context.LAYOUT_INFLATER_SERVICE)) .inflate(R.layout.loadmore, null, false); listView.addFooterView(loadMoreView); //create an ArrayAdaptar from the String Array countryList = new ArrayList<Country>(); dataAdapter = new MyCustomAdapter(this, R.layout.country_info, countryList); listView.setAdapter(dataAdapter); //enables filtering for the contents of the given ListView listView.setTextFilterEnabled(true); listView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // When clicked, show a toast with the TextView text Country country = (Country) parent.getItemAtPosition(position); Toast.makeText(getApplicationContext(), country.getCode(), Toast.LENGTH_SHORT).show(); } }); listView.setOnScrollListener(new OnScrollListener(){ #Override public void onScrollStateChanged(AbsListView view, int scrollState) {} #Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { int lastInScreen = firstVisibleItem + visibleItemCount; if((lastInScreen == totalItemCount) && !(loadingMore)){ String url = "http://10.0.2.2:8080/CountryWebService" + "/CountryServlet"; grabURL(url); } } }); String url = "http://example.com"; grabURL(url); } public void grabURL(String url) { Log.v("Android Spinner JSON Data Activity", url); new GrabURL().execute(url); } private class GrabURL extends AsyncTask<String, Void, String> { private static final int REGISTRATION_TIMEOUT = 3 * 1000; private static final int WAIT_TIMEOUT = 30 * 1000; private final HttpClient httpclient = new DefaultHttpClient(); final HttpParams params = httpclient.getParams(); HttpResponse response; private String content = null; private boolean error = false; private ProgressDialog dialog = new ProgressDialog(AndroidListViewLoadMoreActivity.this); protected void onPreExecute() { dialog.setMessage("Getting your data... Please wait..."); dialog.show(); } protected String doInBackground(String... urls) { String URL = null; loadingMore = true; try { URL = urls[0]; HttpConnectionParams.setConnectionTimeout(params, REGISTRATION_TIMEOUT); HttpConnectionParams.setSoTimeout(params, WAIT_TIMEOUT); ConnManagerParams.setTimeout(params, WAIT_TIMEOUT); HttpPost httpPost = new HttpPost(URL); //add name value pair for the country code List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); nameValuePairs.add(new BasicNameValuePair("page",String.valueOf(page))); httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); response = httpclient.execute(httpPost); StatusLine statusLine = response.getStatusLine(); if(statusLine.getStatusCode() == HttpStatus.SC_OK){ ByteArrayOutputStream out = new ByteArrayOutputStream(); response.getEntity().writeTo(out); out.close(); content = out.toString(); } else{ //Closes the connection. Log.w("HTTP1:",statusLine.getReasonPhrase()); response.getEntity().getContent().close(); throw new IOException(statusLine.getReasonPhrase()); } } catch (ClientProtocolException e) { Log.w("HTTP2:",e ); content = e.getMessage(); error = true; cancel(true); } catch (IOException e) { Log.w("HTTP3:",e ); content = e.getMessage(); error = true; cancel(true); }catch (Exception e) { Log.w("HTTP4:",e ); content = e.getMessage(); error = true; cancel(true); } return content; } protected void onCancelled() { dialog.dismiss(); Toast toast = Toast.makeText(AndroidListViewLoadMoreActivity.this, "Error connecting to Server", Toast.LENGTH_LONG); toast.setGravity(Gravity.TOP, 25, 400); toast.show(); } protected void onPostExecute(String content) { dialog.dismiss(); Toast toast; if (error) { toast = Toast.makeText(AndroidListViewLoadMoreActivity.this, content, Toast.LENGTH_LONG); toast.setGravity(Gravity.TOP, 25, 400); toast.show(); } else { displayCountryList(content); } } } private void displayCountryList(String response){ JSONObject responseObj = null; try { Gson gson = new Gson(); responseObj = new JSONObject(response); JSONArray countryListObj = responseObj.getJSONArray("countryList"); //countryList = new ArrayList<Country>(); if(countryListObj.length() == 0){ ListView listView = (ListView) findViewById(R.id.listView1); listView.removeFooterView(loadMoreView); } else { for (int i=0; i<countryListObj.length(); i++){ //get the country information JSON object String countryInfo = countryListObj.getJSONObject(i).toString(); //create java object from the JSON object Country country = gson.fromJson(countryInfo, Country.class); //add to country array list countryList.add(country); dataAdapter.add(country); } page++; dataAdapter.notifyDataSetChanged(); loadingMore = false; } } catch (JSONException e) { e.printStackTrace(); } } } Make MyCustomAdapter.java as adapter private class MyCustomAdapter extends ArrayAdapter<Country> { private ArrayList<Country> countryList; public MyCustomAdapter(Context context, int textViewResourceId, ArrayList<Country> countryList) { super(context, textViewResourceId, countryList); this.countryList = new ArrayList<Country>(); this.countryList.addAll(countryList); } private class ViewHolder { TextView code; TextView name; TextView continent; TextView region; } public void add(Country country){ Log.v("AddView", country.getCode()); this.countryList.add(country); } #Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; Log.v("ConvertView", String.valueOf(position)); if (convertView == null) { LayoutInflater vi = (LayoutInflater)getSystemService( Context.LAYOUT_INFLATER_SERVICE); convertView = vi.inflate(R.layout.country_info, null); holder = new ViewHolder(); holder.code = (TextView) convertView.findViewById(R.id.code); holder.name = (TextView) convertView.findViewById(R.id.name); holder.continent = (TextView) convertView.findViewById(R.id.continent); holder.region = (TextView) convertView.findViewById(R.id.region); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } Country country = this.countryList.get(position); holder.code.setText(country.getCode()); holder.name.setText(country.getName()); holder.continent.setText(country.getContinent()); holder.region.setText(country.getRegion()); return convertView; } } } Create Country.Java as pojo - public class Country { String code = null; String name = null; String continent = null; String region = null; Double lifeExpectancy = null; Double gnp = null; Double surfaceArea = null; int population = 0; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getContinent() { return continent; } public void setContinent(String continent) { this.continent = continent; } public String getRegion() { return region; } public void setRegion(String region) { this.region = region; } public Double getLifeExpectancy() { return lifeExpectancy; } public void setLifeExpectancy(Double lifeExpectancy) { this.lifeExpectancy = lifeExpectancy; } public Double getGnp() { return gnp; } public void setGnp(Double gnp) { this.gnp = gnp; } public Double getSurfaceArea() { return surfaceArea; } public void setSurfaceArea(Double surfaceArea) { this.surfaceArea = surfaceArea; } public int getPopulation() { return population; } public void setPopulation(int population) { this.population = population; } } Create main.xml for main layout <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="10dp" android:text="#string/some_text" android:textSize="20sp" /> <ListView android:id="#+id/listView1" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> Create country_info.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="6dip" > <TextView android:id="#+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:text="Code: " android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="#+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="#+id/textView1" android:layout_below="#+id/textView1" android:text="Name: " android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="#+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="#+id/textView2" android:layout_below="#+id/textView2" android:text="Continent: " android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="#+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="#+id/textView3" android:layout_below="#+id/textView3" android:text="Region: " android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="#+id/continent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="#+id/textView3" android:layout_alignBottom="#+id/textView3" android:layout_toRightOf="#+id/textView3" android:text="TextView" /> <TextView android:id="#+id/region" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="#+id/textView4" android:layout_alignBottom="#+id/textView4" android:layout_alignLeft="#+id/continent" android:text="TextView" /> <TextView android:id="#+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="#+id/textView3" android:layout_toRightOf="#+id/textView3" android:text="TextView" /> <TextView android:id="#+id/code" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="#+id/textView2" android:layout_alignLeft="#+id/name" android:text="TextView" /> </RelativeLayout> Footer View Text - loadmore.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:gravity="center_horizontal" android:padding="3dp" android:layout_height="fill_parent"> <TextView android:id="#id/android:empty" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center" android:padding="5dp" android:text="Loading more data..."/> </LinearLayout> Don't forget to mention internet permission with - <uses-permission android:name="android.permission.INTERNET" />
First, you need a OnScrollListener method like this: private OnScrollListener onScrollListener() { return new OnScrollListener() { #Override public void onScrollStateChanged(AbsListView view, int scrollState) { int threshold = 1; int count = listView.getCount(); if (scrollState == SCROLL_STATE_IDLE) { if (listView.getLastVisiblePosition() >= count - threshold && pageCount < 2) { Log.i(TAG, "loading more data"); // Execute LoadMoreDataTask AsyncTask //It reached ListView bottom getDataFromUrl(url_page2); } } } #Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }; } set List View scroll listener by listView.setOnScrollListener(onScrollListener()); I have a full tutorial post HERE! You can visit it!
Replacing JSON Populated TextView with JSON Populated ListView [duplicate]
This question already has an answer here: JSON String is incorrectly mapped to textviews (1 answer) Closed 9 years ago. I have a JSON request which returns a response from youtube containing the comments for a particular video. I currently have 3 textviews: one for the name/uploader, one for the content, and one for the date published - which are then populated with the data from my JSON response. My problem is - only the first comment, date published and uploader appear. I belive I'll need to replace my textviews with a list view and parse the 3 fields to it - I simply do not know how. JAVA public class Player extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener { public static final String API_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; #Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.player); String title = getIntent().getStringExtra("title"); String uploader = getIntent().getStringExtra("uploader"); String viewCount = getIntent().getStringExtra("viewCount"); TextView titleTv = (TextView) findViewById(R.id.titleTv); TextView uploaderTv = (TextView) findViewById(R.id.uploaderTv); TextView viewCountTv = (TextView) findViewById(R.id.viewCountTv); titleTv.setText(title); uploaderTv.setText("by" + uploader + " |"); viewCountTv.setText(viewCount + " views"); YouTubePlayerView youTubePlayerView = (YouTubePlayerView) findViewById(R.id.youtubeplayerview); youTubePlayerView.initialize(API_KEY, this); Handler handler = new Handler(new Handler.Callback() { #Override public boolean handleMessage(Message msg) { return false; } }); GetYouTubeUserCommentsTask task = new GetYouTubeUserCommentsTask(handler , viewCount); task.execute(); } #Override public void onInitializationFailure(Provider provider, YouTubeInitializationResult result) { Toast.makeText(getApplicationContext(), "onInitializationFailure()", Toast.LENGTH_LONG).show(); } #Override public void onInitializationSuccess(Provider provider, YouTubePlayer player, boolean wasRestored) { if (!wasRestored) { String video_id = getIntent().getStringExtra("id"); player.loadVideo(video_id); } } public final class GetYouTubeUserCommentsTask extends AsyncTask<Void, Void, Void> { public static final String LIBRARY = "CommentsLibrary"; private final Handler replyTo; private final String username; String video_id = getIntent().getStringExtra("id"); public GetYouTubeUserCommentsTask(Handler replyTo, String username) { this.replyTo = replyTo; this.username = username; } #Override protected Void doInBackground(Void... arg0) { try { HttpClient client = new DefaultHttpClient(); HttpUriRequest request = new HttpGet( "http://gdata.youtube.com/feeds/api/videos/" + video_id + "/comments?v=2&alt=json&start-index=1&max-results=50&prettyprint=true"); HttpResponse response = client.execute(request); String jsonString = StreamUtils.convertToString(response .getEntity().getContent()); JSONObject json = new JSONObject(jsonString); JSONArray jsonArray = json.getJSONObject("feed").getJSONArray( "entry"); List<Comments> comments = new ArrayList<Comments>(); for (int i = 0; i < jsonArray.length(); i++) { JSONObject entry = jsonArray.getJSONObject(i); JSONArray authorArray = entry.getJSONArray("author"); JSONObject publishedObject = entry.getJSONObject("published"); String published = publishedObject.getString("$t"); JSONObject contentObject = entry.getJSONObject("content"); String content = contentObject.getString("$t"); JSONObject authorObject = authorArray.getJSONObject(0); JSONObject nameObject = authorObject.getJSONObject("name"); String name = nameObject.getString("$t"); comments.add(new Comments(name, content, published)); CommentsLibrary lib = new CommentsLibrary(published, content, name); Bundle data = new Bundle(); data.putSerializable(LIBRARY, lib); Message msg = Message.obtain(); msg.setData(data); replyTo.sendMessage(msg); } } catch (ClientProtocolException e) { Log.e("Feck", e); } catch (IOException e) { Log.e("Feck", e); } catch (JSONException e) { Log.e("Feck", e); } return null; } #Override protected void onPostExecute(Void result) { ListView comments = (ListView) findViewById(R.id.comments); comments.setFilterText(com.idg.omv.domain.CommentsLibrary.getName()); } } } CommentsLibrary public class CommentsLibrary implements Serializable{ // The username of the owner of the comment private static String name; // The comment private static String content; // The date the comment was published private static String published; public CommentsLibrary(String name, String content, String published) { this.name = name; this.content = content; this.published = published; } /** * #return the user name */ public static String getName() { return name; } /** * #return the videos */ public static String getContent() { return content; } /** * #return the videos */ public static String getPublished() { return published; } } XML <TextView android:id="#+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:text="" /> <TextView android:id="#+id/content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="#id/name" android:layout_weight="1" android:gravity="left" android:text="" /> <TextView android:id="#+id/published" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="#id/content" android:layout_weight="1" android:gravity="left" android:text="" />
Continuing my answer from your previous question # JSON String is incorrectly mapped to textviews First you need a listview in your layout xml <ListView android:id="#+id/list" android:layout_width="wrap_content" android:layout_height="wrap_content" /> Declare list as a instance variable ArrayList<CommentsLibrary> list = new ArrayList<CommentsLibrary>(); Then for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); String name = jsonObject.optString("name","defaultValue"); String content = jsonObject.optString("content","defaultValue"); String published = jsonObject.optString("published","defaultValue"); list.add(new CommentsLibrary(name, content, published)); } Then initialize listview ListView lv =(ListView)findViewById(R.id.list); CustomAdapter cus = new CustomAdapter(ActivityName.this,list); lv.setAdapter(cus); Define a custom layout with 3 textviews. (list_item.xml) <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="#+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="18dp" android:layout_marginTop="31dp" android:text="TextView" /> <TextView android:id="#+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="#+id/textView1" android:layout_alignBottom="#+id/textView1" android:layout_centerHorizontal="true" android:text="TextView" /> <TextView android:id="#+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="#+id/textView2" android:layout_alignBottom="#+id/textView2" android:layout_alignParentRight="true" android:layout_marginRight="24dp" android:text="TextView" /> </RelativeLayout> Then define a custom adapter by extending a base adapter. Override getView inflate the custom layout and set text views there. public class CustomAdapter extends BaseAdapter { LayoutInfalter mInflater; ArrayList<CommentsLibrary> list; public CustomAdapter(Context context,ArrayList<CommentsLibrary> list) { mInflater = LayoutInfalter.from(context); this.list = list; } #Override public int getCount() { // TODO Auto-generated method stub return list.size(); } #Override public Object getItem(int position) { // TODO Auto-generated method stub return position; } #Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } #Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ViewHolder holder; if(convertView==null) { convertView =minflater.inflate(R.layout.list_item, parent,false); holder = new ViewHolder(); holder.tv1 = (TextView) convertView.findViewById(R.id.textView1); holder.tv2 = (TextView) convertView.findViewById(R.id.textView2); holder.tv3 = (TextView) convertView.findViewById(R.id.textView3); convertView.setTag(holder); } else { holder= (ViewHolder) convertView.getTag(); } holder.tv1.setText(list.get(position).getName()); holder.tv2.setText(list.get(position).getContent()); holder.tv3.setText(list.get(position).getPublished()); return convertView; } static class ViewHolder { TextView tv1,tv2,tv3 } }
You need to add a list view in your layout and populate it using an ArrayAdapter. Here's a tutorial that shows you how - http://www.vogella.com/articles/AndroidListView/article.html#arrayAdapter