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
}
}
Related
I am trying to use TextChangedListener to implement search functionality on my ListView. But after adding some character in EditText; the ListView goes blank. I have implemented filter method in my ArrayAdapter class.
I am getting my data from JSON.
My Logcat shows: getSlotFromBufferLocked: unknown buffer
Is there any other way to search ListView?
Here's my code:
UserList.java
public class UserList extends AppCompatActivity {
private ListView listView;
private ArrayList<MyDataModel> list;
private MyArrayAdapter adapter;
private EditText search;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_list);
search = (EditText) findViewById(R.id.search);
//Array List for Binding Data from JSON to this List
list = new ArrayList<>();
//Binding that List to Adapter
adapter = new MyArrayAdapter(this, list);
//Getting List and Setting List Adapter
listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(adapter);
listView.setTextFilterEnabled(true);
search.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String text = search.getText().toString().toLowerCase(Locale.getDefault());
adapter.filter(text);
}
#Override
public void afterTextChanged(Editable s) {
}
});
//Checking Internet Connection
if (InternetConnection.checkConnection(getApplicationContext())) {
new GetDataTask().execute();
} else {
Snackbar.make(findViewById(R.id.parentLayout),"Internet Connection Not Available", Snackbar.LENGTH_LONG).show();
}
}
//Creating Get Data Task for Getting Data From Web
class GetDataTask extends AsyncTask<Void, Void, Void> {
ProgressDialog dialog;
int jIndex;
int x;
#Override
protected void onPreExecute() {
super.onPreExecute();
//Progress Dialog for User Interaction
x=list.size();
if(x==0)
jIndex=0;
else
jIndex=x;
dialog = new ProgressDialog(UserList.this);
dialog.setTitle("Please Wait..."+x);
dialog.setMessage("Retrieving Data");
dialog.show();
}
#Nullable
#Override
protected Void doInBackground(Void... params) {
//Getting JSON Object from Web Using okHttp
JSONObject jsonObject = JSONParser.getDataFromWeb();
try {
if (jsonObject != null) {
if(jsonObject.length() > 0) {
JSONArray array = jsonObject.getJSONArray(Keys.KEY_CONTACTS);
//Check Length of Array...
int lenArray = array.length();
if(lenArray > 0) {
for( ; jIndex < lenArray; jIndex++) {
//Creating Every time New Object and adding to List
MyDataModel model = new MyDataModel();
JSONObject innerObject = array.getJSONObject(jIndex);
String name = innerObject.getString(Keys.KEY_NAME);
model.setName(name);
list.add(model);
}
}
}
} else {
}
} catch (JSONException je) {
Log.i(JSONParser.TAG, "" + je.getLocalizedMessage());
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
dialog.dismiss();
//Checking if List size if more than zero then update ListView
if(list.size() > 0) {
adapter.notifyDataSetChanged();
} else {
Snackbar.make(findViewById(R.id.parentLayout), "No Data Found", Snackbar.LENGTH_LONG).show();
}
}
}
}
I have implemented the filter method in my ArrayAdapter class.
Here's my ArrayAdapter class:
MyArrayAdapter.java
public class MyArrayAdapter extends ArrayAdapter<MyDataModel> implements Filterable{
List<MyDataModel> modelList;
Context context;
private LayoutInflater mInflater;
private ArrayList<MyDataModel> arrayList;
public MyArrayAdapter(Context context, List<MyDataModel> objects) {
super(context, 0, objects);
this.context = context;
this.mInflater = LayoutInflater.from(context);
modelList = objects;
this.arrayList = new ArrayList<MyDataModel>();
this.arrayList.addAll(modelList);
}
#Override
public MyDataModel getItem(int position) {
return modelList.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder vh;
if (convertView == null) {
View view = mInflater.inflate(R.layout.layout_row_view, parent, false);
vh = ViewHolder.create((RelativeLayout) view);
view.setTag(vh);
} else {
vh = (ViewHolder) convertView.getTag();
}
MyDataModel item = getItem(position);
vh.textViewName.setText(item.getName());
return vh.rootView;
}
private static class ViewHolder {
public final RelativeLayout rootView;
public final TextView textViewName;
private ViewHolder(RelativeLayout rootView, TextView textViewName) {
this.rootView = rootView;
this.textViewName = textViewName;
}
public static ViewHolder create(RelativeLayout rootView) {
TextView textViewName = (TextView) rootView.findViewById(R.id.textViewName);
return new ViewHolder(rootView, textViewName);
}
}
// Filter Class
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
modelList.clear();
if (charText.length() == 0) {
modelList.addAll(arrayList);
} else {
for (MyDataModel wp : arrayList) {
if (wp.getName().toLowerCase(Locale.getDefault()).contains(charText)) {
modelList.add(wp);
}
}
}
notifyDataSetChanged();
}
Try,
modelList = new ArrayList<MyDataModel>;
Write this line after modelList.clear(); and check.
Go with this link, and follow steps for implementing the same:
and the problem with buffer is called every textchanged listener will call everytime if you add or delete any character or space in it. So avoid using that. It will cause memory leak problems.
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
}
}
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]));
I am getting a java.lang.ClassCastException when trying to use an Interface and an AsyncTask from inside my adapter. I don't know if this is 'allowed', but I can't see why it wouldn't be as long as everything is kept in context.
The code starts in my Fragment when I try and set my GridView with a custom Adapter.
mSceneGridAdapter = new SceneGridAdapter(getActivity(), mScenesList);
Which leads to my SceneGridAdapter class being called
public class SceneGridAdapter extends BaseAdapter implements HandleProductThumbnail {
private Context mContext;
private ArrayList<Scene> mSceneList = null;
private LayoutInflater mInflater;
private Drawable mThumbnail;
public SceneGridAdapter() {}
public SceneGridAdapter(Context context, ArrayList<Scene> sceneList) {
super();
mContext = context;
if (mSceneList != null) {
clearData();
} else {
mSceneList = sceneList;
}
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.scene_cell, null);
}
ImageView sceneView = (ImageView) convertView.findViewById(R.id.sceneImage);
Scene scene = mSceneList.get(position);
String specifier = scene.getSpecifier() + "/" + scene.getName();
LoadScenes scenes = new LoadScenes(mContext, specifier);
scenes.execute();
sceneView.setBackground(mThumbnail);
return convertView;
}
#Override
public int getCount() {
return mSceneList.size();
}
#Override
public Object getItem(int position) {
return mSceneList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public void clearData() {
mSceneList.clear();
}
#Override
public void handleProductThumbnail(Drawable thumb) {
mThumbnail = thumb;
}
}
Which implements my Interface HandleProductThumbnails
public interface HandleProductThumbnail {
void handleProductThumbnail(Drawable thumb);
}
and then calls my AsyncTask loader class called LoadScenes, which loads the thumbnails and returns them to the adapter.
public class LoadScenes extends AsyncTask<Void, Void, Drawable> {
private static final String LOADING = "Loading...";
private static final String PNG = "_ORIGINAL.PNG";
private Context mContext;
private HandleProductThumbnail mHandleThumbnail = null;
private ProgressDialog mProgressDialog;
private String mSpecifier;
public LoadScenes () {}
public LoadScenes (Context context, String specifier) {
mContext = context;
mSpecifier = specifier;
}
#Override
public void onPreExecute() {
mProgressDialog = new ProgressDialog(mContext);
mProgressDialog.setMessage(LOADING);
mProgressDialog.show();
}
public Drawable doInBackground(Void... v) {
Drawable productThumbnail = getDrawable(mSpecifier);
return productThumbnail;
}
public void onPostExecute(Drawable productThumbnail) {
mProgressDialog.dismiss();
mHandleThumbnail = (HandleProductThumbnail) mContext;
mHandleThumbnail.handleProductThumbnail(productThumbnail);
}
public Drawable getDrawable(String specifier) {
Bitmap bmp = null;
Drawable productThumbnail = null;
specifier = specifier.replace("\\", "/") + PNG;
try {
bmp = BitmapFactory.decodeStream(mContext.getAssets().open(specifier));
if (bmp != null) {
int width = 300;
int height = 240;
bmp = Bitmap.createScaledBitmap(bmp, width, height, true);
productThumbnail = new BitmapDrawable(mContext.getResources(), bmp);
}
} catch (IOException e) {
e.printStackTrace();
}
return productThumbnail;
}
}
and finally my log
09-30 10:34:35.725: E/AndroidRuntime(22442): java.lang.ClassCastException: com.example.xxx.visualizer.VisualizerActivity cannot be cast to com.example.xxx.interfaces.HandleProductThumbnail
09-30 10:34:35.725: E/AndroidRuntime(22442): at com.example.xxx.visualizer.LoadScenes.onPostExecute(LoadScenes.java:46)
The Fragment is attached to an Activity called VisualizerActivity, and all the context being passed comes from that Activity. While this problem is somewhat layered, the code is fairly boilerplate. I was wondering if I am just doing something that isn't allowed? From my understanding of Context this should work. Please let me know what I'm doing wrong, why, and if it can be fixed. Thank you
Looks like your activity is not implementing the HandleProductThumbnail, but your custom adapter. In your case, instead of casting, I would rather add a method to the AsyncTask subclass:
public void setHandleProductThumbnail(HandleProductThumbnail listener) {
mHandleThumbnail = listener;
}
and inside OnPostExecute
public void onPostExecute(Drawable productThumbnail) {
mProgressDialog.dismiss();
if (mHandleThumbnail != null)
mHandleThumbnail.handleProductThumbnail(productThumbnail);
}
Your problem is here :
mHandleThumbnail = (HandleProductThumbnail) mContext;
You're casting mContext to HandleProductThumbnail whereas mContext is a Context, hence not implementing your custom interface. If you need a reference to the HandleProductThumbnail, pass it as a constructor argument.
Last note : if you're trying to load thumbnails on every list item, I would suggest the use of Picasso, which would make all this much simpler for you.
It is clearly visible that it would create an class cast exception,
because mContext is your activity`s object which is not implementing the "HandleProductThumbnail" interface.
Though you rectify your code by right casting, yet it will produce error due to below lines of code in your adapter
LoadScenes scenes = new LoadScenes(mContext, specifier);
scenes.execute();
sceneView.setBackground(mThumbnail);
Because second line is an async call and mThumbnail would be null.You may apply another approach for rendering images from URL at run time.
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>