I am having a problem with a clickListener on my gridview. The LongClickListener works without issue. But I cannot seem to get any response from the click Listener.
My code is below.
Im confused as to why the long click works but not the normal click,
Any pointers would be appreciated
Thanks
final GridView gridView = (GridView) findViewById(R.id.grid_view);
gridView.setNumColumns(numOfColumns);
gridView.getLayoutParams().width = (CELL_WIDTH * numOfColumns);
gridView.getLayoutParams().height = (CELL_WIDTH * numOfRows);
....
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Log.d("ABCD", "Position Single Click is " + position);
// Ideally in here I want to put to open a soft keyboard for the user to enter a value
// InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
// imm.showSoftInput(gridView, InputMethodManager.SHOW_IMPLICIT);
}
});
gridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Log.d("ABCD", "Position Long Click is " + position);
return true;
}
});
grid_view is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="horizontal">
<View
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"/>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/my_grid_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"/> <<--- I WANT THIS TO GET THE CLICK
<View
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"/>
</LinearLayout>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/listId"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />
</LinearLayout>
GridCell in the grid view is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:padding="0dp" android:layout_margin="0dp"
android:focusable="false"
android:clickable="false"
android:focusableInTouchMode="false"
>
<TextView
android:id="@+id/grid_item_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="1dp"
android:paddingRight="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:textSize="10px"
android:focusable="false"
android:clickable="false"
android:focusableInTouchMode="false"
>
</TextView>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/grid_item_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@+id/celllabel"
android:background="@android:color/transparent"
android:paddingLeft="5dp"
android:paddingRight="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:layout_margin="0dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
android:cursorVisible="false">
</EditText>
</RelativeLayout>
The adapter class has a getView and is as below
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
MyObject obj = myObjects.get(position);
if (convertView == null) {
gridView = inflater.inflate(R.layout.grid_cell, null);
String textColour = "#000000";
TextView textView = (TextView) gridView.findViewById(R.id.grid_item_label);
textView.setText(Html.fromHtml(String.format("<font color='%s'>%s</font>", textColour, obj.getValue())));
TextView superScriptTv = (TextView) gridView.findViewById(R.id.grid_item_number);
if (obj.getNumber() > 0) {
superScriptTv.setText(Html.fromHtml(String.format("<font>%s</font>", cell.getNumber())));
}
} else {
gridView = convertView;
}
gridView.setBackgroundColor(obj.getBackgroundColour());
return gridView;
}
EDIT Really banging my head against a wall here now :) Im updating the code sample so have more data. Ive noticed that in my adapter if I do not set the text on the textview with ID = R.id.grid_item_number then it works. As soon as I set text on it then I lose the click listener.
The linked question/answer doesnt help from what I can see. Can anyone help with my stupidity?
EDIT Adapter code has been added.
Thanks in advance.
The problem is with the EditText
inside the row_cell
. When you click on the item, it takes focus and prevents the whole item to be clickable again. As you noticed, only long click works.
Here you have a similar problem.
To resolve that issue I would move your OnItemClickListeners
from the Activity / Fragment to your GridViewAdapter
, so instead of:
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Log.d("ABCD", "Position Single Click is " + position);
// Ideally in here I want to put to open a soft keyboard for the user to enter a value
// InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
// imm.showSoftInput(gridView, InputMethodManager.SHOW_IMPLICIT);
}
});
gridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Log.d("ABCD", "Position Long Click is " + position);
return true;
}
});
I would do something like that:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridViewItem;
if (convertView == null) {
gridViewItem = new View(mContext);
gridViewItem = layoutInflater.inflate(R.layout.grid_cell, null);
TextView textView = (TextView)gridViewItem.findViewById(R.id.grid_item_number);
textView.setText(mValues[position]);
EditText editText = (EditText)gridViewItem.findViewById(R.id.grid_item_label);
} else {
gridViewItem = (View) convertView;
}
gridViewItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("GRID", "onClick: " );
}
});
gridViewItem.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Log.e("GRID", "onLongClick: " );
return true;
}
});
return gridViewItem;
}
It will prevent this strange behaviour you are struggling right now.
For the sake of that example please find my code below:
MainActivity layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="io.github.mmbs.gridviewcheck.MainActivity"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="0dp">
<GridView
android:id="@+id/gridView"
android:numColumns="auto_fit"
android:columnWidth="100dp"
android:stretchMode="columnWidth"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true">
</GridView>
</android.support.constraint.ConstraintLayout>
Grid cell layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:padding="8dp">
<TextView
android:id="@+id/grid_item_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="0dp"
android:paddingLeft="1dp"
android:paddingRight="0dp"
android:paddingTop="0dp"
android:textSize="20sp"
android:text="TEXTVIEW">
</TextView>
<EditText
android:id="@+id/grid_item_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:background="@android:color/transparent"
android:cursorVisible="false"
android:layout_below="@id/grid_item_number"
android:text="EDITTEXT">
</EditText>
</RelativeLayout>
Please take into consideration, that I removed all layouts attributes responsible for focusability
.
MyGridAdapter:
public class MyGridViewAdapter extends BaseAdapter {
private Context mContext;
private final String[] mValues;
public MyGridViewAdapter(String[] values, Context context) {
mValues = values;
mContext = context;
}
@Override
public int getCount() {
return mValues.length;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridViewItem;
if (convertView == null) {
gridViewItem = new View(mContext);
gridViewItem = layoutInflater.inflate(R.layout.grid_cell, null);
TextView textView = (TextView)gridViewItem.findViewById(R.id.grid_item_number);
textView.setText(mValues[position]);
EditText editText = (EditText)gridViewItem.findViewById(R.id.grid_item_label);
} else {
gridViewItem = (View) convertView;
}
gridViewItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("GRID", "onClick: " );
}
});
gridViewItem.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Log.e("GRID", "onLongClick: " );
return true;
}
});
return gridViewItem;
}
}
If you like, I can also share this code on github, so you will have a fully operational example.
The second option is to leave your implementation as it is and do hacks when the EditText
is focusable and enabled. Here you have related topics:
What is more, please take into account that answer:
Do not use clickable objects in the grid. In that case Android cannot handle the click event of GridView.
Instead, use something to show a similar user interface view. Then handle that object's click actions.
Don't: put Button in the GridView to perform some click actions.
Do: put an ImageView instead of ImageButton and handle ImageView's click events.
Edit: Please find a link to the project on my Github.
use gridView.setOnItemClickListener(.....)
and to your root view add below line
android:descendantFocusability="blocksDescendants"
The ViewGroup will block its descendants from receiving focus.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With