How to get data from hashmap into adapter from json? - java

I try to get data from hashmap in to my CustomArrayAdapter, my hashmap had data is key and value pair is type and image according type and i want to get image when i click item gridview.
i had a trouble in my adapter.
Thank advance.
So this is my Adapter.
Adapter_subCategories.java
public class Adapter_subCategories extends BaseAdapter {
LayoutInflater inflater;
Context context;
ArrayList<HashMap<String,String>> wallpaperArrayList;
public Adapter_subCategories(LayoutInflater inflater, Context context, ArrayList<HashMap<String,String>> array) {
this.inflater = inflater;
this.context = context;
this.wallpaperArrayList = array;
}
public Adapter_subCategories(Item_categories_show item_categories_show, ArrayList<HashMap<String, String>> mapArrayList) {
}
public Adapter_subCategories(Item_categories_show item_categories_show, HashMap<String, ArrayList<Integer>> arrayListHashMap) {
}
#Override
public int getCount() {
return wallpaperArrayList.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater==null)
{
inflater = LayoutInflater.from(context);
}
if (convertView==null){
convertView = inflater.inflate(R.layout.list_images_subcategories,null);
}
ImageView imageView = convertView.findViewById(R.id.imageView_subcategories);
HashMap<String,String> maps = new HashMap<String, String>();
maps = wallpaperArrayList.get(position);
// this is my trouble
String type = maps.get("rootType");
String image = maps.get("url");
// maps = wallpaperArrayList.get(position);
imageView.setImageResource(Integer.parseInt(maps.get("url")));
return convertView;
}
}
My hashmap:
for (int j = 0; j<subArray.length() ; j++) {
JSONObject obj = subArray.getJSONObject(j);
JSONObject row = obj.getJSONObject("row");
String url = row.getString("url");
HashMap<String,String> map = new HashMap<String, String>();
map.put(rootType,url);
hashMapArrayList.add(map);
my json : http://www.vnsupa.com/dulieujson/data.json

I Think your problem is in getItem() and getItemId() both of methods. Change both of methods signature like
#Override
public Object getItem(int position) {
return wallpaperArrayList.get(position);//return your object
}
#Override
public long getItemId(int position) {
return position;//return position
}

Related

when apply something in position it will apply also on other position in custom ListView

a weird problem happened with me, when i apply something (like drop down, visibility, background) on a linear at position, it will also apply it on other position.
for understand me this a picture of my problem :
and this is my Adapter, whats wrong ?
public class Listview1Adapter extends BaseAdapter {
ArrayList<HashMap<String, Object>> data;
public Listview1Adapter(ArrayList<HashMap<String, Object>> arr) {
data = arr;
}
#Override
public int getCount() {
return data.size();
}
#Override
public HashMap<String, Object> getItem(int index) {
return data.get(index);
}
#Override
public long getItemId(int index) {
return index;
}
#Override
public View getView(final int _position, View _v, ViewGroup _container) {
LayoutInflater _inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = _v;
if (v == null) {
v = _inflater.inflate(R.layout.online_block_list, null);
}
final ImageView drop_more = v.findViewById(R.id.drop_more);
final LinearLayout linearMore = v.findViewById(R.id.linearMore);
final LinearLayout linearDro = v.findViewById(R.id.linearDro);
linearDro.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (linearMore.getVisibility() == View.GONE) {
final android.transition.ChangeBounds transition = new android.transition.ChangeBounds(); transition.setDuration(200L);
android.transition.TransitionManager.beginDelayedTransition(listview1, transition);
linearMore.setVisibility(View.VISIBLE);
ObjectAnimator.ofFloat(drop_more, View.ROTATION, 0f, 180f).setDuration(300).start();
} else {
final android.transition.ChangeBounds transition = new android.transition.ChangeBounds(); transition.setDuration(200L);
android.transition.TransitionManager.beginDelayedTransition(listview1, transition);
linearMore.setVisibility(View.GONE);
ObjectAnimator.ofFloat(drop_more, View.ROTATION, 180f, 0f).setDuration(300).start();
}
}
});
ListView reuse views returned by Listview1Adapter.getView() method. You get a situation when view for some item change itself - the state of View instance(object) was changed (expanded). Then ListView pass as an argument of Listview1Adapter.getView() method a same View's instance for other item - this view already expanded.
You should save state of view for each item of ListView (in your case for data ArrayList) and restore it for each item in getView() method. It might look like:
public class Listview1Adapter extends BaseAdapter {
final ArrayList<ItemState> data;
public Listview1Adapter(ArrayList<ItemState> arr) {
data = arr;
}
private static class ItemState {
final HashMap<String, Object> data;
boolean isExpanded;
public ItemState(final HashMap<String, Object> data, final boolean isExpanded) {
this.data = data;
this.isExpanded = isExpanded;
}
}
#Override
public int getCount() {
return data.size();
}
#Override
public HashMap<String, Object> getItem(int index) {
return data.get(index).data;
}
#Override
public long getItemId(int index) {
return index;
}
#Override
public View getView(final int _position, View _v, ViewGroup _container) {
LayoutInflater _inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = _v;
if (v == null) {
v = _inflater.inflate(R.layout.online_block_list, null);
}
final ImageView drop_more = v.findViewById(R.id.drop_more);
final LinearLayout linearMore = v.findViewById(R.id.linearMore);
final LinearLayout linearDro = v.findViewById(R.id.linearDro);
if (data.get(_position).isExpanded) { // check current view state for item
linearMore.setVisibility(View.VISIBLE); // restore view state for current item
} else {
linearMore.setVisibility(View.GONE); // restore view state for current item
}
linearDro.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (linearMore.getVisibility() == View.GONE) {
final android.transition.ChangeBounds transition = new android.transition.ChangeBounds();
transition.setDuration(200L);
android.transition.TransitionManager.beginDelayedTransition(listview1, transition);
linearMore.setVisibility(View.VISIBLE);
data.get(_position).isExpanded = true; // save view state for item
ObjectAnimator.ofFloat(drop_more, View.ROTATION, 0f, 180f).setDuration(300).start();
} else {
final android.transition.ChangeBounds transition = new android.transition.ChangeBounds();
transition.setDuration(200L);
android.transition.TransitionManager.beginDelayedTransition(listview1, transition);
linearMore.setVisibility(View.GONE);
data.get(_position).isExpanded = false; // save view state for item
ObjectAnimator.ofFloat(drop_more, View.ROTATION, 180f, 0f).setDuration(300).start();
}
}
});
return v;
}
}
You have many options to convert your items to ItemState objects, I show a few bellow:
final ArrayList<HashMap<String, Object>> listMapTest = new ArrayList<>(); // input data
// 1th
final ArrayList<ItemState> viewListMapTest_1 = listMapTest.stream().map(item -> new ItemState(item, false)).collect(Collectors.toCollection(ArrayList::new));
// 2th:
final ArrayList<ItemState> viewListMapTest_2 = new ArrayList<ItemState>() {{
for (HashMap<String, Object> item : listMapTest) add(new ItemState(item, false));
}};
// 3th:
final ArrayList<ItemState> viewListMapTest_3 = new ArrayList<>(listMapTest.size());
for (int i = 0; i < viewListMapTest_3.size(); i++) {
viewListMapTest_3.set(i, new ItemState(listMapTest.get(i), false));
}

List View search is not working on item click. Returns original item position

I have a problem in searchview.
For example, if my original list view is:- Aa Ab Ac Ad.
But when i search in search bar a query for example b, it gives:- Ab.
But when i clicked on item, it gives the value of Position:- Aa.
Here is my List view Activity:-
HashMap<String, String> userMap = Login.userMap;
final ArrayList<String> userList = new ArrayList(userMap.keySet());
listView = (ListView) findViewById(R.id.listView);
adapter = new ListAdapter(this, userMap);
listView.setAdapter(adapter);
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
user = userList.get(position);
new GetDetails().execute(new Void[0]);
}
});
searchView.setMenuItem(item);
searchView.setOnQueryTextListener(new MaterialSearchView.OnQueryTextListener() {
public boolean onQueryTextSubmit(String query) {
return false;
}
public boolean onQueryTextChange(String newText) {
Log.i("newText", newText);
if (newText.isEmpty()) {
adapter.filter("");
listView.clearTextFilter();
} else {
adapter.filter(newText);
}
return true;
}
});
Here is my Adapter:-
class ListAdapter extends BaseAdapter {
private static LayoutInflater inflater = null;
private Activity activity;
private HashMap<String, String> data;
private List<String> username = new ArrayList();
private ArrayList<HashMap<String, Object>> list;
public ListAdapter(Activity a, HashMap<String, String> d) {
this.activity = a;
this.data = d;
inflater = (LayoutInflater) this.activity.getSystemService("layout_inflater");
}
public int getCount() {
return username.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return (long) position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null) {
vi = inflater.inflate(R.layout.main_list_adapter, null);
}
ImageView image = (CircularImageView) vi.findViewById(R.id.img);
((TextView) vi.findViewById(R.id.txt)).setText(username.get(position));
Picasso.with(this.activity.getApplicationContext()).load(data.get(this.username.get(position))).placeholder(R.mipmap.empty_photo).resize(70, 70).into(image);
return vi;
}
public void filter(String charText) {
username.clear();
if (charText.length() == 0) {
username.addAll(data.keySet());
} else {
for (String s : data.keySet()) {
if (s.contains(charText)) {
username.add(s);
}
}
}
notifyDataSetChanged();
}
public void refresh(HashMap<String, String> newData) {
data = newData;
username.clear();
username.addAll(data.keySet());
notifyDataSetChanged();
}}
Help will be really appreciated guys. I am looking around, but i am not able to find it.
override getitem() in adapter to
public Object getItem(int position) {
return username.get(position);
}
and onclick use adapter.getItem(position);
this will work;
Position returned on click corresponds to the position of item in your data list. So as during filtering you are changing your list username so position returned will be of the elements in the list.

LazyList 's listview can not refresh with new arraylist

I m trying to use searchView with LazyList. In my lazyAdapter I m updating my arraylist , this works smoothly but my listview doesn't update with arrayList. This is my filer method. I suppose notifyDataSetChanged does not work.Please help how can I refresh my listview?
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
//list.clear();
list = new ArrayList<HashMap<String, String>>();
if (charText.length() == 0) {
list.addAll(arraylist);
}
else
{
for (HashMap<String, String> map : arraylist)
{
if (map.get("radio").toString().toLowerCase(Locale.getDefault()).contains(charText))
{
list.add(map);
}
}
}
notifyDataSetChanged();
}
The variable list holds a different object after the third line. You are changing this new ArrayList but the adapter still remembers the old one. Instead of
list = new ArrayList<HashMap<String, String>>();
write
list.clear();
You then work with the same object as before.
LazyList 's listview can not refresh with new arraylist
Because you are not adding new list in current Adapter of Listview before calling notifyDataSetChanged() :
Add list to adapter using addAll method:
listviewAdapter.addAll(list);
//notify data-source change to adapter
notifyDataSetChanged();
if addAll method not available then create a method in Adapter class and pass list as parameter then call add method:
public void addAll(ArrayList<HashMap<String, String>> data) {
for(String item: data) {
add(item);
}
notifyDataSetChanged();
}
public class MovieListAdapter extends BaseAdapter {
private Context context;
ArrayList<HashMap<String, String>> movielist;
private ArrayList<HashMap<String, String>> listAdapter;
public MovieListAdapter(Context context, ArrayList<HashMap<String, String>> movielist) {
this.context = context;
this.movielist = movielist;
this.listAdapter = new ArrayList<HashMap<String, String>>();
this.listAdapter.addAll(movielist);
}
#Override
public int getCount() {
return movielist.size();
}
#Override
public Object getItem(int position) {
return movielist.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View griView = inflater.inflate(R.layout.movie_listitem, null);
TextView textview = (TextView) griView.findViewById(R.id.catname);
textview.setText(movielist.get(position).get("name"));
textview.setSelected(true);
ImageView imageView = (ImageView) griView.findViewById(R.id.catimage);
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
int width = metrics.widthPixels / 3;
int height = metrics.widthPixels / 3;
// System.out.println(movielist.get(position).getMoviepicture());
if (movielist.get(position).get("image").equals("")) {
imageView.setImageResource(R.drawable.blankart);
} else {
Picasso.with(context)
.load(movielist.get(position).get("image"))
.resize(width, height).placeholder(R.drawable.blankart)
.noFade().into(imageView);
}
return griView;
}
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
movielist.clear();
if (charText.length() == 0) {
movielist.addAll(listAdapter);
} else {
for (HashMap<String, String> si : listAdapter) {
if (si.get("name").toLowerCase(Locale.getDefault())
.contains(charText)) {
movielist.add(si);
}
}
}
notifyDataSetChanged();
}
}
make you adapter like this

Custom Adapter with Expandable Listview

Can any one help me with this...I'm trying to implement expandable listview dynamically and i used one of the tutorials (Androidhive) to get familiar to it. My problem is that i am getting my data from parse.com and i want to load it dynamically into the expandable listview. First i am getting data from parse into my object classified by each type and then i suppose to convert that to the expandable listview. What i am stuck in is that i don't know how to pass to the adapter more than 1 object to the child (i have 3 textviews on each child). From the below example i got the data of main road from only to be viewed in the child but i still need to get 2 additional values which i don't know how to achieve.
Hereunder my code for the asynctask :
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Create a progressdialog
mProgressDialog = new ProgressDialog(MainActivity.this);
// Set progressdialog title
// mProgressDialog.setTitle("Loading...");
// Set progressdialog message
mProgressDialog.setMessage("wait please ...");
mProgressDialog.setIndeterminate(false);
// Show progressdialog
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// Create the array
listviewPostsGet = new ArrayList<listviewPostsGet>();
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"MainRoadsList");
try {
ob = query.find();
for (ParseObject country : ob) {
listviewPostsGet map = new listviewPostsGet();
map.setmainroad(((String) country.get("mainroad")));
map.setmainroadfrom(((String) country.get("from")));
map.setmainroadto((String) country.get("to"));
map.setcategory(((String) country.get("mainroad")));
listviewPostsGet.add(map);
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
String check = "";
for (int i = 0; i < listviewPostsGet.size(); i++)
{
String XX = listviewPostsGet.get(i).getcategory()
.toString();
if (!check.contentEquals(XX.toString())) {
listDataHeader.add(XX);
check = XX;
List<String> TTT = new ArrayList<String>();
for (int j = 0; j < listviewPostsGet.size(); j++) {
String YY = listviewPostsGet.get(j).getcategory().toString();
if (YY.contentEquals(XX.toString()))
{
TTT.add(listviewPostsGet.get(j).getmainroadfrom().toString()+" "+listviewPostsGet.get(j).getmainroadto().toString());
listDataChild.put(XX, TTT);
}
}
}
}
}
}
catch (ParseException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
listAdapter = new ExpandableListAdapter1(MainActivity.this,
listDataHeader, listDataChild);
// setting list adapter
expListView.setAdapter(listAdapter);
mProgressDialog.dismiss();
}
}
Also here is the adapter :
public class ExpandableListAdapter1 extends BaseExpandableListAdapter {
private Context _context;
private List<String> _listDataHeader; // header titles
// child data in format of header title, child title
private HashMap<String, List<String>> _listDataChild;
public ExpandableListAdapter1(Context context, List<String> listDataHeader,
HashMap<String, List<String>> listDataChild ) {
this._context = context;
this._listDataHeader = listDataHeader;
this._listDataChild = listDataChild;
}
public Object getChild(int groupPosition, int childPosititon) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition).toString())
.get(childPosititon);
}
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final String childText = (String) getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.mainlayout, null);
}
TextView from = (TextView) convertView
.findViewById(R.id.fromroad);
TextView to = (TextView) convertView
.findViewById(R.id.toroad);
from.setText(childText);
return convertView;
}
public int getChildrenCount(int groupPosition) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.size();
}
public Object getGroup(int groupPosition) {
return this._listDataHeader.get(groupPosition);
}
public int getGroupCount() {
return this._listDataHeader.size();
}
public long getGroupId(int groupPosition) {
return groupPosition;
}
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.list_group, null);
}
TextView lblListHeader = (TextView) convertView
.findViewById(R.id.lblListHeader);
lblListHeader.setTypeface(null, Typeface.BOLD);
lblListHeader.setText(headerTitle);
return convertView;
}
public boolean hasStableIds() {
return false;
}
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
Edit :
to be clear , My problem is that I want to assign 3 values from my listviewPostsGet to the expandable listview child and what i can actually achieve is to pass only 1 value which is "Main road from" to the TTT array list then assign it to the corresponding textview on the adapter.

ListView doesn't show refreshed content

I have a custom adapter which extends from BaseAdapter..
Custom adapter code :
public class SearchListViewAdapter extends BaseAdapter {
private LayoutInflater layoutInflater;
private JsonArray searchResults;
public SearchListViewAdapter(Context context, JsonArray searchResults) {
this.searchResults = searchResults;
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return searchResults.count();
}
#Override
public Object getItem(int position) {
return searchResults.get(position);
}
/*public ListAdapter updateResults(JsonArray results) {
searchResults = results;
notifyDataSetChanged();
return null;
}*/
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
JsonObject searchResult = (JsonObject)getItem (position);
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.custom_search_result, null);
holder = new ViewHolder();
holder.txtFullName = (TextView) convertView.findViewById(R.id.FullName);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtFullName.setText(searchResult.getString ("FirstName") + searchResult.getString ("LastName"));
return convertView;
}
static class ViewHolder {
TextView txtFullName;
}
}
Activity code :
// After displaying the list in an onPostExecute Method of an AsyncTask class
// I call another async task : BarcodeAction by giving the param : records
new BarcodeAction(records).execute("");
private class BarcodeAction extends AsyncTask<String, Void, JsonArray> {
private JsonArray records;
public BarcodeAction(JsonArray result)
{
this.records = result;
}
#Override
protected JsonArray doInBackground(String... params) {
// Processing... if it's success the onPostExecute method receive : records
if (resultType.equals("success"))
return records;
return null;
}
#Override
protected void onPostExecute(final JsonArray records) {
final ListView lv1 = (ListView) findViewById(R.id.ListViewSearchResults);
// EDIT : notifyDataSetChange doesn't work
SearchListViewAdapter svla1 = new SearchListViewAdapter(SearchActivity.this, records);
lv1.setAdapter(svla1);
svla1.notifyDataSetChanged();
lv1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
Object o = lv1.getItemAtPosition(position);
JsonObject response = (JsonObject)o;
SearchActivity.VISITOR_BARCODE = response.getString("Barcode");
new BarcodeAction(records).execute("");
}
});
}
}
But my list is not getting refreshed..
Do you have any idea about this ? Thnak you.
getItemId() should return unique value for each entry in the list. Try returning position only.
I think the main cause is missing calling notifyDataSetChanged() method.
In fact, your "activity code" is not exactly the activity but a asnyctask that fetch the data. A more common way to use adaper is having a Adaper in your activty along with ListView. In your fetching-data-method(asynctask or loader), call the adaper's change underlying data interface to change the data, and call the adaper's notifyDataSetChanged() method.
A bit psudeo-code may looks like:
Adaper:
public class SearchListViewAdapter extends BaseAdapter {
private JsonArray searchResults;
......
public setDataSet(JsonArray newData) {
searchREsults = newData;
}
......
}
Activity:
public class MyActivity extends Activity {
ListView mResultListView;
SearchListViewAdaper mResultViewAdaper;
#override
OnCreate(...) {
......
//init mResultListView
mResultListView = (ListView) findViewById(R.id.xxxx);
mResultViewAdaper = new SearchListViewAdapter();
mResultListView.setAdapter(mResultViewAdaper);
......
}
......
}
AsyncTask:
public fetchDataTask extends AsyncTask {
......
onPostExecute(JsonArray records) {
mResultViewAdaper.setDataSet(records);
// IMPORTANT: notify data change
mResultViewAdaper.notifyDataSetChanged();
}

Categories