This app is used to fetch the books as JSON using Google Books API and on research I also found that the JSON data is loading fine and the Book Title, Author is parsed correctly and I tested that using toasts. But the listView is not showing up even from setting the listView with the adapter. What must be the error? The app also doesn't crash making it little difficult to troubleshoot. Thanks in advance!
Main Activity
package com.praveent.booklisting;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Scanner;
public class MainActivity extends AppCompatActivity {
public String rootUrl = "https://www.googleapis.com/books/v1/volumes";
public String queryParameter = "q";
Button search_button;
EditText search_string;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list_view);
search_button = (Button) findViewById(R.id.search_button);
search_string = (EditText) findViewById(R.id.search_string);
search_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String query = search_string.getText().toString();
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
if(activeNetworkInfo != null && activeNetworkInfo.isConnected()){
new BackgroundTask().execute(query);
}
else{
Toast.makeText(MainActivity.this, "Please switch on the internet!", Toast.LENGTH_SHORT).show();
}
}
});
}
public void populate(BookAdapter adapter){
listView.setAdapter(adapter);
}
public class BackgroundTask extends AsyncTask<String, JSONArray, String> {
#Override
protected String doInBackground(String... strings) {
String query = strings[0];
URL url = null;
Uri uri = Uri.parse(rootUrl).buildUpon().appendQueryParameter(queryParameter, query).build();
try {
url = new URL(uri.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
String data = null;
try {
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
Scanner scanner = new Scanner(in);
scanner.useDelimiter("\\A");
if(scanner.hasNext()){
data = scanner.next();
}
} catch (IOException e1) {
e1.printStackTrace();
}
return data;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
BookAdapter bookAdapter;
JSONObject jsonObject = null;
JSONArray jsonArray = null;
JSONObject jsonArrayObject = null;
JSONObject volumeInfo = null;
JSONArray authorInfo = null;
JSONObject imageInfo = null;
String imageUrl = null;
String bookTitle = null;
String bookAuthor = null;
try {
jsonObject = new JSONObject(s);
jsonArray = jsonObject.getJSONArray("items");
ArrayList<Book> books= new ArrayList<Book>();
for(int i = 0; i <= jsonArray.length(); i++){
jsonArrayObject = jsonArray.getJSONObject(i);
volumeInfo = jsonArrayObject.getJSONObject("volumeInfo");
bookTitle = volumeInfo.getString("title");
authorInfo = volumeInfo.getJSONArray("authors");
bookAuthor = " ";
if (authorInfo != null){
bookAuthor = authorInfo.getString(0);
}
//imageInfo = volumeInfo.getJSONObject("imageLinks");
//imageUrl = imageInfo.getString("smallThumbnail");
books.add(new Book(bookTitle, bookAuthor));
Toast.makeText(MainActivity.this, bookAuthor, Toast.LENGTH_SHORT).show();
}
bookAdapter = new BookAdapter(MainActivity.this, books);
populate(bookAdapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
Book Adapter
package com.praveent.booklisting;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class BookAdapter extends ArrayAdapter<Book>{
Context c = null;
public BookAdapter(Context context, ArrayList<Book> books) {
super(context, 0, books);
c = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false);
}
Book currentBook = getItem(position);
TextView bookTextView = (TextView) listItemView.findViewById(R.id.book_name);
bookTextView.setText(currentBook.getBookName());
TextView authorTextView = (TextView) listItemView.findViewById(R.id.book_author);
authorTextView.setText(currentBook.getAuthorName());
//ImageView coverImageView = (ImageView) listItemView.findViewById(R.id.cover_image);
//Picasso.with(c).load(currentBook.getImageURL()).into(coverImageView);
return listItemView;
}
}
Book Class
package com.praveent.booklisting;
public class Book {
private String bookName;
private String authorName;
private String imageURL;
public Book(String name, String author){
bookName = name;
authorName = author;
//imageURL = url;
}
public String getBookName() {
return bookName;
}
public String getAuthorName() {
return authorName;
}
public String getImageURL() {
return imageURL;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context="com.praveent.booklisting.MainActivity">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:id="#+id/search_string"
android:textAlignment="center"
android:gravity="center"
android:hint="#string/search_hint"/>
<Button
android:layout_width="match_parent"
android:id="#+id/search_button"
android:layout_height="wrap_content"
android:text="#string/search_button" />
<ListView
android:layout_width="fill_parent"
android:id="#+id/list_view"
android:layout_height="fill_parent">
</ListView>
</LinearLayout>
list_item.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:padding="8dp"
android:layout_height="wrap_content">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="#+id/cover_image"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
android:id="#+id/book_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="#000"
android:id="#+id/book_author"/>
</LinearLayout>
</LinearLayout>
On PostExecute Change
for(int i = 0; i <=jsonArray.length(); i++)
to for(int i = 0;i<jsonArray.length(); i++)
On list_item.xml change the text color to white
you need to call getCount() in adapter.
public class BookAdapter extends ArrayAdapter<Book>{
Context c = null;
ArrayList<Book> bookslist = new ArrayList();
public BookAdapter(Context context, ArrayList<Book> books) {
super(context, 0, books);
c = context;
bookslist = books;
}
#Override
public int getCount() {
return bookslist.size();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false);
}
Book currentBook = getItem(position);
TextView bookTextView = (TextView) listItemView.findViewById(R.id.book_name);
bookTextView.setText(currentBook.getBookName());
TextView authorTextView = (TextView) listItemView.findViewById(R.id.book_author);
authorTextView.setText(currentBook.getAuthorName());
//ImageView coverImageView = (ImageView) listItemView.findViewById(R.id.cover_image);
//Picasso.with(c).load(currentBook.getImageURL()).into(coverImageView);
return listItemView;
}
}
Change your adapter to this
public class BookAdapter extends ArrayAdapter<Book> {
Context c = null;
private List<Book> bookList;
public BookAdapter(Context context, ArrayList<Book> books) {
super(context, 0, books);
c = context;
bookList = new ArrayList<>();
bookList = books;
}
#Override
public int getCount() {
return bookList.size();
}
#Nullable
#Override
public Book getItem(int position) {
return bookList.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false);
}
Book currentBook = getItem(position);
TextView bookTextView = (TextView) listItemView.findViewById(R.id.book_name);
bookTextView.setText(currentBook.getBookName());
TextView authorTextView = (TextView) listItemView.findViewById(R.id.book_author);
authorTextView.setText(currentBook.getAuthorName());
//ImageView coverImageView = (ImageView) listItemView.findViewById(R.id.cover_image);
//Picasso.with(c).load(currentBook.getImageURL()).into(coverImageView);
return listItemView;
}
}
I checked your code Error is in the AsyncTask onPostExecute method, change your for loop condition to this
for(int i = 0; i < jsonArray.length(); i++)
It is now working.
Related
I want to add a dynamically loading listview inside cardviews arranged in a grid Layout that loads up dynamically according to data present. How can it be done?
All the listviews will be different according to data fetched from the links:
1) http://www.json-generator.com/api/json/get/bTARFsabKG?indent=2 (Used)
OR
2) http://www.json-generator.com/api/json/get/cnWvBVaGoO?indent=2
Supporting code for the same is as below:
Mainactivity.java
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
Context context;
RecyclerView.Adapter recyclerView_Adapter;
RecyclerView.LayoutManager recyclerViewLayoutManager;
FoodItem foodItem;
ArrayList<FoodItem> items;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
foodItem = new FoodItem();
items = new ArrayList<FoodItem>();
new ApiFetchOrder().execute("");
context = getApplicationContext();
recyclerView = (RecyclerView) findViewById(R.id.recycler_view1);
}
public class ApiFetchOrder extends AsyncTask<String, Void, String> {
private String JsonResponse = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
JsonResponse = null;
JSONArray jsonArray = null;
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
try {
URL url = new URL("http://www.json-generator.com/api/json/get/bTARFsabKG?indent=2");
Log.d("urlUpadteImage", String.valueOf(url));
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setConnectTimeout(30000);
urlConnection.setRequestMethod("GET");
Log.d("urlConnection", String.valueOf(urlConnection));
InputStream inputstream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputstream == null) {
return null;
}
reader = new BufferedReader(new InputStreamReader(inputstream));
String inputLine;
while ((inputLine = reader.readLine()) != null)
buffer.append(inputLine + "\n");
if (buffer.length() == 0) {
return null;
}
JsonResponse = buffer.toString();
jsonArray = new JSONArray(JsonResponse);
Log.v("JsonRes",jsonArray.getJSONObject(0).getJSONObject("foodItem").getJSONArray("item1").getString(0));
//Log.v("JsonResponse",JsonResponse);
int j=1;
while(j<=4) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONArray arr = jsonArray.getJSONObject(i).getJSONObject("foodItem").getJSONArray("item" + j);
foodItem.setName(arr.getString(0));
foodItem.setQuantity(arr.getString(1));
Log.v("JsonArray", arr.getString(0)+arr.getString(1));
j++;
items.add(foodItem);
}
j++;
}
} catch (IOException | JSONException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
}
}
}
return null;
}
#Override
protected void onPostExecute(String s) {
//Change 3 to your choice because here 3 is the number of Grid layout Columns in each row.
recyclerViewLayoutManager = new GridLayoutManager(context,3);
recyclerView.setLayoutManager(recyclerViewLayoutManager);
recyclerView_Adapter = new RecyclerViewAdapter(context,items);
recyclerView.setAdapter(recyclerView_Adapter);
}
}
}
RecyclerViewAdapter.java
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.AsyncTask;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
ArrayList<FoodItem> values;
Context context1;
ItemsAdapter listViewAdapter;
FoodItem foodItem;
public RecyclerViewAdapter(Context context2,ArrayList<FoodItem> values2){
context1 = context2;
values= values2;
}
public static class ViewHolder extends RecyclerView.ViewHolder{
public ListView listView;
public ViewHolder(View v){
super(v);
listView = (ListView) v.findViewById(R.id.list);
}
}
#Override
public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View view1 = LayoutInflater.from(context1).inflate(R.layout.item_view,parent,false);
listViewAdapter = new ItemsAdapter(context1,R.layout.items,values);
foodItem = new FoodItem();
return new ViewHolder(view1);
}
#Override
public void onBindViewHolder(ViewHolder Vholder, int position){
Vholder.listView.setAdapter(listViewAdapter);
}
#Override
public int getItemCount(){
return values.size();
}
}
ItemsAdapter.java
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class ItemsAdapter extends ArrayAdapter<FoodItem> {
ArrayList<FoodItem> itemList;
LayoutInflater vi;
int Resource;
ViewHolder holder;
public ItemsAdapter(Context context, int resource , ArrayList<FoodItem> objects) {
super(context, resource , objects);
vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Resource = resource;
itemList = objects;
}
#SuppressLint("SetTextI18n")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
holder = new ViewHolder();
v = vi.inflate(Resource, null);
holder.itemName = (TextView) v.findViewById(R.id.itemName);
holder.itemQuantity = (TextView) v.findViewById(R.id.itemQuantity);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.itemName.setText(itemList.get(position).getName());
holder.itemQuantity.setText(itemList.get(position).getQuantity());
return v;
}
static class ViewHolder {
public TextView itemName;
public TextView itemQuantity;
}
}
FoodItem.java
public class FoodItem {
String Name,Quantity,TableNo;
public FoodItem(){}
public FoodItem(String name, String quantity, String tableNo) {
Name = name;
Quantity = quantity;
TableNo = tableNo;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getQuantity() {
return Quantity;
}
public void setQuantity(String quantity) {
Quantity = quantity;
}
public String getTableNo() {
return TableNo;
}
public void setTableNo(String tableNo) {
TableNo = tableNo;
}
}
Layout Files:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:id="#+id/relativelayout">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
item_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardview1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardElevation="7dp"
card_view:contentPadding="7dp"
card_view:cardCornerRadius="7dp"
card_view:cardMaxElevation="7dp"
>
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.v7.widget.CardView>
</LinearLayout>
items.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/itemName"
tools:text="Item Name"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/itemQuantity"
tools:text="Quantity"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
</LinearLayout>
i was tring to load image using url.a single url is working properly. but i need to add a few more images to this page.i need to add this image s to a list view.pls tell me how can i add a string array to this code.
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class FareCrd extends Activity {
String image_url="http://movito.nervov.com/img/ace-hd.png";
String[] mString ={"http://movito.nervov.com/img/ace-hd.png",
"http://movito.nervov.com/img/Movito_Logo_M.png"};
JSONArray jsonary;
ListView list;
private Activity activity;
private String[] data;
private static View inflater=null;
//private String[] mStrings={"http://movito.nervov.com/img/ace-hd.png"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fare_crd);
list=(ListView)findViewById(R.id.farelist);
new ServConn().execute();
}
private void parsedata(String data){
//System.out.println(data);
try {
JSONObject json = new JSONObject(data);
jsonary = json.getJSONArray("data");
ListView list = (ListView) findViewById(R.id.farelist);
list.setAdapter(new DriverOrderList(getApplicationContext(),
R.layout.farecrd, new JSONObject[jsonary.length()]));
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private class DriverOrderList extends ArrayAdapter<JSONObject> {
int listViewResource;
public DriverOrderList(Context context, int resource, JSONObject[] s) {
super(context, resource, s);
listViewResource = resource;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(listViewResource, parent, false);
ImageLoader imgLoader = new ImageLoader(getApplicationContext());
JSONObject rowdata = new JSONObject();
int loader = R.drawable.stub;
try {
rowdata = jsonary.getJSONObject(position);
System.out.println(rowdata);
ImageLoader imgLoader1 = new ImageLoader(getApplicationContext());
ImageView img=(ImageView) row.findViewById(R.id.imgid);
imgLoader.DisplayImage(image_url, loader, img);
TextView nameTxt = (TextView) row.findViewById(R.id.truckname);
TextView idTxt = (TextView) row.findViewById(R.id.id);
TextView minrttv =(TextView) row.findViewById(R.id.minimumRate);
TextView kmrttxt =(TextView) row.findViewById(R.id.kilometerRate);
TextView mindurtv=(TextView) row.findViewById(R.id.minimumDuration);
TextView freewatintim = (TextView) row.findViewById(R.id.freeWaitingTime);
TextView minuterttxt =(TextView) row.findViewById(R.id.minuteRate);
TextView watingchrttv =(TextView)row.findViewById(R.id.waitingCharge);
double freewt=(Double) rowdata.get("freeWaitingTime");
double kmratetxt=(Double) rowdata.get("kilometerRate");
double mindurtxt=(Double) rowdata.get("minimumDuration");
double mindur= mindurtxt/60;
double minkmrttxt=(Double) rowdata.get("minimumKilometer");
double minrttxt=(Double) rowdata.get("minimumRate");
double mintrate=(Double) rowdata.get("minuteRate");
double minutrat=mintrate/60;
double watingchrtxt=(Double) rowdata.get("waitingCharge");
double waitchgunittxt=(Double) rowdata.get("waitingChargeUnit");
nameTxt.setText(rowdata.getString("truckModel"));
minrttv.setText("Rs."+minrttxt+" /-");
kmrttxt.setText("Rs."+kmratetxt+"/km after "+minkmrttxt+"km");
mindurtv.setText("first"+mindur+"hr and "+minkmrttxt+"km");
//minuterttxt.setText(minutrat+"/-");
freewatintim.setText("first "+freewt+"min free");
watingchrttv.setText("RS"+watingchrtxt+"after every "+waitchgunittxt+"min");
}
catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return row;
}
}
private class ServConn extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
System.out.println("do in backgrnd");
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://movito.nervov.com/v1/trucks/miniTruckCategories");
httpget.setHeader(HTTP.CONTENT_TYPE, "application/json");
String replyString = "";
try {
HttpResponse response = httpclient.execute(httpget);
replyString = EntityUtils.toString(response
.getEntity());
} catch (ClientProtocolException e) {
System.out.println("ex: " + e);
} catch (IOException e) {
System.out.println("e: " + e);
}
return replyString;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
System.out.println(result);
result = "{\"data\":"+result+"}";
parsedata(result);
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
}
Try to use Glide libreries instead od picasso .It might help full for you.Please look at following link which might help you out.
http://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en
try this code I am using Picasso library to populate ImageView,
if you are using android studio add this library using following code into your gradle file
compile 'com.squareup.picasso:picasso:2.5.2'
use following code,
It is complete example of how you can make a custom ListView, I didn't include code where you have to get he JSON data from WebService as i didn't want to make the code complicated, I will write a separate code where i will show how to read the data you are interested in.
XML
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="#+id/CustomListViewActivity_listView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
single_item.xml layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<TextView
android:id="#+id/single_item_textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_weight="0.5"
android:text="New Text" />
<ImageView
android:id="#+id/single_item_imageView"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="4dp"
android:layout_weight="0.5" />
</LinearLayout>
Code
public class CustomListViewActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_list_view);
ArrayList<SingleItem> singleItems = new ArrayList<>();
singleItems.add(new SingleItem("http://movito.nervov.com/img/ace-hd.png","first Text"));
singleItems.add(new SingleItem("http://movito.nervov.com/img/Movito_Logo_M.png","Second Text"));
singleItems.add(new SingleItem("http://movito.nervov.com/img/ace-hd.png","third Text"));
singleItems.add(new SingleItem("http://movito.nervov.com/img/Movito_Logo_M.png","fourth Text"));
ListView listView = (ListView)findViewById(R.id.CustomListViewActivity_listView);
MyAdapter adapter = new MyAdapter(getApplicationContext(), R.layout.single_item,singleItems);
listView.setAdapter(adapter);
}
private class MyAdapter extends ArrayAdapter {
private ArrayList<SingleItem> singleItems;
private LayoutInflater layoutInflater;
private Context context;
private View single_View;
public MyAdapter(Context context, int resource, ArrayList<SingleItem> singleItems) {
super(context, resource, singleItems);
this.context = context;
this.singleItems = singleItems;
layoutInflater = LayoutInflater.from(this.context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = null;
if (row == null) {
row = layoutInflater.inflate(R.layout.single_item, parent, false);
holder = new ViewHolder();
holder.textView = (TextView) row.findViewById(R.id.single_item_textView);
holder.imageView = (ImageView) row.findViewById(R.id.single_item_imageView);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
final SingleItem singleItem = singleItems.get(position);
holder.textView.setText("" + singleItem.getText());
Picasso.with(context).load(""+singleItem.getUrl()).into(holder.imageView);
return row;
}
private class ViewHolder {
// Instance Variable (state or data)
TextView textView;
ImageView imageView;
}
}
public class SingleItem {
private String url;
private String text;
public SingleItem() {
}
public SingleItem(String url, String text) {
this.url = url;
this.text = text;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
}
Output
As you will see the loading the images from the URL provided to the appropriate ImageView is taken care by Picasso, do make sure you add the permission for the internet in the AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
I receive a JSON array from the server that looks like this,
[{"id":"3","name":"Spanish 101","uid":"54f22e5c87cbd3.52439435","did":"fba6a04d1d6375fbdbb102953e984002"},
{"id":"4","name":"Calc","uid":"54f22e5c87cbd3.52439435","did":"fb7f4ba1eae22eb396dc7cbd465a10b4"},
{"id":"5","name":"Stats 250","uid":"54f22e5c87cbd3.52439435","did":"f6adca44250056c17fec56530faee7c9"}]
I want to take this information and put it into a listview
This is my code that is suppose to process this JSON aray and put it into a listview
package com.example.library;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.AsyncTask;
public class FetchDataTask extends AsyncTask<String, Void, String>{
private final FetchDataListener listener;
private String msg;
public FetchDataTask(FetchDataListener listener) {
this.listener = listener;
}
#Override
protected String doInBackground(String... params) {
if(params == null) return null;
// get url from params
String url = params[0];
try {
// create http connection
HttpClient client = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
// connect
HttpResponse response = client.execute(httpget);
// get response
HttpEntity entity = response.getEntity();
if(entity == null) {
msg = "No response from server";
return null;
}
// get response content and convert it to json string
InputStream is = entity.getContent();
return streamToString(is);
}
catch(IOException e){
msg = "No Network Connection";
}
return null;
}
#Override
protected void onPostExecute(String sJson) {
if(sJson == null) {
if(listener != null) listener.onFetchFailure(msg);
return;
}
try {
// convert json string to json array
JSONArray aJson = new JSONArray(sJson);
// create apps list
List<Application> apps = new ArrayList<Application>();
for(int i=0; i<aJson.length(); i++) {
JSONObject json = aJson.getJSONObject(i);
Application app = new Application();
app.setTitle(json.getString("name"));
// add the app to apps list
apps.add(app);
}
//notify the activity that fetch data has been complete
if(listener != null) listener.onFetchComplete(apps);
} catch (JSONException e) {
msg = "Invalid response";
if(listener != null) listener.onFetchFailure(msg);
return;
}
}
/**
* This function will convert response stream into json string
* #param is respons string
* #return json string
* #throws IOException
*/
public String streamToString(final InputStream is) throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
}
catch (IOException e) {
throw e;
}
finally {
try {
is.close();
}
catch (IOException e) {
throw e;
}
}
return sb.toString();
}
}
FetchDataListener
package com.example.library;
import java.util.List;
public interface FetchDataListener {
public void onFetchComplete(List<Application> data);
public void onFetchFailure(String msg);
}
I am currently only trying to place the name into the listview, when I run this code what happens is only the first array gets put into the listview. So there is only one list item and it has the name Spanish 101.
Why aren't the other array names being put into the listview?
Application Adapter
package com.example.library;
import java.text.NumberFormat;
import java.util.List;
import android.content.Context;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.example.R;
public class ApplicationAdapter extends ArrayAdapter<Application>{
private List<Application> items;
public ApplicationAdapter(Context context, List<Application> items) {
super(context, R.layout.app_custom_list, items);
this.items = items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if(v == null) {
LayoutInflater li = LayoutInflater.from(getContext());
v = li.inflate(R.layout.app_custom_list, null);
}
Application app = items.get(position);
if(app != null) {
TextView titleText = (TextView)v.findViewById(R.id.titleTxt);
if(titleText != null) titleText.setText(app.getTitle());
}
return v;
}
}
Get and Set
package com.example.library;
public class Application {
private String title;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
MainActivity that has ListView
package com.example;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.example.R;
import com.example.library.Application;
import com.example.library.ApplicationAdapter;
import com.example.library.DatabaseHandler;
import com.example.library.FetchDataListener;
import com.example.library.FetchDataTask;
import com.example.library.UserFunctions;
import java.util.HashMap;
import java.util.List;
public class MainActivity extends ListActivity implements FetchDataListener {
private ProgressDialog dialog;
ProgressDialog nDialog;
AlertDialog.Builder dlgAlert;
ListView listView ;
TextView tv;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
tv = (TextView) findViewById(R.id.tv);
nDialog = new ProgressDialog(MainActivity.this);
//Action bar information
android.app.ActionBar mActionBar = getActionBar();
assert mActionBar != null;
mActionBar.setDisplayShowHomeEnabled(false);
mActionBar.setDisplayShowTitleEnabled(false);
LayoutInflater mInflater = LayoutInflater.from(this);
View mCustomView = mInflater.inflate(R.layout.custom_actionbar, null);
//FIX THISSSSS TO LOGOUT BUTTON
RelativeLayout settingButton = (RelativeLayout) mCustomView
.findViewById(R.id.settingButton);
settingButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
UserFunctions logout = new UserFunctions();
logout.logoutUser(getApplicationContext());
Intent startup = new Intent(getApplicationContext(), StartUp.class);
startup.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(startup);
finish();
}
});
mActionBar.setCustomView(mCustomView);
mActionBar.setDisplayShowCustomEnabled(true);
//End action bar information
}//End onCreate
private void initView() {
// show progress dialog
DatabaseHandler db = new DatabaseHandler(getApplicationContext());
HashMap user = new HashMap();
user = db.getUserDetails();
String uid = user.get("unique_id").toString();
dialog = ProgressDialog.show(this, "", "Loading...");
String url = "www.example.com";
FetchDataTask task = new FetchDataTask(this);
task.execute(url);
}
#Override
public void onFetchComplete(List<Application> data) {
// dismiss the progress dialog
if(dialog != null) dialog.dismiss();
// create new adapter
ApplicationAdapter adapter = new ApplicationAdapter(this, data);
// set the adapter to list
setListAdapter(adapter);
}
#Override
public void onFetchFailure(String msg) {
// dismiss the progress dialog
if(dialog != null) dialog.dismiss();
// show failure message
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
}//End Activity
This is how i deal with ListView and CustomAdapter
in onCreate() of Activity
//Photos Model List
photoList = new ArrayList<Photos>();
//ListView
lvGalleryPhotos = (ListView) parentView.findViewById(R.id.lvGalleryPhotos);
//My CustomAdapter
pgAdapter = new PhotoGalleryAdapter(photoList, getSherlockActivity());
//Setting adapter to GridView
lvGalleryPhotos.setAdapter(pgAdapter);
//Parsing JSON
for(int i=0;i<10;i++){
//each result contains details about a image
JSONObject result = results.getJSONObject(i);
//Real Parsing
int width = result.getInt("width");
int height = result.getInt("height");
String title = result.getString("titleNoFormatting");
String url = result.getString("unescapedUrl");
//Make it workable so replace \u003d with =
String tbUrl = result.getString("tbUrl").replace("\u003d", "=");
//Creating photo object and inserting all collected information into it.
Photos photo = new Photos();
photo.setHeight(height);
photo.setWidth(width);
photo.setTitle(title);
photo.setURL(url);
photo.setTbUrl(tbUrl);
//Adding each Photo Object to PhotoList
photoList.add(photo);
}
//Informing that data has changed
pgAdapter.notifyDataSetChanged();
My Custom Adapter
public class PhotoGalleryAdapter extends BaseAdapter {
ImageLoader mImageLoader;
List<Photos> photoList;
Context mContext;
BlowIt blw;
LayoutInflater mLInflater;
public PhotoGalleryAdapter(List<Photos> photoList,Context mContext){
this.photoList = photoList;
this.mContext = mContext;
blw = new BlowIt(mContext);
}
#Override
public int getCount() {
return photoList.size();
}
#Override
public Object getItem(int position) {
return photoList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//Creating layout inflater
if(mLInflater==null){
mLInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
//Inflating Layout
if(convertView==null){
convertView = mLInflater.inflate(R.layout.gallery_single_photo,parent,false);
}
//Getting Object
final Photos photo = photoList.get(position);
//Single Image
NetworkImageView nivGalleryPhoto = (NetworkImageView) convertView.findViewById(R.id.nivGalleryPhoto);
TextView tvPhotoName = (TextView) convertView.findViewById(R.id.tvPhotoName);
TextView tvPhotoDesc = (TextView) convertView.findViewById(R.id.tvPhotoDesc);
final String photoDescr = photo.getHeight()+"x"+photo.getWidth();
nivGalleryPhoto.setImageUrl(photo.getTbUrl(), mImageLoader);
tvPhotoName.setText(photo.getTitle());
tvPhotoDesc.setText(photoDescr);
convertView.setTag(photo);
convertView.setId(position);
//This will trigger when ever the user clicks on a specific image
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//This will prompt automatically context menu
v.showContextMenu();
}
});
return convertView;
}
}
and the layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/llPhotosFragmentRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/lvGalleryPhotos"
android:layout_height="wrap_content"
android:layout_width="match_parent"
></ListView>
</LinearLayout>
and the gallery_single_photo.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:padding="10dp"
android:layout_height="wrap_content" >
<!-- <com.android.volley.toolbox.NetworkImageView -->
<com.android.volley.toolbox.NetworkImageView
android:id="#+id/nivGalleryPhoto"
android:layout_height="90dp"
android:scaleType="centerCrop"
android:layout_width="75dp"
android:contentDescription="#string/dummy_desc"
/>
<TextView
android:id="#+id/tvPhotoName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="bold"
android:layout_alignTop="#+id/nivGalleryPhoto"
android:layout_marginLeft="5dp"
android:layout_toRightOf="#+id/nivGalleryPhoto"
android:text="Large Text"/>
<TextView
android:id="#+id/tvPhotoDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/tvPhotoName"
android:layout_below="#+id/tvPhotoName"
android:text="Medium Text"
android:textSize="13sp"
android:textColor="#color/border_black" />
</RelativeLayout>
and all the above codes can make a listView with items like this
Use ViewHolder design pattern in your getView(...):
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder;
if(v == null) {
LayoutInflater li = LayoutInflater.from(getContext());
v = li.inflate(R.layout.app_custom_list, null);
holder = new ViewHolder();
holder.titleText = (TextView)v.findViewById(R.id.titleTxt);
v.setTag(holder);
}
else
holder = (ViewHolder) v.getTag()
Application app = items.get(position);
if(app != null) {
if(titleText != null)
holder.titleText.setText(app.getTitle());
}
return v;
}
static class ViewHolder {
TextView titleText;
}
I'm new to Android so struggling to learn best practices etc and working mainly with tutorials.
I have my app doing what I want it to do using a custom listview. My problem is understanding exactly how it works as there is not an actual listview in the code.
What I want to do is add a container above the listview, but everything I have tried just doesn't seem to work and with it being a custom adapter, I'm struggling to find many resources.
Here is my fragment:
package info.androidhive.slidingmenu;
import android.annotation.TargetApi;
import android.app.ListFragment;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewStub;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class PhotosFragment extends ListFragment {
private static final String TAG = MainActivity.class.getSimpleName();
private List<ListViewItem> mItems; // ListView items list
JSONObject obj;
JSONArray stories;
class RequestTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
//Do anything with response..
Log.d(TAG, responseString);
} else {
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
Log.d(TAG, String.valueOf(e));
} catch (IOException e) {
//TODO Handle problems..
Log.d(TAG, String.valueOf(e));
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.e(TAG, result);
try {
obj = new JSONObject(result);
stories = obj.getJSONArray("stories");
// initialize the items list
mItems = new ArrayList<ListViewItem>();
for (int i = 0; i < stories.length(); i++) {
JSONObject storyObj = stories.getJSONObject(i);
if (!storyObj.has("Advert")) {
newsStories newsStories = new newsStories();
newsStories.setTitle(storyObj.getString("subject"));
newsStories.setBody(storyObj.getString("body"));
mItems.add(new ListViewItem(newsStories.getTitle(), newsStories.getBody(), ""));
} else {
newsStories newsStories = new newsStories();
newsStories.setThumbnailUrl(storyObj.getString("Advert"));
mItems.add(new ListViewItem("", "", newsStories.getThumbnailUrl()));
}
// initialize and set the list adapter
setListAdapter(new ListViewDemoAdapter(getActivity(), mItems));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public class newsStories {
private String name, thumbnailUrl, body;
public String getTitle() {
return name;
}
public void setTitle(String name) {
this.name = name;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body.substring(0, 150);
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
public void setThumbnailUrl(String thumbnailUrl) {
//Check if thumbnail exists, if so take out spaces and replace with -
this.thumbnailUrl = thumbnailUrl;
}
}
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// View importPanel = ((ViewStub) getActivity().findViewById(R.id.stub_import)).inflate();
new RequestTask().execute("http://www.myjsonurl.co.uk");
// remove the dividers from the ListView of the ListFragment
getListView().setDivider(null);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// retrieve theListView item
ListViewItem item = mItems.get(position);
// do something
Toast.makeText(getActivity(), item.title, Toast.LENGTH_SHORT).show();
}
public class ListViewItem {
public final String title; // the text for the ListView item title
public final String description; // the text for the ListView item description
public final String adUrl;
//public final Drawable image;
public ListViewItem(String title, String description, String Advert_Url) {
Log.e("Advert:", Advert_Url);
if (Advert_Url != null && !Advert_Url.isEmpty()) {
String Advert = "http://alinktomyadvert.co.uk";
Log.e("TITLE: ", title);
this.title = "";
this.description = "";
this.adUrl = Advert;
} else {
this.title = title;
this.description = description;
this.adUrl = "";
}
}
}
}
If somebody can point me in the right direction I'd be so grateful.
EDIT:
Following #Sufian's advise I now have the following:
package info.androidhive.slidingmenu;
import android.annotation.TargetApi;
import android.app.Fragment;
import android.app.ListFragment;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class PhotosFragment extends Fragment {
public PhotosFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_photos, container, false);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
new RequestTask().execute("http://www.myaddress.co.uk/app/index.php?Type=8&catid=7&userid=4");
Log.v("created", "onActivityCreated()");
setHasOptionsMenu(true);
//mProgressBar = (ProgressBar) getView().findViewById(R.id.progressBar);
ListView mListView = (ListView) getView().findViewById(R.id.listView2);
//mTvEmpty = (TextView) getView().findViewById(R.id.textView);
ArrayAdapter<ListViewItem> adapter = new ArrayAdapter<ListViewItem>(getActivity(), android.R.layout.simple_list_item_1, mItems);
// load your data to your mListView
mListView.setAdapter(adapter); //NULL POINTER
}
private static final String TAG = MainActivity.class.getSimpleName();
private List<ListViewItem> mItems; // ListView items list
JSONObject obj;
JSONArray stories;
//
class RequestTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
//Do anything with response..
Log.d(TAG, responseString);
} else {
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
Log.d(TAG, String.valueOf(e));
} catch (IOException e) {
//TODO Handle problems..
Log.d(TAG, String.valueOf(e));
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.e(TAG, result);
try {
obj = new JSONObject(result);
stories = obj.getJSONArray("stories");
// initialize the items list
mItems = new ArrayList<ListViewItem>();
for (int i = 0; i < stories.length(); i++) {
JSONObject storyObj = stories.getJSONObject(i);
if (!storyObj.has("Advert")) {
newsStories newsStories = new newsStories();
newsStories.setTitle(storyObj.getString("subject"));
newsStories.setBody(storyObj.getString("body"));
mItems.add(new ListViewItem(newsStories.getTitle(), newsStories.getBody(), ""));
} else {
newsStories newsStories = new newsStories();
newsStories.setThumbnailUrl(storyObj.getString("Advert"));
mItems.add(new ListViewItem("", "", newsStories.getThumbnailUrl()));
}
// initialize and set the list adapter
//setListAdapter(new ListViewDemoAdapter(getActivity(), mItems));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public class newsStories {
private String name, thumbnailUrl, body;
public String getTitle() {
return name;
}
public void setTitle(String name) {
this.name = name;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body.substring(0, 150);
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
public void setThumbnailUrl(String thumbnailUrl) {
//Check if thumbnail exists, if so take out spaces and replace with -
this.thumbnailUrl = thumbnailUrl;
}
}
}
//
// #TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
// #Override
// public void onViewCreated(View view, Bundle savedInstanceState) {
// super.onViewCreated(view, savedInstanceState);
//
//
// // View importPanel = ((ViewStub) getActivity().findViewById(R.id.stub_import)).inflate();
// new RequestTask().execute("http://www.myjsonurl.co.uk");
// // remove the dividers from the ListView of the ListFragment
// getListView().setDivider(null);
// }
//
// #Override
// public void onListItemClick(ListView l, View v, int position, long id) {
// // retrieve theListView item
// ListViewItem item = mItems.get(position);
//
// // do something
// Toast.makeText(getActivity(), item.title, Toast.LENGTH_SHORT).show();
// }
//
public class ListViewItem {
public final String title; // the text for the ListView item title
public final String description; // the text for the ListView item description
public final String adUrl;
//public final Drawable image;
public ListViewItem(String title, String description, String Advert_Url) {
Log.e("Advert:", Advert_Url);
if (Advert_Url != null && !Advert_Url.isEmpty()) {
String Advert = "http://www.myaddress.co.uk/images/websitelogo.png?width=700&height=200";
Log.e("TITLE: ", title);
this.title = "";
this.description = "";
this.adUrl = Advert;
} else {
this.title = title;
this.description = description;
this.adUrl = "";
}
}
}
}
I'm now getting a null pointer exception on the set adapter command - I'm a little unsure where to debug from here. I'm assuming it means the list is null?
EDIT 2
Logcat:
01-19 05:27:30.371 1287-1287/info.androidhive.slidingmenu D/OpenGLRenderer﹕ Enabling debug mode 0
01-19 05:27:31.031 1287-1287/info.androidhive.slidingmenu I/Choreographer﹕ Skipped 60 frames! The application may be doing too much work on its main thread.
01-19 05:27:57.901 1287-1287/info.androidhive.slidingmenu V/created﹕ onActivityCreated()
01-19 05:28:08.271 1287-1287/info.androidhive.slidingmenu D/dalvikvm﹕ GC_FOR_ALLOC freed 326K, 9% free 4066K/4468K, paused 24ms, total 26ms
01-19 05:28:08.471 1287-1287/info.androidhive.slidingmenu D/AndroidRuntime﹕ Shutting down VM
01-19 05:28:08.471 1287-1287/info.androidhive.slidingmenu W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0xb3ac2ba8)
01-19 05:28:08.511 1287-1287/info.androidhive.slidingmenu E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: info.androidhive.slidingmenu, PID: 1287
java.lang.NullPointerException
at info.androidhive.slidingmenu.PhotosFragment$RequestTask.onPostExecute(PhotosFragment.java:130)
at info.androidhive.slidingmenu.PhotosFragment$RequestTask.onPostExecute(PhotosFragment.java:52)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
fragment_photos.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/progressBar"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="190dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="#+id/textView"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="63dp" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView2"
android:layout_below="#+id/progressBar"
android:layout_centerHorizontal="true" />
</RelativeLayout>
EDIT 3
package info.androidhive.slidingmenu;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.text.Html;
import android.text.Layout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.List;
public class ListViewDemoAdapter extends ArrayAdapter<PhotosFragment.ListViewItem> {
public ListViewDemoAdapter(Context context, List<PhotosFragment.ListViewItem> items) {
super(context, R.layout.listview_item, items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView == null) {
// inflate the GridView item layout
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.listview_item, parent, false);
// initialize the view holder
viewHolder = new ViewHolder();
viewHolder.ivIcon = (ImageView) convertView.findViewById(R.id.ivIcon);
viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
viewHolder.tvDescription = (TextView) convertView.findViewById(R.id.tvDescription);
convertView.setTag(viewHolder);
} else {
// recycle the already inflated view
viewHolder = (ViewHolder) convertView.getTag();
}
// update the item view
PhotosFragment.ListViewItem item = getItem(position);
//viewHolder.ivIcon.setImageDrawable(item.image);
viewHolder.tvTitle.setText((Html.fromHtml(item.title)));
viewHolder.tvDescription.setText(Html.fromHtml(item.description));
if (!item.adUrl.isEmpty()) {
Picasso.with(getContext())
.load(item.adUrl)
.into(viewHolder.ivIcon);
viewHolder.ivIcon.setVisibility(viewHolder.ivIcon.VISIBLE);
viewHolder.ivIcon.setOnClickListener(new View.OnClickListener() {
//#Override
public void onClick(View v) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.myaddress.co.uk"));
getContext().startActivity(browserIntent);
}
});
}else {
viewHolder.ivIcon.setVisibility(viewHolder.ivIcon.GONE);
}
return convertView;
}
/**
* The view holder design pattern prevents using findViewById()
* repeatedly in the getView() method of the adapter.
*
* #see
*/
private static class ViewHolder {
ImageView ivIcon;
TextView tvTitle;
TextView tvDescription;
}
}
ListFragment comes with a ListView, a ProgressBar (displayed till you write setListShown(true);) and a TextView (which is shown when the ListView has no items.
If you want to add anything above ListView, the easy way to do that is to replace ListFragment with Fragment and inflating your own XML. Like below:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false);
}
And setting up your fields and populating data in onActivityCreated(), like:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.v("created", "onActivityCreated()");
setHasOptionsMenu(true);
mProgressBar = (ProgressBar) getView().findViewById(R.id.progressBar1);
mListView = (ListView) getView().findViewById(R.id.listView1);
mTvEmpty = (TextView) getView().findViewById(R.id.tv_empty);
// load your data to your mListView
}
Edit:
Update your onPostExecute() to:
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.e(TAG, result);
try {
obj = new JSONObject(result);
stories = obj.getJSONArray("stories");
// initialize the items list
mItems = new ArrayList<ListViewItem>();
for (int i = 0; i < stories.length(); i++) {
JSONObject storyObj = stories.getJSONObject(i);
if (!storyObj.has("Advert")) {
newsStories newsStories = new newsStories();
newsStories.setTitle(storyObj.getString("subject"));
newsStories.setBody(storyObj.getString("body"));
mItems.add(new ListViewItem(newsStories.getTitle(), newsStories.getBody(), ""));
}
else {
newsStories newsStories = new newsStories();
newsStories.setThumbnailUrl(storyObj.getString("Advert"));
mItems.add(new ListViewItem("", "", newsStories.getThumbnailUrl()));
}
// initialize and set the list adapter
//setListAdapter(new ListViewDemoAdapter(getActivity(), mItems));
}
//mProgressBar = (ProgressBar) getView().findViewById(R.id.progressBar);
ListView mListView = (ListView) getView().findViewById(R.id.listView2);
//mTvEmpty = (TextView) getView().findViewById(R.id.textView);
Log.d("mListView: ", String.valueOf(mListView));
ArrayAdapter<ListViewItem> adapter = new ArrayAdapter<ListViewItem>(getActivity(), android.R.layout.simple_list_item_1, mItems);
Log.d("Adapter: ", String.valueOf(adapter));
// load your data to your mListView
mListView.setAdapter(adapter);
}
catch (JSONException e) {
e.printStackTrace();
}
}
You were creating adapter even if mItems was null (putting it after catch would run it always).
I´m new to Android and i´ve a problem with my items-background in my listview... it seems to work (items with "premium = 1" should have a yellow background), but when i scroll down and then back up everytime other items have the yellow background-color?!
And i can´t find my mistake :(
Pois.java (the important part)
protected void ausgeben()
{
ausgabestring = ausgabestring.trim();
ausgabestring = ausgabestring.substring(1);
rowItems = new ArrayList<PoiRowItem>();
try{
jsonArray = new JSONArray(ausgabestring);
Log.i("ausgabe", "teilsuccess");
for(int i=0; i < jsonArray.length(); i++)
{
JSONObject jsonObj = jsonArray.getJSONObject(i);
PoiRowItem item = new PoiRowItem(jsonObj.getString("POI_NAME"), jsonObj.getString("POI_ID"), jsonObj.getString("POI_PREMIUM"));
rowItems.add(item);
}
}
catch(JSONException e)
{
Log.e("log_tag", "Error parsing data "+e.toString());
}
listView = (ListView) findViewById(R.id.list);
PoiListViewAdapter adapter = new PoiListViewAdapter(this, R.layout.poi_list_item, rowItems);
listView.setAdapter(adapter);
//listView.setOnItemClickListener(this);
}
PoiListViewAdapter.java (Where i think is my problem)
import java.util.List;
import at.visualstudioteschl.dguide.PoiRowItem;
import at.visualstudioteschl.dguide.R;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class PoiListViewAdapter extends ArrayAdapter<PoiRowItem> {
Context context;
public PoiListViewAdapter(Context context, int resourceId, List<PoiRowItem> items) {
super(context, resourceId, items);
this.context = context;
}
private class ViewHolder {
TextView txtTitle;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
PoiRowItem rowItem = getItem(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.poi_list_item, null);
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
holder.txtTitle.setText(rowItem.getTitle());
// TODO HIER GIBTS NOCH NEN FEHLER... ES WERDEN BEIM SCROLLEN NACH KURZER ZEIT ALLE GELB
if (rowItem.getPremium().contains("1")){
holder.txtTitle.setBackgroundColor(Color.YELLOW);
}
return convertView;
}
}
PoiRowItem.java
public class PoiRowItem {
private String title;
private String kat_id;
private String premium;
public PoiRowItem(String title, String kat_id, String premium) {
this.title = title;
this.kat_id = kat_id;
this.premium = premium;
}
public String getID() {
return kat_id;
}
public void setID(String id) {
this.kat_id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#Override
public String toString() {
return kat_id;
}
public String getPremium() {
return premium;
}
public void setPremium(String premium) {
this.premium = premium;
}
}
*poi_list_item.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="fill_parent" >
<TextView
android:id="#+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:padding="5dp"
android:textSize="20sp"
android:singleLine="true"/>
</RelativeLayout>
The views are re-used.. So you need to set the original color back when you don't want the yellow color.
// TODO HIER GIBTS NOCH NEN FEHLER... ES WERDEN BEIM SCROLLEN NACH KURZER ZEIT ALLE GELB
if (rowItem.getPremium().contains("1")){
holder.txtTitle.setBackgroundColor(Color.YELLOW);
}
else{
holder.txtTitle.setBackgroundColor(Color.WHITE); // the original color here
}
Your list items are reused when scrolling, so you need to force the normal color in case of non-premium, e.g:
if (rowItem.getPremium().contains("1")){
holder.txtTitle.setBackgroundColor(Color.YELLOW);
}
else {
holder.txtTitle.setBackgroundColor(Color.WHITE);
}