我在gridview上遇到clickListener问题。 LongClickListener可以正常工作。但我似乎无法从点击监听器获得任何响应。
我的代码如下。
我很困惑为什么长按不起作用而不是正常点击,
任何指针都将不胜感激
由于
elements.select { |e| e[:street_address].downcase! !~ /pl/ && e[:street_address].downcase! !~ /cres/ && e[:street_address].downcase! !~ /ave/ }
#=> [
# {:id=>"1", :street_address=>"1 northburn rd", :town=>"WANAKA", :valuation_date=>"1/1/2015", :value=>"280000"},
# {:id=>"3", :street_address=>"1 mount linton ave", :town=>"WANAKA", :valuation_date=>"1/1/2015", :value=>"780000"},
# {:id=>"4", :street_address=>"1 centre cres", :town=>"WANAKA", :valuation_date=>"1/1/2015", :value=>"295000"}
# ]
grid_view是
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;
}
});
网格视图中的GridCell是
<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>
适配器类有一个getView,如下所示
<?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>
修改 现在真的把我的头撞在墙上:) 我更新代码示例,以便有更多的数据。我注意到在我的适配器中,如果我没有在ID = R.id.grid_item_number的textview上设置文本,那么它可以工作。一旦我在其上设置文本,我就会丢失点击监听器。
链接的问题/答案对我所看到的内容没有帮助。任何人都可以帮助我的愚蠢吗?
修改 已添加适配器代码。
提前致谢。
答案 0 :(得分:9)
问题在于EditText
内的row_cell
。当您单击该项目时,它将获得焦点并防止整个项目再次可单击。如您所见,只需长按即可。
Here you have a similar problem.
要解决该问题,我会将您的OnItemClickListeners
从活动/片段移至您的GridViewAdapter
,而不是:
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;
}
});
我会做那样的事情:
@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;
}
它可以防止你现在正在努力的这种奇怪的行为。
为了这个例子,请在下面找到我的代码:
MainActivity布局:
<?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>
网格单元布局:
<?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>
请注意,我删除了负责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;
}
}
如果您愿意,我也可以在github上共享此代码,因此您将拥有一个完全可操作的示例。
第二个选项是保持实施不变,并在EditText
可关注并启用时执行黑客攻击。在这里您有相关主题:
更重要的是,请考虑that answer:
不要在网格中使用可点击的对象。在这种情况下,Android无法处理GridView的click事件。
相反,使用某些东西来显示类似的用户界面视图。然后处理该对象的点击操作。
不要:在GridView中放置Button来执行一些点击操作。
执行:放置ImageView而不是ImageButton并处理ImageView的点击事件。
答案 1 :(得分:2)
尝试添加
android:focusable="false"
android:focusableInTouchMode="false"
你的GridCell中的- &gt; TextView
答案 2 :(得分:1)
答案 3 :(得分:1)
如果您的行布局中有任何可聚焦的视图,则不会调用onItemClickListener。对于此问题,您需要自定义getView代码并在convertView上设置onClickListener()并使用Interface将回调传递给activity。我已经更新了适配器的代码,如下所示。现在,您需要在活动上实现GridViewItemClickListener,并在创建Adapter实例时传递实例。
public class MyGridViewAdapter extends BaseAdapter {
private Context mContext;
private final String[] mValues;
private GridViewItemClickListener mListener;
public MyGridViewAdapter(String[] values, Context context,GridViewItemClickListener listener ) {
mValues = values;
mContext = context;
mListener = listener;
}
@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(final 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.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Log.e("GRID", "onLongClick: " );
return true;
}
});
//Add an OnclickListener here
gridViewItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mListener != null){
mListener.onGridItemClick(v, position);
}
}
});
return gridViewItem;
}
public interface GridViewItemClickListener{
void onGridItemClick(View v, int index);
}
}
答案 4 :(得分:1)
如果将GridCell.java中的根元素设置为不可点击,那么点击侦听器如何工作?
<?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"
从GridCell.java中的每个组件中删除这些行
android:focusable="false"
android:clickable="false"
android:focusableInTouchMode="false"
我认为这不是GridView所必需的,但有时对于RecyclerView,它需要在GridCell.java的根组件上安装android:clickable =“true”
答案 5 :(得分:1)
您可以在适配器内部点击监听器,它可以正常工作,它应该像这样工作
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);
superScriptTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// here you can use every item of grid acc to position
}
});
if (obj.getNumber() > 0) {
superScriptTv.setText(Html.fromHtml(String.format("<font>%s</font>", cell.getNumber())));
}
} else {
gridView = convertView;
}
gridView.setBackgroundColor(obj.getBackgroundColour());
return gridView;
}