【问题标题】:OnItemClickListener not working but OnItemLongClickListener is working on GridViewOnItemClickListener 不工作,但 OnItemLongClickListener 在 GridView 上工作
【发布时间】:2016-09-07 23:04:52
【问题描述】:

我的 gridview 上的 clickListener 出现问题。 LongClickListener 可以正常工作。但我似乎无法从点击监听器中得到任何响应。

我的代码如下。

我很困惑为什么长按有效但正常点击无效,

任何指针将不胜感激

谢谢

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 是

<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是

<?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>

适配器类有一个getView,如下

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

编辑 现在真的把我的头撞到墙上了:) 我正在更新代码示例,因此有更多数据。我注意到在我的适配器中,如果我没有在 ID = R.id.grid_item_number 的 textview 上设置文本,那么它就可以工作。一旦我在上面设置文本,我就会失去点击监听器。

链接的问题/答案对我所看到的没有帮助。谁能帮助我的愚蠢?

编辑 已添加适配器代码。

提前致谢。

【问题讨论】:

  • 检查这个问题/答案:stackoverflow.com/questions/5982472/…
  • 能否请您发布 GridCell 的完整 xml 代码?
  • 你能在适配器中分享你的代码吗
  • 嗨@ankitaggarwal 我刚刚从适配器类中添加了getView。如果您需要更多代码,请告诉我。感谢观看
  • 您是否同时使用both?即使您删除了 onLongClickListener,onClickListener 是否也无法正常工作?

标签: android gridview onitemclicklistener


【解决方案1】:

问题在于row_cell 中的EditText。当您单击该项目时,它会获得焦点并防止整个项目再次被单击。正如您所注意到的,只有长按有效。 Here you have a similar problem.

为了解决该问题,我会将您的 OnItemClickListeners 从 Activity / Fragment 移至您的 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?

还有,请关注that answer:

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

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

不要:将Button放在GridView中执行一些点击动作。

做:放置一个ImageView而不是ImageButton并处理ImageView的点击事件。

编辑:请找link to the project on my Github

【讨论】:

  • 感谢@mmBs 的非常全面的回答!将在第二天左右检查。
  • 今晚我会检查这个@mmBs。
  • 嗨@mmBs。它似乎不起作用,我认为这是因为 textView/EditText 部分位于彼此下方。我看到 android:layout_below="@id/grid_item_number"。对于我的代码,它们实际上是相互重叠的。我认为你肯定让我更接近,但会继续更多。似乎当我点击 TextView 部分时,我接到了电话,但是当我点击 EditText 部分时,它没有通过
  • 我现在可能要求更多;)但理想情况下,我想在点击时打开一个键盘。我试图用打开的键盘代码替换调试代码,但这也不起作用。感谢您迄今为止的帮助
  • 嗨@RNJ,问题是在没有所有代码的情况下很难重新创建/重现您的问题。这就是我创建自己的项目并开始实验的原因。您写道,您的TextViewEditText 彼此重叠。所以也许是这样。例如,您可以更改您的grid_cell 布局并进行一些实验吗?更重要的是,您没有在grid_cellRelativeLayout 中添加layout_widthlayout_height 属性。顺便说一句,我认为您也可以使用 RecyclerView 并替换您的 GridViewListView :)
【解决方案2】:

使用gridView.setOnItemClickListener(.....) 到您的根视图添加以下行

android:descendantFocusability="blocksDescendants"

ViewGroup 将阻止其后代接收焦点。

【讨论】:

    【解决方案3】:

    尝试添加

    android:focusable="false"
    android:focusableInTouchMode="false"
    

    在你的 GridCell -->TextView

    【讨论】:

      【解决方案4】:

      如果您觉得合适,请尝试使用回收站视图。

      除此之外它没有任何此类问题。它有自己的优势。

      关注link了解完整说明。

      【讨论】:

        【解决方案5】:

        如果您的行布局中有任何可聚焦的视图,则不会调用 onItemClickListener。对于这个问题,您需要自定义 getView 代码并在 convertView 上设置 onClickListener() 并使用接口将回调传递给活动。我已经更新了您的适配器的代码,如下所示。现在您需要在 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);
        }
        }
        

        【讨论】:

          【解决方案6】:

          您可以在适配器内使用用户单击侦听器,它将工作,它应该像这样工作

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

          【讨论】:

            【解决方案7】:

            如果将 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"

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-11-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-02-25
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多