Android - Gridview, custom layout onclicklistener - android

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.

Related

ListView modify other view from specific view

I have a ListView that contains 5 rows with 5 button:
When I click on first button, I replace it text with "B".
Then, I click on second button, I replace it text with "B", but how can I replace the previous clicked button (the first) with "A"?
This is what really happen:
This is my code for the button click:
private int resource;
private LayoutInflater inflater;
ViewHolder holder;
private Context ctx;
public RingtoneAdapter(Context context, int resourceId, List<Ringtone> objects) {
super(context, resourceId, objects);
this.ctx = context;
resource = resourceId;
inflater = LayoutInflater.from(context);
}
public View getView(final int position, View v, ViewGroup parent) {
// Recuperiamo l'oggetti che dobbiamo inserire a questa posizione
final Ringtone ringtone = getItem(position);
if (v == null) {
v = inflater.inflate(resource, parent, false);
holder = new ViewHolder();
holder.btnPlay = (Button) v.findViewById(R.id.btnPlay);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.btnPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Button btnadd = (Button) view;
btnadd.setText("B");
notifyDataSetChanged();
}
});
return v;
}
private static class ViewHolder {
Button btnPlay;
TextView txtTitolo;
TextView txtCategoria;
}
If I'm reading this correctly, you only want a single position to be 'selected' at a time. If that's the case, you could keep a reference to the selected position, and use the Adapter's functionality instead of having multiple buttons know about each other. e.g.
private int selectedPosition = -1;
#Override
public View getView(final int position, View convertView, ViewGroup parent){
// ... Your ViewHolder / Ringtone initialization
if(position == selectedPosition)
holder.btnPlay.setText("B");
else holder.btnPlay.setText("A");
holder.btnPlay.setOnClickListener(new View.OnClickListener(){
if(holder.btnPlay.getText().toString().equals("A"))
selectedPosition = position;
else selectedPosition = -1;
notifyDataSetChanged();
});
return convertView;
}
The key here is allowing notifyDataSetChanged() to internally call your getView method, which then really only needs to know how to render the data in its current state, instead of dealing with the complex logic required to map between multiple Views.
you need to reset the items which were not clicked,
btn.setText("B"); // if the item was clicked
btn.setText("A"); // for all other items
what you can do is, cycle through all elements setting the text for button like this btn.setText("A"), once this is done call btn.setText("B")
you should be using OnItemClickListener on the listview, it is easy that way, as you are setting the value in view holder, it does not give you access to the other items in the listview, but by using OnItemClickListener you can cover all the elements in the listview once you update things as you like call notifyDataSetChanged(), As this can be done there is another way to look at the problem
ListView listView = (ListView) findViewById(R.id.ListViewTestSevenActivity_listView);
ArrayList<Item> items = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Item item = new Item("A");
items.add(item);
}
MyAdapter adapter = new MyAdapter(getApplicationContext(), R.layout.simple_list_item_1, items);
listView.setAdapter(adapter);
This will take care of initialization and rest of the code as you want it to work. code is also available on github
private class MyAdapter extends ArrayAdapter {
private Context a_context;
private ArrayList<Item> items;
private LayoutInflater a_layoutInflater;
public MyAdapter(Context context, int resource, ArrayList<Item> items) {
super(context, resource, items);
this.a_context = context;
this.items = items;
a_layoutInflater = LayoutInflater.from(this.a_context);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = null;
if (row == null) {
row = a_layoutInflater.inflate(R.layout.single_item_listview_seven, parent, false);
holder = new ViewHolder();
holder.button = (Button) row.findViewById(R.id.ListViewTestSevenActivity_text_button);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
final Item item = items.get(position);
System.out.println("" + item.getText());
holder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (Item current_item : items) {
current_item.setText("A");
}
item.setText("B");
notifyDataSetChanged();
}
});
holder.button.setText("" + item.getText());
return row;
}
private class ViewHolder {
Button button;
}
}
private class Item {
String text;
public Item(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}

i have custom list view using adapter , in list view have two buttons one for make a phonecall secon one send SMS

When I click call button then make a phone call and contact number getting from JSON how add number to the button?
In your ListView adapter, bind the phone number to the call button using setTag and on the click of the call button get the phone number using getTag.
Provide any code. that you write so far. Don't ask for code next time. see Help
See for json example and customized listview and
adapter's code would be like this
public class ListAdapter extends BaseAdapter {
Context context;
ArrayList<String> phonenumbers = new ArrayList<>();
LayoutInflater inflater;
ArrayList<String> time = new ArrayList<>();
public ListAdapter(Context c, ArrayList<String> numbers) {
context = c;
phonenumbers = numbers;
inflater = LayoutInflater.from(this.context);
}
#Override
public int getCount() {
return phonenumbers.size();
}
#Override
public Object getItem(int i) {
return i;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(final int position, View v, ViewGroup viewGroup) {
final ViewHolder holder;
Button button = null;
TextView txtTime = null;
if (v == null) {
holder = new ViewHolder();
v = inflater.inflate(R.layout.listitem, null);
button = (Button) v.findViewById(R.id.buttoncall);
holder.buttonCall = button;
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.buttonCall.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Make you call here on this number
String numberToCall = phonenumbers.get(position);
//numberToCall is the clicked button's number
//you can make call now.
}
});
return v;
}
public static class ViewHolder {
public Button buttonCall;
}
}

Android - Remove GridView item from inside getView()?

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!

how to insert the data from the adapter to the listview

In my activity I have one adapter contains 25 items , and I have one listview. I want to insert 5 items in the listview and if I press the next button in my ativity ,the page will reloads with the next 5 items and so on.
Alter the items in the adapter, and then call notifyDataSetChanged() on the adapter.
adapter.clear();
adapter.addAll(nextFiveElements);
adapter.notifyDataSetChanged();
Also, be scrupulous about using the ViewHolder pattern. When implementing getView(), utilizing this design pattern will save a LOT of memory:
http://www.screaming-penguin.com/node/7767
you should not add all 25 items to the adapter unnecessarily. add five values only ;
static int pageNo. = 0 ;
final int pageSize = 5;
btn.onClick()
{
pageNo.+=;
for(int i = pageNo. ;i<pageN0. + pageSize;i++)
{
adapter.add(*i'th value*);
//modify syntext as per need
}
You have to maintain the position of the array
I have created a demo Adapter you can see
private static final int NO_OF_ITEMS_IN_PAGE = 5;
pivate static int currentPageNo = 0;
public class MyAdapter extends BaseAdapter {
ArrayList<String> arrNotes;
LayoutInflater inflater;
public MyAdapter(Context c, ArrayList<String> arrNotes) {
this.arrNotes = arrNotes;
inflater = ((Activity) c).getLayoutInflater();
}
#Override
public int getCount() {
return NO_OF_ITEMS_IN_PAGE;
}
#Override
public Object getItem(int position) {
int actualPosition = currentPageNo * NO_OF_ITEMS_IN_PAGE + position;
return arrTodaysMedicines.get(actualPosition);
}
#Override
public long getItemId(int arg0) {
return arg0;
}
#Override
public View getView(int position, View convertView, ViewGroup arg2) {
int actualPosition = currentPageNo * NO_OF_ITEMS_IN_PAGE + position;
String strNote = arrNotes.get(actualPosition);
if(convertView == null) {
convertView = inflater.inflate(R.layout.note_list, null);
}
TextView tvTitle =
(TextView) convertView.findViewById(R.id.tvTitle);
tvTitle.setText(strNote);
return convertView;
}
}

Android - Having problem while deleting items from ListView?

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

Categories

Resources