I am trying to populate a ListView control in an Android app. I have looked at many code samples and all seem to suggest doing it this way. However, when I try to implement this I get the following error:
The constructor ArrayAdapter(MainActivity.ReadJsonTask, int, ArrayList) is undefined
protected void onPostExecute(String result){
try{
ListView lv = (ListView)findViewById(R.id.lstItems);
JSONObject jsonObj = new JSONObject(result);
ArrayList<String> items = new ArrayList<String>();
Iterator<String> looper = jsonObj.keys();
while(looper.hasNext()){
String key = looper.next();
items.add(jsonObj.get(key).toString());
}
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
lv.setAdapter(adapter);
}catch(Exception ex){
Log.d("ReadAdscendJsonTask", ex.getLocalizedMessage());
}
}
What is wrong here? Thanks!
It seems so that this piece of code is from inner class. And in such case this refers to this inner class instead of MainActivity. Changing Context parameter to MainActivity.this for ArrayAdapter should fix the error.
Related
I want to add the content from an EditText to a ListView here is my code that dosen't work:
mass = userInput.getText().toString();
//fruits is a String[]
final List<String> fruits_list = new ArrayList<String(Arrays.asList(fruits));
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(context.getApplicationContext(), android.R.layout.simple_list_item_1, fruits_list);
fruits_list.add(mass);
lv.setAdapter(arrayAdapter);
The code adds the item to the listview but when the process is repeated it replaces the previously added string from the EditText.
Your code appears to create a new fruits_list array every time you read the user's entry from the EditText. This will result in only the latest entry being added to your list, replacing any previously added entries.
You need to create the array once (probably as a class member) and then update it each time you read the user input, e.g. something like:
private ArrayList<String> fruits_list;
private ArrayAdapter<String> arrayAdapter;
...
public void initialise(Context context) {
fruits_list = new ArrayList<>(Arrays.asList(fruits));
arrayAdapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, fruits_list);
lv.setAdapter(arrayAdapter);
}
....
public void getInput(
mass = userInput.getText().toString();
fruits_list.add(mass);
arrayAdapter.notifyDataSetChanged();
}
Note the use of arrayAdapter.notifyDataSetChanged() to signal that new data has been added to the underlying data set.
As #Aaron says, you should also look at RecyclerView as a possible replacement, although that's a little bit more complicated to set up.
Background
When I fill a spinner using a resource array, things work just fine:
Spinner countryCodeSpinner = (Spinner) findViewById(R.id.country_code_spinner);
countryCodeSpinner.setOnItemSelectedListener(this);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.country_codes_array, android.R.layout.simple_spinner_item);
where country codes are read from a resource:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array
name="country_codes_array">
<item>971</item>
<item>961</item>
<item>628</item>
<item>193</item>
<item>477</item>
</string-array>
</resources>
output:
Question
but when I fill up the spinner contents from an api call like so:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
..
Spinner currencySpinner = (Spinner) findViewById(R.id.currency_spinner);
populateCurrency(currencySpinner);
private void populateCurrency(final Spinner spinner) {
_currencies = new HashMap<String, String>();
final Context context = this;
// getting the contents of spinner from api call
new SyncHelper().get(CreateOrderActivity.this,
Connections.CURRENCIES(CreateOrderActivity.this),
null, null, new SyncListener() {
#Override
public void onSuccess(String data, int requestCode) {
try {
JSONObject object = new JSONObject(data);
if (object.getString("errors") == "false") {
JSONArray currenciesArray = object.getJSONObject("data")
.getJSONArray("currencies");
for (int i=0; i< currenciesArray.length(); i++) {
String currencyRef = currenciesArray.getJSONObject(i).getString("ref");
String currencyId = currenciesArray.getJSONObject(i).getString("id");
_currencies.put(currencyRef, currencyId);
}
String[] currencyrefs = Arrays.copyOf(_currencies.keySet().toArray(),
_currencies.keySet().toArray().length, String[].class);
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item,currencyrefs);
spinner.setAdapter(adapter);
then the spinner rendered view is all shrunk like so:
even though in both cases, we're using android.R.layout.simple_spinner_item.. any idea how to fix this?
I wasn't able to reproduce the issue, for me the first example gives an output similar to the second example and second example gives the same output (No margins, height is set to wrap_content, also for the second example, I only used the same adapter constructor to simulate). The difference in behavior might be because of the different APIs (I used an emulator with API 26).
However, to me your first and desired output looks like simple_spinner_dropdown_item instead of simple_spinner_item and I was able to produce a similar spinner with simple_spinner_dropdown_item, so you might want to check it out.
private String[] listView2 = {"aa","bb","cc","dd","ee"};
listView1 = (ListView)findViewById(R.id.listView1);
listAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,listView2);
listView1.setAdapter(listAdapter);
Change listView2[1] to "zzz".
Following code isn't work.
listView2[1] = "zzz";
you also need to call
listAdapter.notifyDataSetChanged();
Or use one of the listAdpater methods for changing the data:
add(T), insert(T, int), remove(T), clear()
you can update adapter like this:
adapter.insert("zz", 1);
adapter.notifyDataSetChanged();
Try this.^_^
public void newListView(){
listAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,listView2);
listView1.setAdapter(listAdapter);
}
listView2[0] = "zz";
newListView();
Currently I'm using an ArrayAdapter which I just import. As the question states I want to get images into my listviews. I'm loading information into my list using JSONObjects and storing them into my ArrayLists. I know my current method removes html tages from the JSONObjects.
public class Home extends Activity {
ListView lView;
TextView tView;
ArrayAdapter lAdapter;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_layout);
lView = (ListView) findViewById(android.R.id.list);
//tView = (TextView) findViewById(android.R.id.);
loadList(lView);
}
public void loadList(ListView lView){
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall("URL", ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
ArrayList<String> titles = new ArrayList<String>();
ArrayList<String> body = new ArrayList<String>();
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray entries = jsonObj.getJSONArray("entries");
for (int i = 0; i < entries.length(); i++) {
JSONObject c = entries.getJSONObject(i);
String text = c.getString("introtext");
if(text == "null"){
text = "No text here" + "\n" + "\n";
}
else {
text = android.text.Html.fromHtml(text).toString();
}
String title= c.getString("title");
String full = title + "\n" + "\n" + text;
titles.add(full);
//body.add(text);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
lAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, titles);
lView.setAdapter(lAdapter);
}
}
Any suggestions would be great help
Thanks
First create a layout same what you want to show in a row, now create a class for a custom adapter like:
public class MyAdapter extends ArrayAdapter<T>{
}
Where T represents the entity class, which represents your data model.
Now under override method:
public View getView(final int position, View convertView, ViewGroup parent) {}
Inflate your layout created for the row, and set each view as you want to show.
Don't forgot to use lazy loading for the image to load over the imageview.
Hope it will help you.
You will need to create a custom adapter that has your own Layout defined. In this layout, you can include whatever you want (including an ImageView, that you can place your image).
There are many examples, but the important thing to know in your code, is you will supply your own adapter here, and set it up a bit differently:
lAdapter = new ArrayAdapter<String>(this, R.layout.my_custom_adapter, titles);
Try to use a Base Adapter
Inflate a custom Xml having a imageview using the base adapter
You can put any views(Image,textview etc ) depending on your
requirement
Finally use picasso or imageloader to populate images using the JSON
response to your base adapter
Hope it helps, Revert back to me if you need any more help, Happy coding
You'll have to create a custom adapter instead of ArrayAdapter, so that you can use your own layout for every row, and perform any 'image loading' there. Try creating a class that extends the BaseAdapter abstract class from the framework. Also, search the web or here (in stackoverflow) you'll find tons of tutorials on how to create a custom adapter.
Since downloading and loading images can be a bit of a pain if you aren't experienced with ListViews and custom adapters, I would suggest looking up two 3rd party libraries for this job:
Picasso or Universal-Image-Loader, each one having examples on how to use them alongside with custom adapters
I looked at the following site: ListView Example
Which describes how to implement a search function in a listview which uses the default adapter and it works fine.
How can I modify it so I can use the same for a Custom Adapter for my listview?
Partial code is:
dataList = (ListView) findViewById(R.id.lvFiles);
tvQuote = (TextView) findViewById(R.id.tvDisplay);
tvQuote.setTypeface(Typeface.createFromAsset(MainActivity.this.getAssets(), "fonts/roboto.ttf"));
for (int y=0; y<strNamesOfAllah.length;y++) {
name = strNamesOfAllah[y];
meaning = strMeaning[y];
rowsArray.add(new SetRows(R.drawable.icon, name, meaning));
}
adapter = new SetRowsCustomAdapter(MainActivity.this, R.layout.customlist, rowsArray);
dataList.setAdapter(adapter);
dataList.setClickable(true);
You need to override getFilter inside of your adapter and return a new customFilter object that you create. See this answer: No results with custom ArrayAdapter Filter
Edit:
#Override
public Filter getFilter() {
if(customFilter == null){
customFilter = new CustomFilter();
}
return customFilter;
}