ListView filled from AsyncTask doesn't render - java

I have a Task which extends Androids AsyncTask in order to get data from my Database in the cloud. I am doing this as to avoid NetworkingOnMainThread exception (I know you can set up StrictMode but in my opionion it's more of a hack than a solution).
I get no errors whatsoever. I have checked values in debugging and everything gets fetched correctly from my database. I have a Venue where I set my name, description, image etc... and the ArrayList<Venue> which I use for my adapter gets instantiated properly.
The problem is - the ListView doesn't render.
Here is my custom adapter code
public class EventListArrayAdapter extends ArrayAdapter<String> {
Context context;
ArrayList<Venue> values;
public EventListArrayAdapter(Context context, ArrayList<Venue> values) {
super(context, R.layout.single_event_list_item);
this.context = context;
this.values = values;
}
public View getView(int position, View convertView, ViewGroup parent){
View v = convertView;
if(v==null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.single_event_list_item, null);
}
Venue currEvent = values.get(position);
if(currEvent!=null){
TextView singleItemTitle = (TextView) v.findViewById(R.id.singleItemTitle);
TextView singleItemLocation = (TextView) v.findViewById(R.id.singleItemLocation);
TextView singleItemDate = (TextView) v.findViewById(R.id.singleItemDate);
ImageView singleItemImage = (ImageView) v.findViewById(R.id.singleItemImage);
singleItemTitle.setText(currEvent.getName());
singleItemDate.setText(currEvent.getDate());
singleItemLocation.setText(currEvent.getLocation());
singleItemImage.setImageBitmap(currEvent.getVenueImage());
}
return v;
}
}
And here is my AsyncTask code
private class FillContentTask extends AsyncTask<String, Void, Void> {
ArrayList<Venue> venues;
Context activity;
ProgressDialog dialog;
public FillContentTask(Context context) {
this.activity = context;
}
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(activity);
dialog.setTitle("Loading...");
dialog.show();
}
#Override
protected Void doInBackground(String... params) {
this.venues = Venue.getAll();
for (Venue currentVenue : this.venues) {
try {
InputStream in = new java.net.URL(currentVenue.getImageURL()).openStream();
currentVenue.setVenueImage(BitmapFactory.decodeStream(in));
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
ListView list = (ListView) findViewById(R.id.eventList);
EventListArrayAdapter adapter = new EventListArrayAdapter(activity, this.venues);
list.setAdapter(adapter);
dialog.hide();
}
}
And as I already said. To the best of my knowledge, the AsnycTask does it's job properly since all ArrayList<Venue> values get filled properly

Override the getCount method in your EventListArrayAdapter
#Override
public int getCount()
{
return values.size();
}
OR
change the super call in EventListArrayAdapter constructor from
super(context, R.layout.single_event_list_item);
to
super(context, R.layout.single_event_list_item,values);
and also you will need to change extends ArrayAdapter<String> to extends ArrayAdapter<Venue>

Related

Issue with showing lists of running apps on List view

I'm trying to show the list of background running apps in ListView. what I have tried is creating AppAdapter extending ArrayAdapter and used Async task to call the method which returns the list of running services' package names. I posted the code below.
AppAdapter:
public class AppAdapter extends ArrayAdapter<String> {
private List<ActivityManager.RunningServiceInfo> applist =null;
private Context context;
private PackageManager packageManager;
private List<String> applist1 = null;
public AppAdapter(#NonNull Context context, int resource, #NonNull List<String> objects) {
super(context, resource, objects);
this.context = context;
this.applist1 = objects;
packageManager = context.getPackageManager();
}
#Override
public int getCount() {
return ((applist1 != null) ? applist1.size() : 0);
}
#Override
public String getItem(int position) {
return ((applist1 != null) ? applist1.get(position) : null);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.list_item, null);
}
ActivityManager.RunningServiceInfo data = applist.get(position);
Log.d("Test", "data is : " + data);
if (data != null){
Log.d("Test", "data is not null : " + data);
TextView appName = view.findViewById(R.id.applabel);
TextView packageName = view.findViewById(R.id.pname);
ImageView iconView = view.findViewById(R.id.appicon);
ComponentName mComponentName = data.service;
appName.setText(mComponentName.getClassName());
packageName.setText(mComponentName.getPackageName());
} else {
Log.d("Test", "data is null : " + data);
}
return view;
}
}
Code in Main Activity:
private class LoadApplications extends AsyncTask<Void, Void, Void>{
private ProgressDialog progressDialog = null;
#Override
protected Void doInBackground(Void... voids) {
applist1 = runningServices();
listadapter = new AppAdapter(Taskmanager.this, R.layout.list_item, applist1);
Log.d("Test", "applist1 is : " + applist1);
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
listView.setAdapter(listadapter);
progressDialog.dismiss();
super.onPostExecute(aVoid);
}
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(Taskmanager.this, null, "Loading..");
super.onPreExecute();
}
}
and the runningServices() method correctly returns the list of package names (if you want to see that let me know).
The problem is the after app launch it shows nothing (no list). I didn't forget to call the async task in the onCreate method of the activity.
Can someone please figure out what might be going wrong. I posted only limited code if you want more then ask me in the comments, please.
Do the necessary work after getting a list from the background task. Return the List value from the doInBackgroind method and then assign it to adapter in the onPostExecute method which runs on the UI thread.
public class LoadApplications extends AsyncTask<Void, Void, List<ActivityManager.RunningServiceInfo>> {
#Override
protected List<ActivityManager.RunningServiceInfo> doInBackground(Void... arg0) {
return runningServices();
}
#Override
protected void onPostExecute(List<ActivityManager.RunningServiceInfo> applist) {
// call super
listadapter = new AppAdapter(Taskmanager.this,
R.layout.list_item, applist);
listView.setAdapter(listadapter);
progressDialog.dismiss();
//other works
}
}

ArrayAdapter not displaying data in Fragment

I have seen a lot of similar questions about this issue but I couldn't find any solution to this:
I have three fragments in a TabLayout handled by a ViewPager and I have a ListView in the third Fragment which is not displaying any items after I change the orientation of the screen. I have tried to set a background color to the convertView in the ArrayAdapter to see if it was displayed and indeed it is not being displayed after I change the orientation. But it's weird because in my First Fragment where I use the same ArrayAdapter for another ListView everything's working and I can't understand why it's not on the third Fragment.
One thing is sure: I have checked with logs almost everywhere that the ArrayList.size() is never zero.
Here's the Third Fragment's relevant code:
public class SavedScanFragment extends Fragment{
private ListView lv;
private Database db;
private ArrayList<Scan> scans;
private ScanAdapter adapter;
public static SavedScanFragment newInstance() {
return new SavedScanFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
db = new Database(getContext());
getScans();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View result = inflater.inflate(R.layout.fragment_saved_scan, container, false);
lv = (ListView) result.findViewById(R.id.saved_scan_list);
return result;
}
#Override
public void onResume() {
super.onResume();
db = new Database(getContext());
getScans();
}
public void getScans() {
AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
#Override
protected Boolean doInBackground(Void... params) {
scans = db.getScans();
if(scans!=null)
return true;
else {
scans = new ArrayList<>();
return false;
}
}
#Override
protected void onPostExecute(Boolean result) {
if(result)
populateList();
}
};
task.execute();
}
public void populateList() {
if(getContext()!=null) {
if (lv.getAdapter() == null) {
adapter = new ScanAdapter(getContext(), R.layout.scan_list_item, scans);
lv.setAdapter(adapter);
} else {
((ScanAdapter) lv.getAdapter()).update(scans);
}
}
}
And the ArrayAdapter's code:
public class ScanAdapter extends ArrayAdapter<Scan> implements ListAdapter {
private Context context;
private int layoutResourceID;
private ArrayList<Scan> results;
public ScanAdapter(Context context, int layoutResourceID, ArrayList<Scan> results) {
super(context, layoutResourceID, results);
this.context = context;
this.layoutResourceID = layoutResourceID;
this.results = results;
}
public void update(ArrayList<Scan> scans) {
results.clear();
results.addAll(scans);
notifyDataSetChanged();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView; //view = row
ViewHolder holder = null;
if(view == null) {
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(layoutResourceID, parent, false);
view.setBackgroundColor(Color.GREEN);
holder = new ViewHolder();
holder.name = (TextView)view.findViewById(R.id.scan_name_and_date_text);
holder.ssid = (TextView)view.findViewById(R.id.scan_SSID_text);
holder.frequency = (TextView)view.findViewById(R.id.scan_frequency_text);
holder.level = (TextView)view.findViewById(R.id.scan_level_text);
view.setTag(holder);
} else
holder = (ViewHolder) view.getTag();
Scan sr = results.get(position);
holder.name.setText(sr.getName()+" ( "+sr.getDate()+" )");
holder.ssid.setText(sr.getSsid() + " ( " + sr.getBssid() + " )");
holder.frequency.setText(sr.getFrequency()+" MHz");
holder.level.setText(Integer.toString(sr.getLevel())+ " dBm");
return view;
}
static class ViewHolder {
TextView name,ssid, frequency, level;
}
}
Thanks in advance!
From this post. You can try to use onActivityCreated instead of onCreate. Try this:
public class SavedScanFragment extends Fragment{
//....to restore the saved state
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//Restore the fragment state here
db = new Database(getContext());
getScans();
}
//add this to save instant state
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//save your important variable here to outstate
}
}

Output JSON image in listView

I tried uploading an image using JSON. I create a link to image in JSON. Many times I tried to fix my problem, but with no success.
Is there a mistake in my use of DownloadImageTask in My adapter Adapter ?
MainActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = (ListView) findViewById(R.id.list);
newsList = new ArrayList<News>();
//this is i take json image
new NewsAsynkTask().execute();
}
public class NewsAsynkTask extends AsyncTask<String , Void, String> {
protected String doInBackground(String... params) {
//code
}
protected void onPostExecute(String file_url) {
pDialog.dismiss();
//this i run adapter
NewsAdapter adapter = new NewsAdapter(getApplicationContext(), R.layout.list_row, newsList);
list.setAdapter(adapter);
}
}
My adapter Adapter
public class NewsAdapter extends ArrayAdapter<News> {
ArrayList<News> ArrayListNews;
int Resourse;
Context context;
LayoutInflater vi;
public NewsAdapter(Context context, int resource, ArrayList<News> objects) {
super(context, resource, objects);
ArrayListNews = objects;
Resourse = resource;
this.context = context;
vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = vi.inflate(Resourse, null);
holder = new ViewHolder();
holder.imageview = (ImageView) convertView.findViewById(R.id.imagenews);
holder.nameNews = (TextView) convertView.findViewById(R.id.namenews);
holder.dayNews = (TextView) convertView.findViewById(R.id.daynews);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
new DownloadImageTask(holder.imageview).execute(ArrayListNews.get(position).getImageNews());
holder.nameNews.setText(ArrayListNews.get(position).getNameNews());
holder.dayNews.setText(ArrayListNews.get(position).getDayNews());
return convertView;
}
static class ViewHolder {
public ImageView imageview;
public TextView nameNews;
public TextView dayNews;
}
//this is i try load image. I using wrong somthing, please help me
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
ImageLoader imgLoader;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
#Override
protected Bitmap doInBackground(String... urls) {
final String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
Handler handler = new Handler(context.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
//this is class on this [link][1]. I try use simple, it work. But here dont work
imgLoader = new ImageLoader(context);
imgLoader.DisplayImage(urldisplay, bmImage);
}
});
} catch (Exception e) {
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}

how to TextView.setText(List<String>object) like TextView.setText(array[index]) settext from List

Hello I have a list and i try to do settext from it, example I knew that TextView.setText(List<String>object) like TextView.setText(array[index]) but it is not working.I tried with get also.Is it the right way to implement custom Adapter:
firtsly I should settext List and then I will add images and so on.
Below is my code :
public class GetName extends Fragment {
ListView listview;
List<ParseObject> ob;
ProgressDialog mProgressDialog;
//ArrayAdapter<String> adapter;
CustomList adapter;
public GetName()
{
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Parse.initialize(getActivity(), "user", "pass");
defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
View view=inflater.inflate(R.layout.getnewlay,container, false);
new GetData().execute();
return view;
}
private class GetData extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(getActivity());
mProgressDialog.setTitle("Parse.com Simple ListView Tutorial");
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
ParseQuery query = new ParseQuery("Name");
query.orderByDescending("_created_at");
try {
ob = query.find();
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
listview = (ListView)getView().findViewById(R.id.listviewget);
adapter = new CustomList(getActivity(), ob);
/*ArrayAdapter<String>(getActivity(),
R.layout.listview_item);*/
// Retrieve object "name" from Parse.com database
for (ParseObject country : ob) {
adapter.add((String) country.get("name"));
}
listview.setAdapter(adapter);
}
}
}
Adapter class:
public class CustomList extends ArrayAdapter<String> {
private final Activity context;
private final String[] descr;
private final Integer[] imageId;
private final Integer[] imagId;*/
private List<ParseObject> ob;
public CustomList(Activity context, List<ParseObject> ob) {
super(context, R.layout.list_single);
this.ob = ob;
this.context = context;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.list_single, null, true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.lname);
>for(ParseObject i : ob) txtTitle.setText((CharSequence) i);
> txtTitle.setText( ob.get(position));
return rowView;
}
}
use this
TextView.setText(String.valueOf(array[index]));
Your object should be string. For example,
TextView.setText("Your Text");
only work.
So try like,
TextView.setText(array[index].toString())
or
TextView.setText(String.valueOf(array[index]))
I hope this will help you.
textView.setText(array[index].toString());
Or simply
textView.setText(array[index]+"");
You need to change this from
txtTitle.setText(ob.get(position));
to
txtTitle.setText(ob.get(position).get("name"));
Simply you can do this:
TextView.setText(String.valueOf(array[index]));

Custom adapter for ListView (only 1 ImageView being displayed)

For some reason my custom adapter is only allowing me to have 1 image visible in the list view at any time, I am not sure why this is happening. There should be a image within each list item but only the last list item has its image set, so I assume I am re-using a value somewhere that I should not be. The rest of the list items are being set properly.
public class CustomAdapter extends ArrayAdapter<Item> {
private ArrayList<Item> itemList;
private ViewHolder holder;
private Context context;
public CustomAdapter(Context context, int textViewResourceId, ArrayList<Item> list) {
super(context, textViewResourceId, list);
this.itemList = new ArrayList<Item>();
this.itemList.addAll(list);
this.context = context;
}
private class ViewHolder {
ImageView img;
TextView name;
CheckBox access;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.list_grid, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.access = (CheckBox) convertView.findViewById(R.id.checkBox1);
holder.img = (ImageView) convertView.findViewById(R.id.imageView1);
convertView.setTag(holder);
}
else { holder = (ViewHolder) convertView.getTag(); }
Item it = itemList.get(position);
new UrlLookup().execute(it.getUrl());
holder.name.setText(it.getName());
holder.access.setChecked(it.isSelected());
return convertView;
}
//Create an image from the url passed in from the server and display it on the image view
private class UrlLookup extends AsyncTask<String, Integer, String>{
Bitmap bmp;
#Override
protected String doInBackground(String... params){
try {
URL u = new URL(params[0]);
bmp = BitmapFactory.decodeStream(u.openConnection().getInputStream());
} catch (Exception e) { e.printStackTrace(); }
return "Done!";
}
#Override
protected void onPostExecute(String result){
super.onPostExecute(result);
holder.img.setImageBitmap(bmp);
}
}
}
You're forgetting the fact that your holder changes every time a view is visible. So it's normal only the last item has an image.
AsyncTask will take considerably longer to finish than your getView method.
You should pass your ImageView to your AsyncTask:
new UrlLookup().execute(it.getUrl(), holder.img);
To call the AsyncTask
private class UrlLookup extends AsyncTask<Object, Integer, String>{
Bitmap bmp;
ImageView view;
#Override
protected String doInBackground(Object... params){
view = (ImageView) params[1];
try {
URL u = new URL((String)params[0]);
bmp = BitmapFactory.decodeStream(u.openConnection().getInputStream());
} catch (Exception e) { e.printStackTrace(); }
return "Done!";
}
#Override
protected void onPostExecute(String result){
super.onPostExecute(result);
view.setImageBitmap(bmp);
}
}
Now you will have a reference of the ImageView of every row in every AsyncTask.
I would like to point out to you that Koush has a splendid project for doing just what you want:
UrlImageViewHelper

Categories

Resources