Android Show autocomplete values within a HashMap - android

public class Select_outlet_sales extends Activity {
private AutoCompleteTextView select_outlet;
ArrayList<HashMap<String, String> > ar=new ArrayList<HashMap<String, String> >();
HashMap<String, String> x=new HashMap<String, String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.select_outlet_sales);
select_outlet = (AutoCompleteTextView) findViewById(R.id.select_outlet);
select_outlet.setTextIsSelectable(true);
getValues();
ArrayAdapter<HashMap<String, String>> adapter = new ArrayAdapter<HashMap<String, String>>(
this, android.R.layout.simple_dropdown_item_1line, ar);
select_outlet.setAdapter(adapter);
}
public void getValues() {
x.put("id"," aaaaa");
ar.add(x);
}
}
Here I used the above code to show data stored in a Hashmap but i want to display only the value of id. But when i try that it shows the entire hash map.Can you help me to do that?

Don't use ar but do something like this
List<String> strings = new ArrayList<String>();
for(int i = 0; i < x.size(); i++)
{
strings.add(x.get("id"));
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line,strings);
select_outlet.setAdapter(adapter);

That's because inside ArrayAdapter created list of HashMaps. You should translate your HashMap into ArrayList<Pair<String, String>> for example and override method getView of ArrayAdapter.
class MyAdapter extends ArrayAdapter<Pair<String, String>>{
public MyAdapter (Context context, List<Pair<String, String>> data) {
super(context, android.R.layout.simple_list_item_1,data);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if(view == null) {
view = new TextView(getContext());
}
((TextView)view).setText(getItem(position).second);
return view;
}
}

Add this to your code:
select_outlet.setOnItemClickListener( new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
HashMap<String, String> hashMap = (HashMap<String, String>)parent.getItemAtPosition
(position);
Iterator<String> iterator = hashMap.keySet().iterator();
while(iterator.hasNext()) {
String key = (String) iterator.next();
String value = (String)hashMap.get(key);
select_outlet.setText(value);
}
}
});
This will show only "aaaaa"in AutoComplete textbox.

Related

Custom list view not refreshing after changes

There are many questions on updating a custom list view, one common problems seems to be a reference issue with the ArrrayList as in this answer or a not calling update from the UI thread. Though I have not managed to fix my issue with those examples.
As far as I can tell, the Arraylist (nameScoresList) is being updated and the getView function in the adapter also appears to be called when notifyDatasetChanged is called. Looking at the logs in different locations in the code the Arraylist is changing with the new values.
However, the screen of the app remains with the original list view rendered and does not change with the altered values of nameScoresList.
Can anyone see the mistake I am making? Thanks
The code for my adapter is:
public class ListViewAdapter extends BaseAdapter{
public ArrayList<HashMap<String, String>> list;
Activity activity;
TextView txtFirst;
TextView txtSecond;
public ListViewAdapter(Activity activity, ArrayList<HashMap<String, String>> list){
super();
this.activity=activity;
this.list=list;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater=activity.getLayoutInflater();
if(convertView == null){
convertView=inflater.inflate(R.layout.list_row_name_score, null);
txtFirst=(TextView) convertView.findViewById(R.id.name);
txtSecond=(TextView) convertView.findViewById(R.id.score);
}
HashMap<String, String> map=list.get(position);
txtFirst.setText(map.get(FIRST_COLUMN));
txtSecond.setText(map.get(SECOND_COLUMN));
Log.d("CHECK_UPDATE", map.get(SECOND_COLUMN));
return convertView;
}
// Two previous attempts at an update function
//
// public void refreshScores(float[] outputScores) {
// int count = 0;
// for(HashMap<String, String> entry : this.list) {
// entry.put(SECOND_COLUMN, Float.toString(outputScores[count]));
// count += 1;
// }
// this.notifyDataSetChanged();
// }
// public void refreshScores(ArrayList<HashMap<String, String>> nameScoresList) {
// list.clear();
// list.addAll(nameScoresList);
// this.notifyDataSetChanged();
// }
}
These are the sections which I think are relevant from the main activity (I can add more if needed):
private ArrayList<HashMap<String, String>> nameScoresList = new ArrayList<HashMap<String, String>>();
public class SpeechActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// Put data in nameScoresList;
for (int i=0; i < speakerJson.entrySet().size(); i++){
nameScoresList.add(new HashMap<String, String>());
}
int ID_number;
for (Map.Entry<String, JsonElement> entry : speakerJson.entrySet()) {
speaker = entry.getKey();
ID_number = entry.getValue().getAsInt();
HashMap<String,String> temp=new HashMap<String, String>();
temp.put(FIRST_COLUMN, speaker.replace("_", " "));
temp.put(SECOND_COLUMN, Float.toString(0));
nameScoresList.set(ID_number - 1, temp);
}
adapter = new ListViewAdapter(this, nameScoresList);
nameScoresLV.setAdapter(adapter);
record();
}
private void record() {
// Get outputScores
// Update Arraylist which ListView uses
int count = 0;
for (HashMap<String, String> entry : nameScoresList) {
entry.put(SECOND_COLUMN, Float.toString(outputScores[count]));
count += 1;
}
runOnUiThread(
new Runnable() {
#Override
public void run() {
adapter.notifyDataSetChanged();
// These are calls which correspond to the commented functions in ListViewAdapter class
//adapter.refreshScores(outputScores);
//adapter.refreshScores(nameScoresList);
}
});
}

How to use CustomAdapter with ListView from XML Async Task

I achieved populate a ListView using StringBuilder from a Internet XML Source.
With this code the listView is populated with only one String but I want populate the listview by elements: getIdLine and getTimeLeft (With CustomAdapter) for customize the layout of the listView items in separated Strings.
How to achieve this?
EDITED CODE
FragmentActivity.class
private ListView listViewEMT;
private ArrayList<HashMap<String, String>> yourList;
... AsyncTask
protected void onPostExecute(String string) {
super.onPostExecute(string);
CustomAdapter adapter = new CustomAdapter(getActivity(), yourList);
listViewEMT.setAdapter(adapter);
this.progressDialog.dismiss();
}
/** RSS HANDLER CLASS */
class RSSHandler extends DefaultHandler {
StringBuffer chars;
private Arrival currentArrival;
RSSHandler() {
this.currentArrival = new Arrival();
this.chars = new StringBuffer();
}
public void characters(char[] arrc, int n, int n2) {
this.chars.append(new String(arrc, n, n2));
}
public void endElement(String string, String string2, String string3) throws SAXException {
super.endElement(string, string2, string3);
if ((string2.equalsIgnoreCase("idStop")) && (this.currentArrival.getIdStop() == null)) {
this.currentArrival.setIdStop(this.chars.toString());
}
if ((string2.equalsIgnoreCase("idLine")) && (this.currentArrival.getIdLinea() == null)) {
this.currentArrival.setIdLinea(this.chars.toString());
}
if ((string2.equalsIgnoreCase("TimeLeftBus")) && (this.currentArrival.getTimeLeft() == 0)) {
int n = Integer.valueOf((String)(this.chars.toString()));
this.currentArrival.setTimeLeft(n);
}
if (!(string2.equalsIgnoreCase("Arrive"))) return;
yourList.add((HashMap<String, String>)(currentArrival.getMap()));
this.currentArrival = new Arrival();
}
public void startElement(String string, String string2, String string3, org.xml.sax.Attributes attributes) throws SAXException {
super.startElement(string, string2, string3, attributes);
this.chars = new StringBuffer();
string2.equalsIgnoreCase("Arrive");
}
}
Arrival.class
...getters and setters
public HashMap<String, String> getMap() {
HashMap<String, String> map;
map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put("KEY1", idLinea);
map.put("KEY2", String.valueOf(timeLeft));
return map;
}
CustomAdapter.class Thanks to Nabin
public class CustomAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater = null;
private List<String> listString;
public CustomAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data = d;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.emt_item, null);
TextView tv1 = (TextView) vi.findViewById(R.id.itemLine);
TextView tv2 = (TextView) vi.findViewById(R.id.itemTime);
HashMap<String, String> map;
map = data.get(position);
tv1.setText(map.get("KEY1"));
tv2.setText(map.get("KEY2"));
return vi;
}
}
Create a custom adapter as following:
public class ArrayAdapter extends BaseAdapter{
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater = null;
private List<String> listString;
public ArrayAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data = d;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
//your getView method here
}
GetView Method
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.custom, null);
TextView tv1 = (TextView) vi.findViewById(R.id.tvone);
TextView tv2 = (TextView) vi.findViewById(R.id.tvtwo);
HashMap<String, String> map = new HashMap<String, String>();
map = data.get(position);
tv1.setText(map.get("KEY1"));
tv2.setText(map.get("KEY2"));
return vi;
}
Make array list as:
ArrayList<HashMap<String, String>> yourList;
And fill yourList as
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put("KEY1", value1);
map.put("KEY2", value2);
yourList.add(map);
And while making object of the custom adapter
CustomAdapter adapter = new CustomAdapter(YourActivity.this, yourList);
list.setAdapter(adapter);
For list you can do
list = (ListView) getView().findViewById(android.R.id.list);

Items in listview not setting up using BaseAdapter and SimpleAdapter

I'm facing problem with setting up the items in ListView, I'm using an Async task for updating the items. Here is what I have done so far.
Async Task onPostExecute()
#Override
protected void onPostExecute(String result) {
notifyList = new ArrayList<HashMap<String, String>>();
try {
JSONObject rootObj = new JSONObject(result);
JSONObject jSearchData = rootObj.getJSONObject("notifications");
int maxlimit = 5;
for (int i = 0; i < maxlimit; i++) {
JSONObject jNotification0 = jSearchData.getJSONObject(""
+ i + "");
String text = jNotification0.getString("text");
String amount = jNotification0.getString("amount");
String state = jNotification0.getString("state");
System.out.println(text);
System.out.println(amount);
System.out.println(state);
HashMap<String, String> map = new HashMap<String, String>();
map.put("text", text);
map.put("amount", amount);
notifyList.add(map);
}
if (notification_adapter != null) {
notification_list.setAdapter(new CustomNotificationAdapter(
notifyList));
}
} catch (Exception e) {
e.printStackTrace();
}
}
Here is my CustomNotification class which extends BaseAdapter
public class CustomNotificationAdapter extends BaseAdapter {
public ArrayList<HashMap<String, String>> notificationData = new ArrayList<HashMap<String, String>>();
public CustomNotificationAdapter(
ArrayList<HashMap<String, String>> notificationData) {
this.notificationData = notificationData;
}
#Override
public int getCount() {
return notificationData.size();
}
#Override
public Object getItem(int position) {
return notificationData.get(position).get("text").toString();
}
#Override
public long getItemId(int position) {
return notificationData.get(position).get("text").hashCode();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
LayoutInflater inflater = getLayoutInflater();
vi = inflater.inflate(R.layout.custom_notification_list, null);
TextView notificationText = (TextView) findViewById(R.id.notificationText);
TextView notificationAmount = (TextView) findViewById(R.id.notificationPoint);
notificationText
.setText(notificationData.get(position).get("text"));
notificationAmount.setText(notificationData.get(position).get(
"amount"));
return vi;
}
}
NotificationAdapter class which extends SimpleAdapter
public class NotificationAdapter extends SimpleAdapter {
List<Map<String, String>> cur_list = new ArrayList<Map<String, String>>();
public NotificationAdapter(Context context,
List<? extends Map<String, ?>> data, int resource, String[] from,
int[] to) {
super(context, data, resource, from, to);
}
}
I'm able to get all the data from JSONResponse but I'm not able to show it on the list. What am I missing?
Any kind of help will be appreciated.
Try replacing this:
if (notification_adapter != null) {
notification_list.setAdapter(new CustomNotificationAdapter(
notifyList));
}
with this:
notification_adapter = new CustomNotificationAdapter(notifyList);
notification_list.setAdapter(notification_adapter);
This will set the adapter to the new JSON data even if notification_adapter was previously null.
Call notification_adapter.notifyDataSetChanged() after updating your adapter's data or remove the if (notification_adapter != null) {if you want it easy and bad.
to update your data:
public void updateData(ArrayList<HashMap<String, String> notificationData){
this.notificationData = notificationData;
this.notifyDataSetChanged();
}
Inside your adapter, and call it like: notification_adapter.updateData(notifyList);

How to add data dynamically into the spinner from xml

Hello I'm downloading XML and parsing data. I want to add data to the spinner. The data updates every time I run the application.
public class Main extends ListActivity {
TextView valueTextView;
HashMap<String, String> name=null;
private HashMap<String, String> array_spinner[];
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main)
ArrayList<HashMap<String, String>>mylist = new ArrayList<HashMap<String, String>>();
String xml = XMLfunctions.getXML();
Document doc = XMLfunctions.XMLfromString(xml);
NodeList nodes = doc.getElementsByTagName("Table");
Toast.makeText(Main.this, "ID '" + nodes.getLength(),Toast.LENGTH_LONG).show();
for (int i = 0; i < nodes.getLength(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element)nodes.item(i);
map.put("id", XMLfunctions.getValue(e, "id"));
map.put("name", "Name:" + XMLfunctions.getValue(e, "name"));
map.put("Score", "Score: " + XMLfunctions.getValue(e, "score"));
mylist.add(map);
}
valueTextView = (TextView)findViewById(R.id.selected);
Spinner s = (Spinner)findViewById(R.id.spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
}
Its incomplete code I don't know how to apply SpinnerAdapter Please anyone help me
Thank you
Abhishek
I would take your Hashmap and create an Array instead, without knowing how you want your Spinner to work I would combine Name and Score. Then make the call to the adapter like this:
String[] nameScore = (xml name score data in string array)
ArrayAdapter adapter= new ArrayAdapter(this, android.R.layout.simple_spinner_item, nameScore);
s.setAdapter(adapter);
Anything more complex than that then you will have to make a custom adapter.
Answer:::
Here is what you do. Create a Class called NameData then set properties with ID, name and score.
public class NameData {
public int id;
public String name;
public int score;
public NameData(int i, String n, int s) {
this.id = i;
this.name = n;
this.score = s;
}
}
Next create a method to connect to your data parse it and put each item into this NameData Object
public List<NameData> getNameData() {
List<NameData> list = new LinkedList<NameData>();
//get data from url and parse it to your namedata object
// /.....for loop (psuedo coding here...
list.add(new NameData(id, name, score));
// end for loop
return list;
}
then you will need to make a custom List adapter that uses a layout you design for the rows.:
private class ItemsAdapter extends BaseAdapter {
NameData[] items;
public ItemsAdapter(Context context, int textViewResourceId, NameData[] md) {
this.items = md;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
TextView text1;
View view = convertView;
if (view == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.yourRowForListlayout, null);
}
text1 = (TextView) view.findViewById(R.id.yourRowForListlayoutTextView);
text1.setText("" + (position+1));
return view;
}
#Override
public int getCount() {
return this.items.length;
}
#SuppressWarnings("boxing")
#Override
public Object getItem(int p) {
return p;
}
#Override
public long getItemId(int p) {
return p;
}
}
then in your creation code you can take this list and add it directly to the adapter:
List<NameData> list = getNameData();
adapter = new ItemsAdapter(this, R.layout.yourRowForListlayout, list.toArray(new NameData[list.size()]) );
setAdapter(adapter);
And thats the way I would do it for a custom list.

Text not appearing in listview

I have a listview in which i wanted to have custom typeface e.g. Arial. for this i subclassed the SimpleAdapter and implemented the the typeface for textviews in the list. But after this implementation, the list appears to be blank but the onClick is still working and clicking on the blank list item navigates me to the next activity as required.
Code
public class TopNewsActivity extends ListActivity {
public static final String LOG_TAG = "Infra";
private ProgressDialog progressDialog;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listplaceholder);
new BackgroundAsyncTask().execute();
}
public class BackgroundAsyncTask extends AsyncTask<String, Integer, ArrayList<HashMap<String, String>>> {
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(TopNewsGroup.group);
progressDialog.setCancelable(true);
progressDialog.setMessage("Loading...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setProgress(0);
progressDialog.show();
}
#Override
protected ArrayList<HashMap<String, String>> doInBackground(String... paths) {
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
String xml = XMLfunctions.getTopNewsXML();
Document doc = XMLfunctions.XMLfromString(xml);
int numResults = XMLfunctions.numResults(doc);
Log.d(LOG_TAG, "Number of Results: " + numResults);
if ((numResults <= 0)) {
Toast.makeText(TopNewsActivity.this, "No Result Found",Toast.LENGTH_LONG).show();
return null;
}
NodeList nodes = doc.getElementsByTagName("result");
for (int i = 0; i < nodes.getLength(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) nodes.item(i);
map.put("id", XMLfunctions.getValue(e, "id"));
map.put("title", XMLfunctions.getValue(e, "title"));
map.put("date", XMLfunctions.getValue(e, "date"));
map.put("recordDate", XMLfunctions.getValue(e, "recordDate"));
mylist.add(map);
}
return mylist;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
ListAdapter adapter = new MySimpleAdapter(TopNewsActivity.this, result, R.layout.list_item, new String[] { "title", "date" }, new int[] { R.id.item_title, R.id.item_subtitle });
setListAdapter(adapter);
progressDialog.dismiss();
final ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
#SuppressWarnings("unchecked")
#Override
public void onItemClick(AdapterView<?> a, View view, final int position, long id) {
HashMap<String, String> o = (HashMap<String, String>) lv.getItemAtPosition(position);
Intent i = new Intent(TopNewsActivity.this, NewsDetails.class);
i.putExtra("content_id", o.get("id"));
i.putExtra("title", o.get("title"));
i.putExtra("date", o.get("recordDate"));
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
View v = TopNewsGroup.group.getLocalActivityManager().startActivity("ShowNews", i).getDecorView();
// Again, replace the view
TopNewsGroup.group.replaceView(v);
}
});
}
}
public class MySimpleAdapter extends SimpleAdapter {
public MySimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
}
public View getView(int position, View view, ViewGroup parent){
Typeface localTypeface1 = Typeface.createFromAsset(getAssets(), "fonts/arial.ttf");
View v = view;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.list_item, null);
}
TextView tt = (TextView) v.findViewById(R.id.item_title);
tt.setBackgroundColor(R.color.white);
tt.setTypeface(localTypeface1);
tt.setTextColor(android.R.color.black);
TextView bt = (TextView) v.findViewById(R.id.item_subtitle);
bt.setBackgroundColor(R.color.white);
bt.setTypeface(localTypeface1);
bt.setTextColor(R.color.grey);
return v;
/*Typeface localTypeface1 = Typeface.createFromAsset(getAssets(), "fonts/arial.ttf");
View v = super.getView(position, view, parent);
((TextView) v).setTypeface(localTypeface1);
return v;*/
}
}
}
In the Declaration of Simple Adapter use this code
public MySimpleAdapter(Context context, ArrayList<? extends Map<String, String>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
}
Or in other places , Change your ArrayList to List . I feel there's a conflict there .
Rahul, Use this link to understand a bit more on using SimpleAdapter
the answer is quite simple as it was my mistake, wasn't providing the ItemText to be viewed to the getView method:
public class MySimpleAdapter extends SimpleAdapter {
private ArrayList<HashMap<String, String>> results;
public MySimpleAdapter(Context context, ArrayList<HashMap<String, String>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
this.results = data;
}
public View getView(int position, View view, ViewGroup parent){
Typeface localTypeface1 = Typeface.createFromAsset(getAssets(), "fonts/arial.ttf");
View v = view;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.list_item, null);
}
TextView tt = (TextView) v.findViewById(R.id.item_title);
tt.setText(results.get(position).get("title"));
tt.setTypeface(localTypeface1);
TextView bt = (TextView) v.findViewById(R.id.item_subtitle);
bt.setText(results.get(position).get("date"));
bt.setTypeface(localTypeface1);
return v;
}
}
:)

Categories

Resources