When i was trying to iterate through the arraylist of custom listview used for loop, my app suddenly crashed and when i tried to look at the logcat no error appeared. I've tried one by one finding the problem then i found out the problem is the part where i try to get the item value. can help me point out the problem?
This is part of my code in iterating/getting the arraylist value
for(int i=0;i<=myAdapter.myItem.size();i++){
String name=tabl.getText().toString();
//this is the part that causes the crash
String answer=myAdapter.myItem.get(i).toString();
//mHelper.insertData(name,answer);
//temporary disable sql
}
This is my subclass for the custom listview
public class MyAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public ArrayList myItem = new ArrayList();
public MyAdapter() {
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 1; i < x+1; i++) {
ListItem listItem = new ListItem();
listItem.caption = "hahaha";
myItem.add(i+".");
}
notifyDataSetChanged();
}
public int getCount() {
return myItem.size(); }
public Object getItem(int position) {
return position; }
public long getItemId(int position) {
return position; }
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.items, null);
holder.caption = (EditText) convertView
.findViewById(R.id.ItemCaption);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//Fill EditText with the value you have in data source
holder.caption.setText(myItem.get(position).toString());
holder.caption.setId(position);
//we need to update adapter once we finish with editing
holder.caption.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus){
final int position = v.getId();
final EditText Caption = (EditText) v;
myItem.set(position, Caption.getText().toString());
}
}
});
return convertView;
}
}
class ViewHolder { EditText caption;}
class ListItem { String caption;}
change
for(int i=0;i<=myAdapter.myItem.size();i++){
with:
for(int i=0; i < myAdapter.myItem.size(); i++) {
When you're using <=, at the last iteration you're pointing to null. The condition should be just i < myAdapter.myItem.size();
Related
I need help to refresh the ListView of disabled item. I've read a few articles, I gotta say I have no idea how to refresh the disabled item, therefore if you can give me a hand and post with that additional desired code, it would be more than appreciated.
Thanks in advance!
I have this code in my Activity:
adapter = new CustomAdapter(PendingOrdersActitvity.this, itemsList1);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
for (int i = 0; i <itemsList1.size(); i++) {
if(i == position){
view.setEnabled(false);
view.setClickable(false);
view.setBackgroundColor(Color.parseColor("#DCDBDB"));
ItemsBean bean = new ItemsBean();
bean.setInvNo(itemsList1.get(position).getInvNo());
bean.setItemnNameDisplay(itemsList1.get(position).getItemnNameDisplay());
bean.setQuantityDisplay(itemsList1.get(position).getQuantityDisplay());
bean.setProdnum(itemsList1.get(position).getProdnum());
newlist.add(bean);
adapter.getmethod(position);
}
}
insertintodatabase(newlist);
newlist.clear();
adapter.notifyDataSetChanged();
return true;
}
});
This is my custom Adapter class I don't know where is fault but i need help to complete the project as am new to android
public class CustomAdapter extends BaseAdapter {
Context ctx;
private int pos;
LayoutInflater inflator;
ArrayList<ItemsBean> newList = new ArrayList<ItemsBean>();
ArrayList<ItemsBean> newListitems = new ArrayList<ItemsBean>();
ArrayList<String> childList = new ArrayList<String>();
ArrayList<String> qtychildList = new ArrayList<String>();
String parentobjid=null;
PendingOrdersActitvity myactivity;
public CustomAdapter(PendingOrdersActitvity kdsActitvity, ArrayList<ItemsBean> invoiceDataList) {
this.ctx = kdsActitvity;
this.newList = invoiceDataList;
this.inflator = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
pos = -1;
}
public int getCount() {
return newList.size();
}
public void getmethod(int pos1) {
pos = pos1;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
public static class ViewHolder {
TextView qty, name, childText, qtyChild;
}
#SuppressLint("NewApi") #Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
String item = null, qty = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflator.inflate(R.layout.invoicelistadapter, null);
holder.qty = (TextView) convertView.findViewById(R.id.qty);
holder.name = (TextView) convertView.findViewById(R.id.item);
holder.childText = (TextView) convertView
.findViewById(R.id.childitem);
holder.qtyChild = (TextView) convertView
.findViewById(R.id.qtychild);
convertView.setTag(holder);
} else {
if(pos!=-1 && pos==position)
{
convertView.setEnabled(false);
convertView.setClickable(false);
convertView.setBackgroundColor(Color.parseColor("#DCDBDB"));
}
holder = (ViewHolder) convertView.getTag();
}
//holder.qty.setText(String.valueOf(newList.get(position).getQuantityDisplay()));
parentobjid=newList.get(position).getParentobjectid();
if(!parentobjid.isEmpty())
{
holder.name.setText(" " +newList.get(position).getItemnNameDisplay());
holder.name.setTextColor(Color.parseColor("#CC0000"));
holder.qty.setText(" "+String.valueOf(newList.get(position).getQuantityDisplay()));
holder.qty.setTextColor(Color.parseColor("#CC0000"));
} else {
holder.name.setText(newList.get(position).getItemnNameDisplay());
holder.qty.setText(String.valueOf(newList.get(position)
.getQuantityDisplay()));
holder.name.setTextColor(Color.parseColor("#FFFFFF"));
holder.qty.setTextColor(Color.parseColor("#FFFFFF"));
}
}
}
call adapter.notifyDataSetChanged() inside the listview ClickListener.
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
for (int i = 0; i <itemsList1.size(); i++) {
if(i == position){
view.setEnabled(false);
view.setClickable(false);
view.setBackgroundColor(Color.parseColor("#DCDBDB"));
ItemsBean bean=new ItemsBean();
bean.setInvNo(itemsList1.get(position).getInvNo());
bean.setItemnNameDisplay(itemsList1.get(position).getItemnNameDisplay());
bean.setQuantityDisplay(itemsList1.get(position).getQuantityDisplay());
bean.setProdnum(itemsList1.get(position).getProdnum());
newlist.add(bean);
adapter.getmethod(position);
}
insertintodatabase(newlist);
newlist.clear();
adapter.notifyDataSetChanged();
return true;
}
});
The ListView is just a container.
Instead of enabling the single items, clear it and recreate it through your Adapter.
In fact the adapter just ties the ListView to an ArrayList of elements and represents into the ListView the "state" of the ArrayList.
Do not operate to ListView already created, but refresh the ArrayList and the ListView will be refreshed too!
use notifydatasetchanged();
Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself
What I am trying to achieve is that, I am having an ArrayList< String > data = new ArrayList< String >(); that contains values form 1 to 100. Now if I want to display this data in a scrollView then I will write the following code:
for(int i=0; i<data.size(); i++) {
View v = getLayoutInflator.inflate(R.layout.mycontainer, null);
TextView tv = (TextView)v.findViewById(R.id.tv1);
tv.setText(data.get(i));
layout.addView(v);
}
The above code will display the data, but it may take some time to display all the data. What I want to do is that, I want to update the scrollView at every loop and display each row after the textview is added to the layout.
Please check out this app for the reference.
This is the test code that I am doing to achieve what I want. Please have a look:
ListView list = (ListView)findViewById(R.id.listView1);
ListAdapter adapter = new ListAdapter(this);
list.setAdapter(adapter);
for(int i=1; i<=10; i++) {
adapter.setData(String.valueOf(i));
adapter.notifyDataSetChanged();
}
Code for my ListAdapter:
public class ListAdapter extends BaseAdapter {
private Context context;
private int count;
private ArrayList<String> data = new ArrayList<String>();
public ListAdapter(Context context) {
this.context = context;
}
#Override
public int getCount() {
return count;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
public void setData(String str) {
data.add(str);
count = data.size();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.test_layout, parent, false);
holder = new ViewHolder();
holder.tv = (TextView)convertView.findViewById(R.id.textView1);
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
try {
for(int i=0; i<=data.size(); i++) {
holder.tv.setText(data.get(i));
}
} catch (Exception e) {
e.printStackTrace();
}
return convertView;
}
static class ViewHolder {
TextView tv;
}
}
Thanks in advance
Abhishek
Clean Master (Cleaner)
What this app is using is a regular ListView.
I am not able to figure out how they are displaying data of single
cell instead of showing data of all the cell's at once
What this app is doing:
The apps objects are fetched at run-time. These app objects are passed to the adapter one by one (as opposed to passing them as one long list), as they are made available, and adapter.notifyDataSetChanged() is called after adding each object.
I have a GridView with two TextViews inside it, When the GridView is populated, an OnClickListener is set which returns the position of the item that was selected. I want to trigger a method when one of the TextViews is selected.
Is this possible? If yes, how do I set this up?
EDIT 3:
Inside my activity whch populated the GridView: I retrieve a String-Array from my Strings.xml, a for loop examines each item inside the Array and searches for a condition based on the Item's name inside the SharedPreferences, this for loop is solely for counting how many "true" conditions there are, so it retrieves a int saved inside the count. Then a new String[] is created, this required an exact length to be given before items can be added to it, so I check count if it's more than 0, it will give the String[] a length of count and then another for loop will add each true to the String[] list that we just created. If count is 0 (no true conditions found in the first for loop) then only 1 Item is added to the String[] and is given the value "No Favourites Added".
Then you have the GridView's OnItemClickListener().
String s[] = getResources().getStringArray(R.array.FullList);
int count = 0;
for(int i = 0; i < s.length; i++) {
SharedPreferences sP = getActivity().getSharedPreferences("fav", MODE_PRIVATE);
Boolean b = sP.getBoolean(s[i], false);
if (b == true) {
count++;
}
}
String[] newList;
if (count > 0) {
newList = new String[count];
count = 0;
for(int i = 0; i < s.length; i++) {
SharedPreferences sP = getActivity().getSharedPreferences("fav", MODE_PRIVATE);
Boolean b = sP.getBoolean(s[i], false);
if (b == true) {
newList[count] = s[i];
count++;
}
}
} else {
newList = new String[1];
newList[0] = "No favourites added";
}
GridView FavGV = (GridView) getActivity().findViewById(R.id.sexp_fav);
FavGV.setAdapter(new Tab01_FavAdapter(getActivity(), newList));
FavGV.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView arg0,
View arg1, int position, long arg3) {
//Intent i = new Intent(getActivity(), PosPreview_Gestures.class);
//i.putExtra("position", position);
//startActivity(i);
}
});
So that's the code inside the Activity which populates the GridView. The Adapter in it's original, functioning form: This simply populates the GridView with Favourite Items (their names from the String[]) and adds a TextView with "Remove" which when pressed, shows a Toast: "Remove".
public class Tab01_FavAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mInflator;
String mEntries[];
public Tab01_FavAdapter (Context c, String[] entries) {
mContext = c;
mInflator = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mEntries = entries;
}
#Override
public int getCount() {
return mEntries.length;
}
#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) {
if(convertView == null) {
convertView = mInflator.inflate(R.layout.favitemlayout, parent, false);
}
TextView tx = (TextView) convertView.findViewById(R.id.favgridremoveitem);
OnClickListener oCL = new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext,"Remove",Toast.LENGTH_SHORT).show();
}
};
tx.setOnClickListener(oCL);
return convertView;
}
}
I am assuming that you are using a custom adapter for populating this GridView, and passing the Context as an argument to the constructor.
In the custom adapter, you should add onClickListeners to the TextViews. Using the context, you can call methods from your activity:
((CallingActivityName)context).methodYouWishToCall(parameters);
This would go inside the onClickListeners.
Edit: Added some code:
public class MyGridAdapter extends BaseAdapter {
private final List<MyObjectClass> mEntries;
private final LayoutInflater mInflater;
private final Context mContext;
public static class ViewHolder {
public TextView tx;
}
public MyGridAdapter(CallingActivityName context, List<MyObjectClass> entries) {
super();
mEntries = entries;
mContext = context;
mInflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return mEntries.size();
}
#Override
public Object getItem(int position) {
return mEntries.get(position);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = mInflator.inflate(R.layout.favitemlayout, parent, false);
holder = new ViewHolder();
holder.tx = (TextView) convertView
.findViewById(R.id.favgridremoveitem);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final MyObjectClass info = mEntries.get(position);
holder.tx.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
((CallingActivityName)mContext).favRemove(info);
notifyDataSetChanged();
}
});
return convertView;
}
}
So, CallingActivityName is the name of the Activity where you initiate the adapter and where the method you need to call resides. info is the object held at position position of the gridview. MyObjectClass is the class name of the objects in the List mEntries.
I need a way to remove an Item from the GridView but this must be done from within the getView() method inside my custom Adapter. Here is my GridView:
Activity:
...
String[] newList;
newList[0] = "Item 1";
newList[1] = "Item 2";
newList[2] = "Item 3";
...
GridView GV = (GridView) getActivity().findViewById(R.id.gv);
GV.setAdapter(new Adapter(getActivity(), newList));
GV.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView arg0,
View arg1, int position, long arg3) {
...
}
});
Adapter
public class Adapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mInflator;
private String mEntries[];
public static class ViewHolder {
public TextView myTextView;
}
public Adapter (Context context, String[] entries) {
mContext = context;
mInflator = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mEntries = entries;
}
#Override
public int getCount() {
return mEntries.length;
}
#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) {
ViewHolder holder = null;
if(convertView == null) {
convertView = mInflator.inflate(R.layout.gvitemlayout, parent, false);
holder = new ViewHolder();
holder.myTextView = (TextView) convertView.findViewById(R.list.removeItem);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
String string = mEntries[position];
String[] data = string.split("\\.");
if (data.length < 2) {
TextView itemName = (TextView) convertView.findViewById(R.list.itemName);
itemName.setText("");
TextView itemClass = (TextView) convertView.findViewById(R.favlist.itemClass);
itemClass.setText("");
holder.myTextView.setText("");
TextView itemNone = (TextView) convertView.findViewById(R.list.itemNone);
itemNone.setText("No Items");
} else {
TextView itemName = (TextView) convertView.findViewById(R.list.itemName);
itemName.setText(data[1]);
TextView itemClass = (TextView) convertView.findViewById(R.list.itemClass);
itemClass.setText(data[0]);
}
final int info = (Integer) getItem(position);
holder.myTextView.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
SharedPreferences sP = mContext.getSharedPreferences("fav", mContext.MODE_PRIVATE);
Boolean b = sP.getBoolean(mEntries[info], false);
if (b == true) {
SharedPreferences.Editor editor = sP.edit();
editor.remove(mEntries[info]);
editor.commit();
// REMOVE ITEM CODE NEEDED HERE
}
}
});
return convertView;
}
}
Hope this makes it easier to understand what I need.
This is what I did, there was no need to initialise the 'adapter' variable. Inside the getView() simply do this:
Remove the Item from the list that was used as the data source.
So. if you want to remove Item 2 from the list
String mEntries[] = ITEM1, ITEM2, ITEM3, etc
Do this:
String newList[] = new String[mEntries.length - 1];
int count = 0;
for (int i = 0; i < mEntries.length; i++) {
if (mEntries.length - 1 > 0) {
if (mEntries[i] == mEntries[1]) { // mEntries[1] as the range starts from 0, so 1 would be ITEM2
// SKIP IF MATCHES THE ITEM YO WANT TO REMOVE
} else {
newList[count] = mEntries[i];
count++;
}
}
}
mEntries = newList; // save the new list into mEntries
notifyDataSetChanged(); // notify the changes and the listview/gridview will update
What you are asking for is very possible. You didn't give enough code for it to be clear exactly what's happening, but the code above you posted won't work unless the remove button is an entire view returned by getView in the adapter.
Your getView in your adapter will need to look something like this:
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.grid_view_item, null);
}
Button removeButton = (Button) convertView.findViewById(R.id.remove_button);
removeButton.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View v) {
adapter.mThumbIdsList.remove(position);
adapter.notifyDataSetChanged();
}
});
return convertView;
}
Hope this helps. Good luck!
I have a ListView in my app which has a custom adapter. I have a ImageView, a CheckBox and a TextView in my list view and i have one button in my app which should delete Checked items from the list on onClick event but the problem is - It does not matter which items i am selecting but it's always deleting the items from the botton of the list.
here is my custom adapter's code -
public class IconAdapter extends BaseAdapter
{
private Activity activity;
private Object[] data;
private ArrayList<HashMap<String,String>> listItems;
public static LayoutInflater inflater = null;
private PackageManager pm;
public ArrayList<Boolean> itemChecked = new ArrayList<Boolean>();
private ArrayList<String> itemSelected = new ArrayList<String>();
private ArrayList<TextView> ctv = new ArrayList<TextView>();
private int posi;
private String pkg;
public IconAdapter(Activity a, ArrayList<HashMap<String,String>> items)
{
activity = a;
listItems = items;
data = items.toArray();
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
pm = a.getPackageManager();
for(int i = 0; i < items.size(); i++)
{
itemChecked.add(i,false);
}
for(int i = 0; i < items.size(); i++)
{
itemSelected.add(i," ");
}
}
public int getCount() {
return listItems.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public static class ViewHolder{
public TextView textView;
public ImageView imageView;
public CheckBox checkBox;
}
public View getView(final int position, View convertView, ViewGroup parent)
{
View row = convertView;
ViewHolder holder;
if(row==null)
{
row = inflater.inflate(R.layout.item, parent, false);
holder = new ViewHolder();
holder.textView = (TextView)row.findViewById(R.id.text1);
holder.imageView = (ImageView)row.findViewById(R.id.image);
holder.checkBox = (CheckBox)row.findViewById(R.id.check);
row.setTag(holder);
}
else
{
holder = (ViewHolder) row.getTag();
}
String s = data[position].toString();
String[] tokens = s.split(",");
String[] mToken = tokens[0].split("=");
String taskName = mToken[1];
String[] mTokens = tokens[1].split("=");
final String pkgName = mTokens[1].substring(0, (mTokens[1].length() - 1));
holder.textView.setText(taskName);
holder.textView.setTag(pkgName);
holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton button, boolean b) {
if (b)
{
itemChecked.set(position, true);
itemSelected.set(position, pkgName);
}
else
{
itemChecked.set(position, false);
}
}
});
holder.checkBox.setChecked(itemChecked.get(position));
try{
Drawable icon = pm.getApplicationIcon(pkgName);
holder.imageView.setImageDrawable(icon);
}
catch (PackageManager.NameNotFoundException ne)
{
}
return row;
}
public String getPkgName(int position)
{
return itemSelected.get(position);
}
public void setItemChecked(boolean isChecked)
{
}
}
nd here is my onClick code -
public void onClick(View view)
{
int size = icon.getCount();
for(int i = size-1; i >= 0; i--)
{
if(icon.itemChecked.get(i))
{
list.remove(i);
}
}
icon.notifyDataSetChanged();
}
please help!!!!!
And when i removed notifyDataSetChanged from onClick and reload the list manually again its working exactly i want it to work so there is some problem in NotyfyDataSetChanged. Please help.
You can use notifyDataSetChanged method of your adapter, but keep in mind some points that are stated here (see accepted answer) notifyDataSetChanged example
did you put a log statement in onCheckedChanged method and see what position is being set ? My guess is that you shouldn't use the position argument in that manner. One way to do so could be to use holder.checkBox.setTag(new Integer(position)) and in the onCheckedChanged method use int posClicked = ((Integer)button.getTag()).intValue() and then use this instead of position