Android - Gridview with custom BaseAdapter, create onclicklistener

I created a grid that displays the letters of the alphabet. I populate the gridview array of strings using a custom BaseAdapter.

What I want to do is get the value (letter) of the clicked cell. To make sure that it works, I created a TextView, and I want when the user clicks on an element (cell) to set the TextView text with the value of the selected cell

enter image description here

I made an attempt that does not work. Here is my code:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" tools:ignore="MergeRootFrame" > <GridView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/myGridView" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:numColumns="7" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Large Text" android:id="@+id/feedback" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" /> </RelativeLayout> 

cell.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"> <Button android:id="@+id/grid_item" android:layout_gravity="center" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="05" android:textSize="20sp" android:enabled="true" android:clickable="true"> </Button> </LinearLayout> 

Mainactivity

 public class MainActivity extends Activity { private TextView text; private GridView gridView; private final String[] items = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text = (TextView) findViewById(R.id.feedback); gridView = (GridView) this.findViewById(R.id.myGridView); CustomGridAdapter gridAdapter = new CustomGridAdapter(MainActivity.this, items); gridView.setAdapter(gridAdapter); gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { text.setText((String) (gridView.getItemAtPosition(position))); Log.i("ITEM_CLICKED", "" + (String) (gridView.getItemAtPosition(position))); } }); } } 

CustomGridAdapter

 public class CustomGridAdapter extends BaseAdapter { private Context context; private String[] items; LayoutInflater inflater; public CustomGridAdapter(Context context, String[] items) { this.context = context; this.items = items; inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = inflater.inflate(R.layout.cell, null); } Button button = (Button) convertView.findViewById(R.id.grid_item); button.setText(items[position]); return convertView; } @Override public int getCount() { return items.length; } @Override public Object getItem(int position) { return items[position]; } @Override public long getItemId(int position) { return position; } } 

What am I doing wrong?

Change It seems that gridView.setOnItemClickListener (...); not called / not executed. I changed it to this to test it, and I can not see anything in logcat.

 gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Log.i("ON_ITEM_CLICK_LISTENER", "item clicked"); } }); 
+7
android gridview baseadapter onclicklistener
source share
3 answers

The problem in your case is that the button uses a click and it does not get into the GridView. I see two options:

  • Easy: in cell.xml there are these properties for Button : android:clickable="false" and android:focusable="false"
  • Gross-mode: send the Activity parameter as a parameter to the adapter and derive the public method from MainActivity . If you are thinking of reusing the adapter, then submit an abstract activity type or interface.

Something like:

 public class MainActivity extends Activity { private TextView text; private GridView gridView; private final String[] items = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text = (TextView) findViewById(R.id.feedback); gridView = (GridView) this.findViewById(R.id.myGridView); CustomGridAdapter gridAdapter = new CustomGridAdapter(MainActivity.this, items); gridView.setAdapter(gridAdapter); } public void itemClicked(int position) { text.setText(items[position]); } } 

and in your adapter:

 public class CustomGridAdapter extends BaseAdapter { private MainActivity context; private String[] items; LayoutInflater inflater; public CustomGridAdapter(MainActivity context, String[] items) { this.context = context; this.items = items; inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } public View getView(final int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = inflater.inflate(R.layout.cell, null); } Button button = (Button) convertView.findViewById(R.id.grid_item); button.setText(items[position]); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { context.itemClicked(position); } }); return convertView; } @Override public int getCount() { return items.length; } @Override public Object getItem(int position) { return items[position]; } @Override public long getItemId(int position) { return position; } } 
+5
source share

Actually for gridview setOnItemClickListener you are not doing anything wrong. This is the kind of cell that creates the problem. Try changing the cell screen button to a text box, it should work. Right now, when you click on an element in a gridview, the element is not actually clicked because your cell view button has its own implementation of OnClickListener, and that is why setOnItemClickListener does not receive the call.

+3
source share

You can use setTag () adnd getTag (), which allows you to place / receive objects of any type. Thus, in the future you will be able to convey anything (if you make the appropriate throw after)

 public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = inflater.inflate(R.layout.cell, null); } Button button = (Button) convertView.findViewById(R.id.grid_item); button.setText(items[position]); convertView.setTag(items[position]); return convertView; } 

and

 gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String str = (String) view.getTag(); text.setText(str); Log.i("ITEM_CLICKED", "" + (String) (gridView.getItemAtPosition(position))); } }); 
0
source share

All Articles