I have implemented a ListView. From ListView I am adding a products to cart. My problem is if i add a first product i am changing a button name Addtocart to Added if i scroll ListView 4th position product button name is changing to Added.
How can I resolve this ?
Here my code:
holderForGrid.AddtoCart.setTag(position);
holderForGrid.AddtoCart.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
holderForGrid.AddtoCart.setText("Added");
}
});
Adapter Class:
class ListAdapter extends BaseAdapter {
public Context context;
public ListAdapter(Context a,List<BusinessCatalogVariables> listDataHeader) {
this.listDataHeader = listDataHeader;
context = a;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return catalogList.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
#Override
public View getView(final int position, View convertView, ViewGroup arg2) {
final ViewHolderGrid holderForGrid;
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.catalog_list_item, null);
holderForGrid = new ViewHolderGrid(convertView);
convertView.setTag(holderForGrid);
} else {
holderForGrid = (ViewHolderGrid) convertView.getTag();
}
finalCatalogVariables Catalog = catalogList.get(position);
holderForGrid.AddtoCart.setClickable(false);
holderForGrid.AddtoCart.setTag(position);
holderForGrid.AddtoCart.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
int position1=(Integer)arg0.getTag();
AddedProduct = (String) holderForGrid.CatalogHeader.getText();
holderForGrid.AddtoCart.setText("Added");
}
});
return convertView;
}
private class ViewHolderGrid {
Button AddtoCart = null;
ViewHolderGrid(View convertView) {
AddtoCart = (Button) convertView.findViewById(R.id.btn_AddtoCart);
}
}
}
create boolean variable added in finalCatalogVariables class.
and create getter,setter method for this variable.
like,
class finalCatalogVariables{
// other variable and methods
boolean added;
public boolean isAdded()
{
return this.added;
}
public void setAdded(boolean added){
this.added = added;
}
}
then in getView method on click of holderForGrid.AddtoCart
public View getView(final int position, View convertView, ViewGroup arg2) {
final ViewHolderGrid holderForGrid;
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.catalog_list_item, null);
holderForGrid = new ViewHolderGrid(convertView);
convertView.setTag(holderForGrid);
} else {
holderForGrid = (ViewHolderGrid) convertView.getTag();
}
finalCatalogVariables catalog = catalogList.get(position);
if(catalog.isAdded()){
holderForGrid.AddtoCart.setText("Added");
}else{
holderForGrid.AddtoCart.setText("Add to cart");
}
holderForGrid.AddtoCart.setClickable(false);
holderForGrid.AddtoCart.setTag(position);
holderForGrid.AddtoCart.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
catalog.setAdded(true);
int position1=(Integer)arg0.getTag();
AddedProduct = (String) holderForGrid.CatalogHeader.getText();
// holderForGrid.AddtoCart.setText("Added");
}
});
return convertView;
}
Override below mentioned two methods in your adapter class.
Override
public int getViewTypeCount() {
return getCount();
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.rowlayout, null);
if (imageLoader == null)
imageLoader = Session.getInstance().getImageLoader();
//write your declaration code
List m = Yourarray.get(position);
// thumbnail image
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//your code
int position1=(Integer)arg0.getTag();
AddedProduct = (String) holderForGrid.CatalogHeader.getText();
holderForGrid.AddtoCart.setText("Added");
}
});
return convertView;
}
I think the problem is that if you change the button on a view and then scroll far enough for the view to disappear, Android will assign the view position to another item in the listView.
You need to maintain somehow the status "added" or not of each product and let your adapter decide what label to display based on that.
Related
So I followed an online tutorial to have a sort of gallery app. The pictures are shown inside a GridView but I needed to change it into a recyclerview. When I do that though I get that error and my adapter doesn't seem to work with the recyclerview. Here is my adapter code:
class AlbumAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap< String, String >> data;
public AlbumAdapter(Activity a, ArrayList < HashMap < String, String >> d) {
activity = a;
data = d;
}
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) {
AlbumViewHolder holder = null;
if (convertView == null) {
holder = new AlbumViewHolder();
convertView = LayoutInflater.from(activity).inflate(
R.layout.album_row, parent, false);
holder.galleryImage = (ImageView) convertView.findViewById(R.id.galleryImage);
holder.gallery_count = (TextView) convertView.findViewById(R.id.gallery_count);
holder.gallery_title = (TextView) convertView.findViewById(R.id.gallery_title);
convertView.setTag(holder);
} else {
holder = (AlbumViewHolder) convertView.getTag();
}
holder.galleryImage.setId(position);
holder.gallery_count.setId(position);
holder.gallery_title.setId(position);
HashMap < String, String > song = new HashMap < String, String > ();
song = data.get(position);
try {
holder.gallery_title.setText(song.get(Function.KEY_ALBUM));
holder.gallery_count.setText(song.get(Function.KEY_COUNT));
Glide.with(activity)
.load(new File(song.get(Function.KEY_PATH))) // Uri of the picture
.into(holder.galleryImage);
} catch (Exception e) {}
return convertView;
}
}
class AlbumViewHolder {
ImageView galleryImage;
TextView gallery_count, gallery_title;
}
And this is some of the code from the activity in which I set my adapter:
#Override
protected void onPostExecute(String xml) {
AlbumAdapter adapter = new AlbumAdapter(ProfileActivity.this, albumList);
galleryGridView.setAdapter(adapter);
galleryGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
final int position, long id) {
Intent intent = new Intent(ProfileActivity.this, AlbumActivity.class);
intent.putExtra("name", albumList.get(+position).get(Function.KEY_ALBUM));
startActivity(intent);
}
});
}
This is the error I'm currently getting:
Error message
I basically want to fix the adapter so that it works inside a recyclerview.
You have to create RecyclerView.Adapter to work with RecyclerView. It's bit different that BaseAdapter. Let me give you example of how to implement this.
public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder> {
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.album_row, viewGroup, false);
return new AlbumAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
holder.galleryImage.setId(position);
holder.gallery_count.setId(position);
holder.gallery_title.setId(position);
}
#Override
public int getItemCount() {
return data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView galleryImage;
TextView gallery_count, gallery_title;
public ViewHolder(View v) {
galleryImage = v.findViewById(R.id.galleryImage);
gallery_count =v.findViewById(R.id.gallery_count);
gallery_title = v.findViewById(R.id.gallery_title);
}
}
}
I'm making NLevel expandable list using listview. I've added checkbox only last level data in list view. I have stuck in below scenario.
If I check checkbox then when I expand listview means checkbox gets automatically unchecked.I don't want it to be like that. If I checked checkbox it should stay checked until I uncheck manually.
Please anyone help me!! It's been two days I stuck here.
Here goes my code:
MainActivity.java
public class MainActivity extends Activity {
List<NLevelItem> list;
ListView listView;
Context context;
Button checkButton;
ArrayList<String>tempList;
CheckBox selected = null; //Make only one selection at a time
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView1);
list = new ArrayList<NLevelItem>();
context = this;
checkButton = (Button)findViewById(R.id.buttons);
tempList = new ArrayList<String>();
//here we create 5 grandparent (top level) NLevelItems
//then foreach grandparent create a random number of parent (second level) NLevelItems
//then foreach parent create a random number of children (third level) NLevelItems
//we pass in an anonymous instance of NLevelView to the NLevelItem, this NLevelView is
//what supplies the NLevelAdapter with a View for this NLevelItem
Random rng = new Random();
final LayoutInflater inflater = LayoutInflater.from(this);
for (int i = 0; i < 5; i++) {
final NLevelItem grandParent = new NLevelItem(new SomeObject("GrandParent "+i),null, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.list_item, null);
TextView tv = (TextView) view.findViewById(R.id.textView);
//tv.setBackgroundColor(Color.GREEN);
String name = (String) ((SomeObject) item.getWrappedObject()).getName();
tv.setText(name);
return view;
}
});
list.add(grandParent);
int numChildren = rng.nextInt(4) + 1;
for (int j = 0; j < numChildren; j++) {
NLevelItem parent = new NLevelItem(new SomeObject("Parent "+j),grandParent, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.list_item, null);
TextView tv = (TextView) view.findViewById(R.id.textView);
//tv.setBackgroundColor(Color.YELLOW);
String name = (String) ((SomeObject) item.getWrappedObject()).getName();
tv.setText(name);
return view;
}
});
list.add(parent);
int children = rng.nextInt(3)+1;
for(int x=0; x<children;x++){
final NLevelItem childs = new NLevelItem(new SomeObject("Parent1 "+x),parent, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.list_item, null);
TextView tv = (TextView) view.findViewById(R.id.textView);
//tv.setBackgroundColor(Color.BLUE);
String name = (String) ((SomeObject) item.getWrappedObject()).getName();
tv.setText(name);
return view;
}
});
list.add(childs);
int grandChildren = rng.nextInt(5)+1;
for( int k = 0; k < grandChildren; k++) {
NLevelItem child = new NLevelItem(new SomeObject("child "+k),childs, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.check_list, null);
TextView tv = (TextView) view.findViewById(R.id.checktextView);
final String name = (String) ((SomeObject) item.getWrappedObject()).getName();
final CheckBox checkBox = (CheckBox)view.findViewById(R.id.check);
checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(selected != null){ //Edit
selected.setChecked(false);
}
selected = checkBox; //Edit
if(checkBox.isChecked()){
tempList.add((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
else {
tempList.remove((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
}
});
//tv.setBackgroundColor(Color.GRAY);
tv.setText(name);
return view;
}
});
list.add(child);
}
}
}
}
NLevelAdapter adapter = new NLevelAdapter(list);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
((NLevelAdapter)listView.getAdapter()).toggle(arg2);
((NLevelAdapter)listView.getAdapter()).getFilter().filter();
}
});
checkButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i=0;i<tempList.size();i++){
Toast.makeText(context,tempList.get(i),Toast.LENGTH_LONG).show();
}
}
});
}
class SomeObject {
public String name;
public SomeObject(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
}
NLevelAdapter.java
public class NLevelAdapter extends BaseAdapter {
List<NLevelItem> list;
List<NLevelListItem> filtered;
public void setFiltered(ArrayList<NLevelListItem> filtered) {
this.filtered = filtered;
}
public NLevelAdapter(List<NLevelItem> list) {
this.list = list;
this.filtered = filterItems();
}
#Override
public int getCount() {
return filtered.size();
}
#Override
public NLevelListItem getItem(int arg0) {
return filtered.get(arg0);
}
#Override
public long getItemId(int arg0) {
return 0;
}
#Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
return getItem(arg0).getView();
}
public NLevelFilter getFilter() {
return new NLevelFilter();
}
class NLevelFilter {
public void filter() {
new AsyncFilter().execute();
}
class AsyncFilter extends AsyncTask<Void, Void, ArrayList<NLevelListItem> > {
#Override
protected ArrayList<NLevelListItem> doInBackground(Void...arg0) {
return (ArrayList<NLevelListItem>)filterItems();
}
#Override
protected void onPostExecute(ArrayList<NLevelListItem> result) {
setFiltered(result);
NLevelAdapter.this.notifyDataSetChanged();
}
}
}
public List<NLevelListItem> filterItems() {
List<NLevelListItem> tempfiltered = new ArrayList<NLevelListItem>();
OUTER: for (NLevelListItem item : list) {
//add expanded items and top level items
//if parent is null then its a top level item
if(item.getParent() == null) {
tempfiltered.add(item);
} else {
//go through each ancestor to make sure they are all expanded
NLevelListItem parent = item;
while ((parent = parent.getParent())!= null) {
if (!parent.isExpanded()) {
//one parent was not expanded
//skip the rest and continue the OUTER for loop
continue OUTER;
}
}
tempfiltered.add(item);
}
}
return tempfiltered;
}
public void toggle(int arg2) {
filtered.get(arg2).toggle();
}
}
Thanks in advance!!
i think you need to store the checkbox state in a boolean (is checked), and reflect that on the view, when getView() is called.
1- Add boolean checked to NLevelItem :
private boolean checked = false;
//add setter: setChecked(boolean)
//add getter isChecked()
2- Use that boolean in getView() (last one where checkbox is added)
#Override
public View getView(final NLevelItem item) {
// .......
final CheckBox checkBox = (CheckBox)view.findViewById(R.id.check);
checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//store checkbox state, note that NLevelItem item might need to be defined with 'final'
item.setChecked(checkBox.isChecked());
if(checkBox.isChecked()){
tempList.add((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
else {
tempList.remove((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
}//onClick()
}//setOnClickListener()
//update checkbox state from the corresponding NLevelItem
checkBox.setChecked(item.isChecked());
//.......
}//getView()
-EDIT:
to select 1 item, you need to iterate all items, set checked = false, but 1
i am not sure if you have to do it on:
List<NLevelItem> list;
or
List<NLevelListItem> filtered;
in the adapter class
private void selectOnly(int position){
for(int a=0;a<list.size();a++){
if(a == position){
list.get(a).setChecked(true);
continue;
}
list.get(a).setChecked(false);
}//for loop
notifyDataSetChanged(); // to update views (checkbox state)
}
Usage: selectOnly(15);
Use ViewHolder class to set and get Tag like this:
public class ListAdapter extends BaseAdapter {
private Context con;
private List<String> dataLt;
private static LayoutInflater inflater = null;
public ListAdapter(Context context, List<String> dataList){
con = context;
dataLt = dataList;
inflater = (LayoutInflater)con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return dataLt.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
ViewHolder holder;
if(convertView==null){
/****** Inflate tabitem.xml file for each row ( Defined below ) *******/
vi = inflater.inflate(R.layout.list_item_search, null);
/****** View Holder Object to contain tabitem.xml file elements ******/
holder = new ViewHolder();
holder.textView = (TextView) vi.findViewById(R.id.textView);
/************ Set holder with LayoutInflater ************/
vi.setTag( holder );
}
else
holder=(ViewHolder)vi.getTag();
return vi;
}
public static class ViewHolder{
TextView textView;
}
}
Hope this may help.
I've loaded some pictures into a ListView using an adapter. When a user clicks on any row of the list I'm showing a checkmark at the end:
public class LazyImageLoadAdapter extends BaseAdapter implements OnClickListener{
private Activity activity;
List<String> names,facebookbid;
String sent;
private LayoutInflater inflater=null;
public ImageLoader imageLoader;
public LazyImageLoadAdapter(Activity a, List<String> n,List<String> fid,String s) {
activity = a;
names=n;
facebookbid=fid;
sent=s;
inflater = (LayoutInflater)activity.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new ImageLoader(activity.getApplicationContext(),"p");
}
#Override
public int getViewTypeCount() {
if (getCount() != 0)
return getCount();
return 1;
}
public int getCount() {
return facebookbid.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
/********* Create a holder Class to contain inflated xml file elements *********/
public class ViewHolder{
public TextView text;
public ImageView image;
public ImageView checkmark;
public RelativeLayout friendsrow;
}
public View getView(final int position, View convertView, ViewGroup parent) {
convertView=null;
final ViewHolder holder;
if(convertView==null){
/****** Inflate tabitem.xml file for each row ( Defined below ) *******/
convertView = inflater.inflate(R.layout.planners_friends_listrow, null);
/****** View Holder Object to contain tabitem.xml file elements ******/
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.planner_friend_name);
(ImageView)convertView.findViewById(R.id.planner_friend_image);
holder.checkmark=(ImageView)convertView.findViewById(R.id.checkmark);
holder.friendsrow=(RelativeLayout)convertView.findViewById(R.id.friendsrow);
/************ Set holder with LayoutInflater ************/
convertView.setTag( holder );
}
else
holder=(ViewHolder)convertView.getTag();
holder.text.setText(names.get(position));
Typeface face = Typeface.createFromAsset(convertView.getContext().getAssets(),
"fonts/MAXWELL REGULAR.ttf");
holder.text.setTypeface(face);
ImageView image = holder.image;
String link;
if(sent.equals("planners"))
{link=facebookbid.get(position);
}
else
{
link="https://graph.facebook.com/"+facebookbid.get(position)+"/picture?type=large";
}
//DisplayImage function from ImageLoader Class
imageLoader.DisplayImage(link, image);
holder.friendsrow.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
boolean a=isNetworkConnected();
if(a==true)
{
if(sender.equals("settings"))
{
}
else if(sender.equals("savethedate"))
{
if(sid.contains(facebookbid.get(position)))
{
if(sid.contains("_"))
{
sid=sid.replace("_"+facebookbid.get(position), "");
}
else
{
sid=sid.replace(facebookbid.get(position), "");
}
nb_selections--;
selectedids.remove(selectedids.size()-1);
sidetitle.setText("Invite ("+String.valueOf(nb_selections)+") friends");
holder.checkmark.setVisibility(View.GONE);
}
else
{
if(sid.isEmpty())
{
sid=sid+facebookbid.get(position);
}
else
{
sid=sid+"_"+facebookbid.get(position);
}
nb_selections++;
selectedids.add(facebookbid.get(position));
sidetitle.setText("Invite ("+String.valueOf(nb_selections)+") friends");
holder.checkmark.setVisibility(View.VISIBLE);
}
}
else
{
String friendname=names.get(position);
String friendid=facebookbid.get(position);
String friendgender=gender.get(position);
Intent resultIntent = new Intent(Friends.this,Newmarriage.class);
resultIntent.putExtra("facebookbid", friendid);
resultIntent.putExtra("name", friendname);
resultIntent.putExtra("gender", friendgender);
if(sender.equals("planner"))
{
resultIntent.putExtra("plannerid",friendid);
resultIntent.putExtra("imageurl","https://graph.facebook.com/"+friendid+"/picture?type=large");
setResult(Activity.RESULT_OK, resultIntent);
finish();
}
else
{
resultIntent.putExtra("plannerid","");
resultIntent.putExtra("imageurl","");
setResult(Activity.RESULT_OK, resultIntent);
finish();
}
}
}
else
{
Toast.makeText(getApplicationContext(),"No internet connection",Toast.LENGTH_LONG).show();
}
}
});
/******** Set Item Click Listner for LayoutInflater for each row ***********/
// vi.setOnClickListener(new OnItemClickListener(position));
return convertView;
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
}
The problem is: When the ListView is scrolled, the checkmark icon simply disappears. What am I doing wrong?
Looking at your code you set the Visibility of the checkmark when the user clicks on one of the items which then shows / hides the item. Now when the user scrolls the items are recycled and you dont have any code to check if the item has been checked or not.
So in short you need something that basically says
if (checked) {
//set visibility of the checkmark to visible
} else {
//set visibility of the checkmark to gone
}
First you need to change getView method as don't reinitialize convertView as null remove below line from getView
public class LazyImageLoadAdapter extends BaseAdapter implements OnClickListener {
private Activity activity;
List<String> names, facebookbid;
String sent;
public ImageLoader imageLoader;
private int size = 0;
private HashMap<String, Boolean> mapClickStatus;
public LazyImageLoadAdapter(Activity a, List<String> n, List<String> fid, String s) {
activity = a;
names = n;
facebookbid = fid;
sent = s;
mapClickStatus = new HashMap<String, Boolean>();
if (facebookbid != null)
size = facebookbid.size();
// Give total size of the list item to getCount method
imageLoader = new ImageLoader(activity, "p");
}
#Override
public int getCount() {
return size;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
/*********
* Create a holder Class to contain inflated xml file elements
*********/
public class ViewHolder {
public TextView text;
public ImageView image;
public ImageView checkmark;
public RelativeLayout friendsrow;
}
public View getView(final int position, View convertView, ViewGroup parent) {
// convertView=null;
//It should not be null every time
final ViewHolder holder;
if (convertView == null) {
/****** Inflate tabitem.xml file for each row ( Defined below ) *******/
convertView = LayoutInflater.from(activity).inflate(R.layout.planners_friends_listrow, parent, false);
/****** View Holder Object to contain tabitem.xml file elements ******/
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.planner_friend_name);
(ImageView) convertView.findViewById(R.id.planner_friend_image);
holder.checkmark = (ImageView) convertView.findViewById(R.id.checkmark);
holder.friendsrow = (RelativeLayout) convertView.findViewById(R.id.friendsrow);
/************ Set holder with LayoutInflater ************/
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
holder.text.setText(names.get(position));
Typeface face = Typeface.createFromAsset(convertView.getContext().getAssets(),
"fonts/MAXWELL REGULAR.ttf");
holder.text.setTypeface(face);
ImageView image = holder.image;
String link;
if (sent.equals("planners")) {
link = facebookbid.get(position);
} else {
link = "https://graph.facebook.com/" + facebookbid.get(position) + "/picture?type=large";
}
//DisplayImage function from ImageLoader Class
imageLoader.DisplayImage(link, image);
// set the visibility of CheckMark ImageView based on the click status.
if (mapClickStatus.get(facebookbid.get(position)))
holder.checkmark.setVisibility(View.VISIBLE);
else
holder.checkmark.setVisibility(View.GONE);
holder.friendsrow.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
boolean a = isNetworkConnected();
/// I dont know about the unique ID field in this so i took facebookbid.get(position) as a key
// To set click status of row item in hashmap.
mapClickStatus.put(facebookbid.get(position),
mapClickStatus.containsKey(facebookbid.get(position)) ? false : true);
if (a == true) {
if (sender.equals("settings")) {
} else if (sender.equals("savethedate")) {
if (sid.contains(facebookbid.get(position))) {
if (sid.contains("_")) {
sid = sid.replace("_" + facebookbid.get(position), "");
} else {
sid = sid.replace(facebookbid.get(position), "");
}
nb_selections--;
selectedids.remove(selectedids.size() - 1);
sidetitle.setText("Invite (" + String.valueOf(nb_selections) + ") friends");
// holder.checkmark.setVisibility(View.GONE);
} else {
if (sid.isEmpty()) {
sid = sid + facebookbid.get(position);
} else {
sid = sid + "_" + facebookbid.get(position);
}
nb_selections++;
selectedids.add(facebookbid.get(position));
sidetitle.setText("Invite (" + String.valueOf(nb_selections) + ") friends");
// holder.checkmark.setVisibility(View.VISIBLE);
}
// TO refresh view with updated checkmark status
notifyDataSetChanged();
} else {
String friendname = names.get(position);
String friendid = facebookbid.get(position);
String friendgender = gender.get(position);
Intent resultIntent = new Intent(Friends.this, Newmarriage.class);
resultIntent.putExtra("facebookbid", friendid);
resultIntent.putExtra("name", friendname);
resultIntent.putExtra("gender", friendgender);
if (sender.equals("planner")) {
resultIntent.putExtra("plannerid", friendid);
resultIntent.putExtra("imageurl", "https://graph.facebook.com/" + friendid + "/picture?type=large");
setResult(Activity.RESULT_OK, resultIntent);
finish();
} else {
resultIntent.putExtra("plannerid", "");
resultIntent.putExtra("imageurl", "");
setResult(Activity.RESULT_OK, resultIntent);
finish();
}
}
} else {
Toast.makeText(getApplicationContext(), "No internet connection", Toast.LENGTH_LONG).show();
}
}
});
/******** Set Item Click Listner for LayoutInflater for each row ***********/
// vi.setOnClickListener(new OnItemClickListener(position));
return convertView;
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
}
Suggestions
Inflate layout with parent attaching like below
.
convertView = LayoutInflater.from(activity).inflate(R.layout.planners_friends_listrow, parent, false);
Avoid mantaining status by using multiple collection(Arraylist or
like that to display data) use Model Class or JSON or Arraylist of
map etc.
I'm using expandable listView and Expandable ListAdapter.
ChlidView show me the titles and child View show me the subTitle .
In the "child View" i have a button that delete the the specific row .
i have two classes, one for loading the data from database into the hashMap and the second class for the ExpandableListAdapter. i create the onClick method on the adapter class , and the delete function is working, but the list not refreshing the updated data. i know i need to load again the data to the hashMap but the adapter class is outSide the first class. i'm trying to use "notifyDataSetChanged" and no result too.
class 1 :
hand = new DbHandler(getActivity());
fullList = new HashMap<ArrayList<ClockModel>, ArrayList<ClockModel>>();
temp = new ArrayList<ClockModel>();
ArrayList<ClockModel> child = new ArrayList<ClockModel>();
child = hand.getDay(workName);
for (int i = 0; i < child.size(); i++) {
if(child.get(i).getDateMonth() == month && child.get(i).getDateYear()==year){
ClockModel m1 = new ClockModel(
child.get(i).getId(),
child.get(i).getWorkName(),
child.get(i).getDateDay(),
child.get(i).getDateMonth(),
);
temp.add(m1);
fullList.put(temp, temp);
}
}
adapter = new ExpandableListCustom(getActivity(), fullList,temp);
lv.setAdapter(adapter);
adapter :
#Override
public View getChildView(final 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.row_child,null);
}
TextView txMyVal = (TextView) convertView.findViewById(R.id.row_myVal);
TextView txBreakTime = (TextView) convertView.findViewById(R.id.row_breakTime);
TextView txComment = (TextView) convertView.findViewById(R.id.row_comments);
TextView txNameOfDay = (TextView) convertView.findViewById(R.id.row_nameOfDay);
String comments= fullList.get(child).get(groupPosition).getComment();
nameOfDay= fullList.get(child).get(groupPosition).getNameOfDay();
shiftType= fullList.get(child).get(groupPosition).getShiftType();
int breakTime= fullList.get(child).get(groupPosition).getBreakTime();
currentPosition = fullList.get(child).get(groupPosition).getId();
btnRemove = (ImageButton) convertView.findViewById(R.id.row_btnRemove);
btnRemove.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
hand.deleteDay(currentPosition);
Toast.makeText(context, "Del : "+currentPosition, 2000).show();
}
});
public class ExpandableListCustom extends BaseExpandableListAdapter implements OnClickListener {
DbHandler hand;
private Context context;
private HashMap<ArrayList<ClockModel>,ArrayList<ClockModel> > fullList; //Headers
ArrayList<ClockModel> child; //data
MySharedPreferences preferences;
public ExpandableListCustom(Context context,
HashMap<ArrayList<ClockModel>, ArrayList<ClockModel>> fullList,
ArrayList<ClockModel> child) {
super();
this.context = context;
this.fullList = fullList;
this.child = child;
clockSet = new Clock();
preferences = new MySharedPreferences(context);
hand = new DbHandler(context);
}
#Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return this.fullList.get(this.fullList.get(childPosition));
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public View getChildView(final 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.row_child,null);
}
TextView txMyVal = (TextView) convertView.findViewById(R.id.row_myVal);
TextView txBreakTime = (TextView) convertView.findViewById(R.id.row_breakTime);
TextView txComment = (TextView) convertView.findViewById(R.id.row_comments);
TextView txNameOfDay = (TextView) convertView.findViewById(R.id.row_nameOfDay);
enterHour= (int) fullList.get(child).get(groupPosition).getEnterHour();
exitHour= (int) fullList.get(child).get(groupPosition).getExitHour();
enterMin= (int) fullList.get(child).get(groupPosition).getEnterMin();
exitMin= (int) fullList.get(child).get(groupPosition).getExitMin();
currentPosition = fullList.get(child).get(groupPosition).getId();
btnRemove = (ImageButton) convertView.findViewById(R.id.row_btnRemove);
btnRemove.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
hand.deleteDay(currentPosition);
Toast.makeText(context, "Del : "+currentPosition, 2000).show();
}
});
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub //////////////////////////////////////////
// return this.fullList.get(groupPosition).size();
if(fullList != null){
return 1;
}else{
return 0;
}
}
#Override
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return this.fullList.get(child).get(groupPosition);
}
#Override
public int getGroupCount() {
if(fullList != null){
return this.fullList.size();
}else{
return 0;
}
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
int dateDay= fullList.get(child).get(groupPosition).getDateDay();
int dateMonth= fullList.get(child).get(groupPosition).getDateMonth();
int dateYear= fullList.get(child).get(groupPosition).getDateYear();
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this.context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.row_header, null);
}
return convertView;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
}
Now when you delete the item from the database you need at the same time to remove it from the adapter and call notifyDataSetChanged():
#Override
public void onClick(View v) {
hand.deleteDay(currentPosition);
fullList.remove(currentPosition);
notifyDataSetChanged();
}
you need to fetch data from database and assign to arraylist "fullList" which is used for adapter when you delete the data and use ...
notifyDataSetChanged();
method of adapter...
I'm using a custom adapter to load 20 items from a JSON string as well as implement ads in the 4th and 14th position. What I'm encountering is that when I scroll to view item #19, it crashes with the error in the title.
I know that the error is saying that it's trying to access an index that is not in the array but I think it's because it's included the adViews in the index (which it shouldn't). I feel like this is something simple that I am missing but please help. Here are my 2 adapters:
public class ListViewAdapter extends BaseAdapter implements AdListener {
private final Activity activity;
private final BaseAdapter delegate;
public ListViewAdapter(Activity activity, BaseAdapter delegate) {
this.activity = activity;
this.delegate = delegate;
}
#Override
public int getCount() {
// Total count includes list items and ads.
return delegate.getCount() + 2;
}
#Override
public Object getItem(int position) {
// Return null if an item is an ad. Otherwise return the delegate item.
if (isItemAnAd(position)) {
return null;
}
return delegate.getItem(position - 1);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (isItemAnAd(position)) {
if (convertView instanceof AdView) {
return convertView;
} else {
AdView adView = new AdView(activity, AdSize.SMART_BANNER,"AD ID (removed for post)" );
AdRequest adRequest = new AdRequest();
adView.loadAd(adRequest);
return adView;
}
} else {
return delegate.getView(position-1, convertView, parent);
}
}
#Override
public int getViewTypeCount() {
return delegate.getViewTypeCount() + 1;
}
#Override
public int getItemViewType(int position) {
if (isItemAnAd(position)) {
return delegate.getViewTypeCount();
} else {
return delegate.getItemViewType(getOffsetPosition(position));
}
}
#Override
public boolean areAllItemsEnabled() {
return false;
}
#Override
public boolean isEnabled(int position) {
return (!isItemAnAd(position)) && delegate.isEnabled(getOffsetPosition(position));
}
private boolean isItemAnAd(int position) {
// Place an ad at the first and last list view positions.
return (position == 4 || position == 14);
}
#Override
public void onDismissScreen(Ad arg0) {
}
#Override
public void onFailedToReceiveAd(Ad arg0, AdRequest.ErrorCode arg1) {
}
#Override
public void onLeaveApplication(Ad arg0) {
}
#Override
public void onPresentScreen(Ad arg0) {
}
#Override
public void onReceiveAd(Ad arg0) {
}
private int getOffsetPosition(int position) {
return position - 1;
}
}
Here's the custom adapter which sets the listview:
class CustomMovieAdapter extends BaseAdapter {
private ArrayList<SearchResults> searchArrayList;
private LayoutInflater mInflater;
public CustomMovieAdapter(Context context, ArrayList<SearchResults> results){
searchArrayList = results;
mInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return searchArrayList.size()+2;
}
#Override
public Object getItem(int position) {
return searchArrayList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
if(convertView == null){
convertView = mInflater.inflate(R.layout.list_item, null);
holder = new ViewHolder();
assert convertView != null;
holder.txtRating = (TextView) convertView.findViewById(R.id.movieRating);
holder.txtMovieName = (TextView) convertView.findViewById(R.id.movieName);
holder.txtMovieSize = (TextView) convertView.findViewById(R.id.movieSize);
holder.txtImdbRating = (TextView) convertView.findViewById(R.id.imdbScore);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtRating.setText(searchArrayList.get(position+1).getRating());
holder.txtMovieName.setText(searchArrayList.get(position+1).getName());
holder.txtMovieSize.setText(searchArrayList.get(position+1).getSize());
holder.txtImdbRating.setText(searchArrayList.get(position+1).getImdbRating());
return convertView;
}
class ViewHolder {
TextView txtRating;
TextView txtMovieName;
TextView txtMovieSize;
TextView txtImdbRating;
}
}
#Override
public int getCount() {
// Total count includes list items and ads.
return delegate.getCount() + 2;
}
you should return the size of the dataset without changing it. If you need to show more items, add those to the dataset. Changing it with
#Override
public int getCount() {
// Total count includes list items and ads.
return delegate.getCount() ;
}
Should fix your exception.
Edit, in getView you should avoid tampering the position android is providing you:
position+1