I have created a ListView for My Model class and displayed it successfully.
I have successfully done removing value/raw from my ListView onItemClickListener of ListView.
It's Ok, But, my ListView also contains an ImageView and I have to delete a row on click of that ImageView.
So, I have taken a BaseAdapter and handle click of my that ImageView inside my BaseAdapter as below :
My Adapter class is as below :
public class MyAdapter extends BaseAdapter {
private ArrayList<ModelClass> mArrayListModel;
private LayoutInflater mInflator;
private Context mContext;
public MyAdapter(Context mContext, ArrayList<ModelClass> mArrayListModel) {
this.mContext = mContext;
this.mArrayListModel = mArrayListModel;
}
#Override
public int getCount() {
return mArrayListModel.size();
}
#Override
public Object getItem(int position) {
return mArrayListModel.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder view = null;
if (convertView == null) {
view = new ViewHolder();
mInflator = LayoutInflater.from(mContext);
convertView = mInflator.inflate(R.layout.custom_layout, parent, false);
view.textName = (TextView) convertView.findViewById(R.id.txtName);
view.textAddress = (TextView) convertView.findViewById(R.id.txtAddress);
// view.btnShow = (Button) convertView.findViewById(R.id.btnShow);
view.imgDelete=(ImageView) convertView.findViewById(R.id.imgDelete);
view.textName.setText("" + mArrayListModel.get(position).getStrName());
view.textAddress.setText("" + mArrayListModel.get(position).getStrAddress());
convertView.setTag(view);
view.imgDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, ""+mArrayListModel.get(position).getStrName(), Toast.LENGTH_SHORT).show();
mArrayListModel.remove(position);
notifyDataSetChanged();
}
});
} else {
view = (ViewHolder) convertView.getTag();
}
return convertView;
}
class ViewHolder {
TextView textName, textAddress;
//Button btnShow;
ImageView imgDelete;
}
}
I am deleting as below :
view.imgDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, ""+mArrayListModel.get(position).getStrName(), Toast.LENGTH_SHORT).show();
mArrayListModel.remove(position);
notifyDataSetChanged();
}
});
The Problem is with deleting item, When I click on ImageView it deletes only last value.. last position from listview. I think its issue with my position.
Will you pls. check it and let me know what might be the issue ?
Thanks.
Related
When I click on the first button only clicked on one button it sets the button background ok . but problem when I scroll down i found more buttons was changed randomly look like picture.
See picture here.
part of code :- ContactSug_Adapter
public class ContactSug_Adapter extends ArrayAdapter {
List list = new ArrayList();
ImageLoader imgLoader = new ImageLoader(getContext());
private Context context;
public ContactSug_Adapter(Context context, int resource) {
super(context, resource);
}
#Override
public void add(Object object) {
super.add(object);
list.add(object);
}
#Override
public int getCount() {
return super.getCount();
}
#Override
public Object getItem(int position) {
return this.list.get(position);
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
View row;
row = convertView;
final ContactHolder contactHolder;
if (row == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.row, parent, false);
contactHolder = new ContactHolder();
contactHolder.tx_id = (TextView) row.findViewById(R.id.usersName2);
contactHolder.tx_name = (TextView) row.findViewById(R.id.usersName);
contactHolder.sug_add = (Button) row.findViewById(R.id.sug_id);
row.setTag(contactHolder);
} else {
contactHolder = (ContactHolder) row.getTag();
}
final Contacts_Sug contacts = (Contacts_Sug) this.getItem(position);
contactHolder.image_tx.setImageResource(R.mipmap.ic_launcher);
contactHolder.tx_id.setText(contacts.getId());
contactHolder.tx_name.setText(contacts.getName());
contactHolder.sug_add.setTag(position);
contactHolder.sug_add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
contactHolder.sug_add.setText("Selected");
}
});
return row;
}
public class ContactHolder {
TextView tx_id, tx_name,loadId;
ImageView image_tx;
public Button sug_add;
}/********* act
This is due to recycling of views.
You need to set the text "Selected" for the items you want to be and set the default text for the other items. You can do that using if-else statement.
For that you need to have a member variable in Contacts_Sug to hold the selectionPos like this -
private int selectionPos;
public void setSelectedPosition(int position){
selectionPos = position;
}
public int getSelectedPosition(){
return selectionPos;
}
And set it in button onClick() -
contactHolder.sug_add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
contacts.setSelectedPosition(position); //Set position here
contactHolder.sug_add.setText("Selected");
}
});
And outside this onClick() where you are setting the values for your views.
Add this -
if(contacts.getSelectedPosition() == position){
//Set your button state to "selected" here
contactHolder.sug_add.setText("Selected");
} else{
//Set your button state to default here
contactHolder.sug_add.setText("Follow");
}
Is it possible to change row view when I'm clicking on it? For example I have listView with rows where some short information shown, and when after clicking on row detailed view will show instead of old row.
I tried to use addView in my listView, but "listview addView(View, int) is not supported in AdapterView" error appeared.
try something like that:
public class MyAdapter extends BaseAdapter {
private Context mContext;
private List<UserPojo> mList;
public MyAdapter(Context context, List<UserPojo> users) {
this.mContext = context;
this.mList = users;
}
#Override
public int getCount() {
return mList.size();
}
#Override
public UserPojo getItem(int position) {
return mList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final UserPojo user = mList.get(position);
final ViewHolder holder;
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.item_ad, null);
holder = new ViewHolder();
holder.pic = (CircleImageView) convertView.findViewById(R.id.profile_imageView);
holder.name = (TextView) convertView.findViewById(R.id.name_textView);
convertView.setTag(holder);
} else{
holder = (ViewHolder) convertView.getTag();
}
if (user.isClicked) {
holder.pic.setVisibility(View.VISIBLE);
holder.name.setVisibility(View.GONE);
} else {
holder.pic.setVisibility(View.GONE);
holder.name.setVisibility(View.VISIBLE);
}
holder.name.setText("text");
holder.name.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
user.setClicked(true);
notifyDataSetChanged();
}
});
return convertView;
}
private static class ViewHolder {
CircleImageView pic;
TextView name;
}
}
I have a CustomBase adapter with a button attached to it,when I click on the button the row is to be deleted, which is working perfectly fine, but my problem is, that data which is populated in my adapter is from a remote server, I want to be getting the information contained by the adapter before deleting it and giving it to my MainActivity, in my case, I would like to be getting the title before the view is removed and sending it to the server, telling it to delete it from storage, the big issue is all code to do with the button is in my baseAdapter class, I do not know if I can give my MainActivity the data before the row is Deleted, I cannot think of a way of achieving that, if anyone has an idea please share, below is my Base Adapter.
public class CartAdapter extends BaseAdapter{
private ArrayList<ListItem> listData;
private LayoutInflater layoutInflater;
ViewHolder holder;
public CartAdapter(Context context, ArrayList<ListItem> listData) {
this.listData = listData;
notifyDataSetChanged();
layoutInflater = LayoutInflater.from(context);
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.singlecartitem, null);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.title);
final ImageButton delete = (ImageButton) convertView.findViewById(R.id.delete);
convertView.findViewById(R.id.postCommentBox);
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listData.remove(position);
notifyDataSetChanged();
}
});
convertView.setTag(holder);
delete.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final ListItem newsItem = listData.get(position);
holder.title.setText(newsItem.getTitle());
return convertView;
}
static class ViewHolder {
TextView title;
int position;
}
}
Are you using a ListFragment? If you do, check
this out.
If you do not, make your activity implement an interface e.g. HandleDeletion with a method e.g. handleTitle(String title). In your clickListener cast the context object to HandleDeletion and call the method handleTitle(String title) on it. This is a so called callback.
[EDIT]
Example:
public interface HandleDeletion {
handleTitle(String title);
}
public class MyActivity implements HandleDeletion {
...
handleTitle(String title) {
//do whatever you want
}
...
}
public class CartAdapter extends BaseAdapter{
...
private Context context;
public CartAdapter(Context context, ArrayList<ListItem> listData) {
this.listData = listData;
this.context = context;
notifyDataSetChanged();
layoutInflater = LayoutInflater.from(context);
}
public View getView(final int position, View convertView, ViewGroup parent) {
...
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((HandleDeletion)context).handleTitle(listData.get(position).getTitle());
listData.remove(position);
notifyDataSetChanged();
}
});
...
}
...
}
I've four textviews and a button in listview. when user clicks on the button i want to get the value of these four textviews and pass to the database. I'm confuse how to save the data of selected item to sqlite.
public class PlannningListViewAdapter extends BaseAdapter{
Context context;
public ArrayList<Planning> planArraylist;
private static LayoutInflater inflater = null;
public Activity planActivity;
public PlannningListViewAdapter(Context context,
ArrayList<Planning> planArraylist) {
this.context = context;
this.planArraylist = planArraylist;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return planArraylist.size();
}
#Override
public Object getItem(int arg0) {
return arg0;
}
#Override
public long getItemId(int arg0) {
return arg0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.single_lv_item, null);
}
Planning p = planArraylist.get(position);
TextView tvDocCode = (TextView) convertView.findViewById(R.id.Plan_no);
TextView tvDocName = (TextView) convertView.findViewById(R.id.doc_name);
TextView tvmon = (TextView) convertView.findViewById(R.id.mon);
TextView tvAdr = (TextView) convertView.findViewById(R.id.adr);
Button btn_save =(Button)convertView.findViewById(R.id.button1);
btn_save.setOnClickListener(ButtonClickListener);
tvDocCode.setText(p.getDocCode());
tvDocName.setText(p.getDocName());
tvmon.setText(p.getTerrCode());
tvAdr.setText(p.getAdr());
return convertView;
}
private OnClickListener ButtonClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
final int position = mListView.getPositionForView((View) v.getParent());
// Log.v(TAG, "item clicked, row %d", position);
}
};
}
You can use setTag()and getTag() method on your button.
Please look at the code below:
You have to change getItem method:
#Override
public Planning getItem(int arg0) {
return planArraylist.get(arg0);
}
Update your getView method:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
...
Button btn_save =(Button)convertView.findViewById(R.id.button1);
btn_save.setTag(position);
...
}
private OnClickListener ButtonClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
final int position = (int)v.getTag();
Planning planning = getItem(position);
yourDatabaseHelper. getRuntimeExceptionDao(Planning.class).createOrUpdate(planning);
}
};
One more thing. You should implement ViewHolder please read about this pattern, and the best solution for you is use RecyclerView, getting position is already implemented there in RecyclerView.ViewHolder.
One of my activities requires a list view with custom number pickers in each row.
I created the number picker as suggested here. When I click on the buttons, however, the counter doesn't increment or decrement at all.
The following is the code found at my Custom ListView Adapter.
public class MaterialListViewAdapter extends BaseAdapter
{
ViewHolder holder;
int counter = 0;
private ArrayList<MaterialClass> data;
public static LayoutInflater inflater = null;
public static Dialog dialog;
String materialName;
public MaterialListViewAdapter(Context applicationContext,
int materialdialogcontent, ArrayList<MaterialClass> materials)
{
this.data = materials;
inflater = (LayoutInflater)applicationContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount()
{
return data.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 = new ViewHolder();
if(vi == null)
{
holder = new ViewHolder();
vi = inflater.inflate(R.layout.materialdialogcontent, null);
//Initialize Buttons and TextViews.
holder.num.setText("0");
holder.add.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
counter++;
holder.num.setText("" + counter);
}
});
holder.sub.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
counter--;
holder.sub.setText("" + counter);
}
});
//holder.pk = (NumberPicker)vi.findViewById(R.id.npMaterialAmount);
vi.setTag(holder);
}
else
{
holder = (ViewHolder)vi.getTag();
}
holder.txt.setText(data.get(position).getName());
//holder.pk.setMaxValue(20);
//holder.pk.setMinValue(0);
return vi;
}
private class ViewHolder
{
TextView txt;
Button add;
Button sub;
TextView num;
//NumberPicker pk;
}
}
When I try debugging to see what's going on, counter doesn't even initialize with '0'.
I tried initializing the counter in the getView() method, however in order to do so I need to set the counter to final, and then another error shows up saying
The final local variable counter cannot be assigned, since it is defined in an enclosing type.
Any suggestions?
Updated for additional code:
public class Material extends Activity
{
ArrayList<String> materialList;
ListView lv;
Button btnConfirm;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_material);
lv = (ListView)findViewById(R.id.list);
btnConfirm = (Button)findViewById(R.id.btnConfirm);
materialList = new ArrayList<String>();
Intent i = getIntent();
materialList = i.getStringArrayListExtra("materialList");
if(materialList != null)
{
Toast t = Toast.makeText(getApplicationContext(), materialList.get(0).toString(), Toast.LENGTH_LONG);
t.show();
}
else
{
//FILL HERE LATER
}
ArrayList<MaterialClass> materials = new ArrayList<MaterialClass>();
for(String temp : materialList)
{
MaterialClass m = new MaterialClass();
m.setName(temp);
materials.add(m);
}
MaterialListViewAdapter adapter = new MaterialListViewAdapter(getApplicationContext(), R.layout.materialdialogcontent, materials);
lv.setAdapter(adapter);
}
}
You should implement the onItemClickListener for your listView . You are using listener in adapter class but practically those numbers are nothing but items of that listView, so that to operate on those buttons (listView's items) you've not defined onItemClickListener. So after setting adapter write
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View item, int position, long id) {
// here you are getting position of clicked item
}
}
UPDATE:
I've gone through your code again and I found these:
1.you are writing this line:
MaterialListViewAdapter adapter = new MaterialListViewAdapter(getApplicationContext(), R.layout.materialdialogcontent, materials);
but I didn't see any constructor in your Adapter.
2.As you are extending BaseAdapter, you must override getCount() , getItem(int position) and getItemId(int position) method as like getView() . There you are getting issue.
Try this :
public class MaterialListViewAdapter extends BaseAdapter
{
ViewHolder holder;
int counter = 0;
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View vi = convertView;
//ViewHolder holder = new ViewHolder();
if(vi == null)
{
holder = new ViewHolder();
vi = inflater.inflate(R.layout.materialdialogcontent, null);
//Initialize Buttons and TextViews.
//holder.pk = (NumberPicker)vi.findViewById(R.id.npMaterialAmount);
vi.setTag(holder);
}
else
{
holder = (ViewHolder)vi.getTag();
}
holder.txt.setText(data.get(position).getName());
//holder.pk.setMaxValue(20);
//holder.pk.setMinValue(0);
holder.add.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
counter++;
holder.num.setText("" + counter);
}
});
holder.sub.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
counter--;
holder.num.setText("" + counter);
}
});
return vi;
}
private class ViewHolder
{
TextView txt;
Button add;
Button sub;
TextView num;
//NumberPicker pk;
}
}