Android. Using HashMap for listView - android

I try to use HashMap<String, String>() to populate ListView. I'm supposed to fetch my site API to get the latest news json representation. By now I basically try to simulate dynamic data and put the news manually. The problem I faced is that it won't add news as expected but just repeats them. Sorry for bad explanation. Here's my code to clarify
public class MainActivity extends Activity {
public final static String EXTRA_MESSAGE = "ru.rateksib.sendmessage.MESSAGE";
EditText editText;
ListView newsList;
Map<String, String> map;
ArrayList<HashMap<String, String>> NewsArrayList;
NewsArrayAdapter arrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
LayoutInflater inflater = this.getLayoutInflater();
View convertView = (View) inflater.inflate(R.layout.news_dialog, null);
builder.setView(convertView);
builder.setTitle("Новости компании");
// set up list view inside alertDialog
newsList = (ListView) convertView.findViewById(R.id.dialogNewsList);
// map
NewsArrayList = new ArrayList<HashMap<String, String>>();
map = new HashMap<String, String>();
map.put("title", "New branch opened!");
map.put("date", "28.03.2014");
NewsArrayList.add((HashMap<String, String>) map);
map.put("title", "Second one!");
map.put("date", "28.03.2014");
NewsArrayList.add((HashMap<String, String>) map);
// custom adapter
arrayAdapter = new NewsArrayAdapter(NewsArrayList, this);
newsList.setAdapter(arrayAdapter);
So when I run the app the list is populated twice with the last set of title and date.
My custom adapter code is
public class NewsArrayAdapter extends BaseAdapter {
ArrayList<HashMap<String,String>> names;
Context ctxt;
LayoutInflater inflater;
public NewsArrayAdapter(ArrayList<HashMap<String,String>> newsArrayList, Context c) {
names = newsArrayList;
ctxt = c;
inflater = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return names.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return names.get(arg0);
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
#Override
public View getView(int position, View view, ViewGroup viewGroup) {
// TODO Create the cell (View) and populate it with an element of the array
if (view == null) {
// view = inflater.inflate(android.R.layout.simple_list_item_1, viewGroup, false);
view = inflater.inflate(R.layout.dialog_news_list_item, viewGroup, false);
}
TextView title = (TextView) view.findViewById(R.id.title);
TextView date = (TextView) view.findViewById(R.id.date);
title.setText(names.get(position).get("title"));
date.setText(names.get(position).get("date"));
return view;
}
}

I know this is old post, but I know what the question is asking ask he request for a loop, just put your hashMap into the loop as well and you will be fine. for your loop n count, count on your variables
for(int i = 0; i< n; i++){
HashMap<String, String> hashMap = new HashMap<>();
map.put("title", $title);
map.put("date", $date);
classList.add(hashMap);
}

It's because you add two times map which is a reference to the same object. After your first NewsArrayList.add((HashMap<String, String>) map);, you overwrite the values of title and date, that's why you end up with the same values twice.
To fix, just create another map like this:
// map
NewsArrayList = new ArrayList<HashMap<String, String>>();
map1 = new HashMap<String, String>();
map1 .put("title", "New branch opened!");
map1 .put("date", "28.03.2014");
NewsArrayList.add((HashMap<String, String>) map1);
map2 = new HashMap<String, String>();
map2.put("title", "Second one!");
map2.put("date", "28.03.2014");
NewsArrayList.add((HashMap<String, String>) map2);

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);
}
});
}

No load data anymore except refresh action

I couldn't find a solution to my problem on the search engine, So i decided to ask here.
I have navigation tab with 3 fragments fragmentA, fragmentB, fragmentC. Each fragment load data from parsed data. i have opened fragment a and load data on listview, then i want to change to fragment b, and load the data too. but when i want to go back to fragmentA the fragment loads the data again.
I want my fragment are saving the loaded data before and when i refresh the fragment, the fragment load new data. An example app like a twitter or facebook. What i have to do? thanks for reading
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View Vi = inflater.inflate(R.layout.list_kuliah, container, false);
//Hashmap for ListView
contactList = new ArrayList<HashMap<String, String>>();
progress = (LinearLayout) Vi.findViewById(R.id.linlaHeaderProgress);
ListView lv = (ListView) Vi.findViewById(R.id.list1);
// Listview on item click listener
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String name = ((TextView) view.findViewById(R.id.title))
.getText().toString();
String email = ((TextView) view.findViewById(R.id.publisher))
.getText().toString();
String address = ((TextView) view.findViewById(R.id.description))
.getText().toString();
//String thumb_url = ((ImageView))
// Starting single contact activity
Intent in = new Intent(getActivity() ,SingleKuliahAct.class);
in.putExtra(TAG_NAME, name);
in.putExtra(TAG_EMAIL, email);
in.putExtra(TAG_ADDRESS, address);
startActivity(in);
getActivity().overridePendingTransition( R.anim.left1, R.anim.left2 );
}
});
new MyAsyncTask().execute();
return Vi;
}
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
progress.setVisibility(View.VISIBLE);
}
#Override
protected Void doInBackground(Void... args0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
//getting JSON string from URL
String jsonStr = sh.makeServiceCall(url_contacts, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
contacts = jsonObj.getJSONArray(TAG_CONTACTS);
// looping through All Contacts
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String email = c.getString(TAG_EMAIL);
String address = c.getString(TAG_ADDRESS);
// tmp hashmap for single contact
HashMap<String, String> contact = new HashMap<String, String>();
// adding each child node to HashMap key => value
contact.put(TAG_ID, id);
contact.put(TAG_NAME, name);
contact.put(TAG_EMAIL, email);
contact.put(TAG_ADDRESS, address);
// adding contact to contact list
contactList.add(contact);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
/**
* Updating parsed JSON data into ListView
* */
/*ListAdapter adapter = new SimpleAdapter(
getActivity(), contactList,
R.layout.list_kuliah_item, new String[] { TAG_NAME, TAG_EMAIL, TAG_ADDRESS}, new int[] { R.id.title,
R.id.publisher, R.id.description });
ListView mView = (ListView)
getView().findViewById(R.id.list1);
mView.setAdapter(adapter);*/
KuliahAdapter adapter;
ListView List = (ListView) getView().findViewById(R.id.list1);
adapter = new KuliahAdapter(getActivity(), contactList);
List.setAdapter(adapter);
progress.setVisibility(View.GONE);
}
above is my code on fragment kuliah (fragment A), and i have adapter for each fragment
public class KuliahAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
public KuliahAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.list_kuliah_item, null);
TextView title = (TextView)vi.findViewById(R.id.title); // title
TextView artist = (TextView)vi.findViewById(R.id.publisher); // artist name
TextView duration = (TextView)vi.findViewById(R.id.description); // duration
//TextView countcomment = (TextView)vi.findViewById(R.id.countcomment); // duration
//TextView countlikes = (TextView)vi.findViewById(R.id.countlikes); // duration
//TextView created = (TextView)vi.findViewById(R.id.created); // created
//ImageView thumb_image=(ImageView)vi.findViewById(R.id.image); // default image
HashMap<String, String> contactList = new HashMap<String, String>();
contactList = data.get(position);
// Setting all values in listview
title.setText(contactList.get(KuliahFragment.TAG_NAME));
artist.setText(contactList.get(KuliahFragment.TAG_EMAIL));
duration.setText(contactList.get(KuliahFragment.TAG_ADDRESS));
//countcomment.setText(courses.get(KuliahFragment.TAG_COUNTCOMMENT));
//countlikes.setText(courses.get(KuliahFragment.TAG_COUNTLIKES));
//created.setText(courses.get(KuliahFragment.TAG_CREATED));
//imageLoader.DisplayImage(courses.get(KuliahFragment.TAG_IMAGE), thumb_image);
return vi;
}
}

Android Show autocomplete values within a HashMap

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.

Android List view SectionIndexer - list view not displaying curent scroll letter

I am trying to use secionIndexer with fast scroll in list view.
I have implemented but
on scroll of list it should popup the current letter at which we have scrolled,
but its not showing that.
on debug mode I came to know that getSectipons() and getPositionForSection() are never called in my case ,
but in any other simple example that i tried from web it does make a call to those functions.
Pelase suggest me what to do
//##################
here is code of my adapter
//#######################
public class MyListAdapter extends ArrayAdapter<Object> implements SectionIndexer {
Activity context;
Object[] listData;
HashMap<String, Integer> alphaIndexer;
String[] sections;
public MyListAdapter(Activity context, Object[] objects) {
super(context, R.layout.new_invest_row, objects);
this.context = context;
listData = objects;
alphaIndexer = new HashMap<String, Integer>();
//changes here
ArrayList myArrayList = new ArrayList();
for (int ix=0; ix<objects.length; ix++) {
myArrayList.add(objects[ix]);
}
Collections.sort(myArrayList, new Comparator<HashMap<String, String>>(){
public int compare(HashMap<String, String> one, HashMap<String, String> two) {
return one.get("Name").compareToIgnoreCase(two.get("Name"));
}
});
listData = myArrayList.toArray();
//Arrays.sort(listData);
for (int i = listData.length - 1; i >= 0; i--) {
final HashMap<String, String> obj = (HashMap<String, String>)listData[i];
String element = obj.get("Name");
alphaIndexer.put(element.substring(0, 1).toUpperCase(), i);
}
Set<String> keys = alphaIndexer.keySet(); // set of letters
// Copy into a List for sorting
Iterator<String> it = keys.iterator();
ArrayList<String> keyList = new ArrayList<String>();
while (it.hasNext()) {
String key = it.next();
keyList.add(key);
}
Collections.sort(keyList);
// Convert to array
sections = new String[keyList.size()];
keyList.toArray(sections);
for(int c=0;c < sections.length;c++)Log.e("secction<"+c+">","+"+sections[c]);
Log.e("alphaIndexer","+"+alphaIndexer);
}
static class ViewHolder {
TextView txtName;
TextView txtOwner;
TextView txtStartDate;
TextView txtEndDate;
TextView txtStatus;
ImageView imgIcon;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.new_invest_row, null, true);
holder = new ViewHolder();
**holder.txtName = (TextView) rowView.findViewById(R.id.invest_row_name);**
//my custom code here
rowView.setTag(holder);
} else {
holder = (ViewHolder) rowView.getTag();
}
#SuppressWarnings("unchecked")
final HashMap<String, String> obj = (HashMap<String, String>)listData[position];
String str = obj.get("Name");
if(null == str){
str = "";
}
holder.txtName.setText(str);
//#################
//my custom code here
return rowView;
}
public int getPositionForSection(int section) {
String letter = sections[section];
Log.e("alphaIndexer.get(letter)","+"+alphaIndexer.get(letter));
return alphaIndexer.get(letter);
}
public int getSectionForPosition(int arg0) {
// TODO Auto-generated method stub
return 1;
}
public Object[] getSections() {
return sections;
}
}
//#######################
I assume that in adapter when I am passing the textViewId its not taking the currect textVewId as the sectionIndexer functions are never called.
In the Layout new_invest_row I am getting custom row which have an icon and few textViews.
I am sorting the list on the basis of name of the Object that I am displaying in each row.
i want indexer to work on the name of the object.
Please help me with exact solution

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.

Categories

Resources