OnItemClickListener无法正常工作,但OnItemLongClickListener正在使用GridView

时间:2016-05-12 08:30:55

标签: android gridview onitemclicklistener

我在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上设置文本,那么它可以工作。一旦我在其上设置文本,我就会丢失点击监听器。

链接的问题/答案对我所看到的内容没有帮助。任何人都可以帮助我的愚蠢吗?

修改 已添加适配器代码。

提前致谢。

6 个答案:

答案 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可关注并启用时执行黑客攻击。在这里您有相关主题:

  1. Android: Force EditText to remove focus?
  2. ListView items focus behaviour
  3. Focusable EditText inside ListView
  4. Android: Force EditText to remove focus?
  5. 更重要的是,请考虑that answer:

      

    不要在网格中使用可点击的对象。在这种情况下,Android无法处理GridView的click事件。

         

    相反,使用某些东西来显示类似的用户界面视图。然后处理该对象的点击操作。

         

    不要:在GridView中放置Button来执行一些点击操作。

         

    执行:放置ImageView而不是ImageButton并处理ImageView的点击事件。

    修改:请找link to the project on my Github

答案 1 :(得分:2)

尝试添加

android:focusable="false"
android:focusableInTouchMode="false"
你的GridCell中的

- &gt; TextView

答案 2 :(得分:1)

如果您对此感到满意,请尝试使用回收站视图。

除此之外,它没有给出任何此类问题,它有其自身的优势。

关注link以获取完整说明。

答案 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;
}