2016-05-12 18 views
10

Ich habe ein Problem mit einem clickListener in meiner Gridview. Der LongClickListener funktioniert ohne Probleme. Ich kann jedoch keine Antwort vom Klick-Listener erhalten.OnItemClickListener funktioniert nicht, aber OnItemLongClickListener funktioniert auf GridView

Mein Code ist unten. Im

verwirrt, warum die langen Klick funktioniert, aber nicht die normale Klick,

Alle Zeiger würde

Dank

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; 
     } 
}); 
geschätzt werden

grid_view ist

<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 der Rasteransicht ist

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

Der Adapter-Klasse hat eine getView und wie unten

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 wirklich meinen Kopf gegen eine Wand hämmern hier jetzt :) Im das Codebeispiel zu aktualisieren, um mehr Daten haben. Ich habe bemerkt, dass in meinem Adapter, wenn ich den Text nicht auf die Textansicht mit ID = R.id.grid_item_number setzen, dann funktioniert es. Sobald ich Text darauf setze, verliere ich den Klick-Listener.

Die verknüpfte Frage/Antwort hilft nicht von dem, was ich sehen kann. Kann mir jemand mit meiner Dummheit helfen?

BEARBEITEN Adaptercode wurde hinzugefügt.

Vielen Dank im Voraus.

+0

prüft diese Frage/Antwort aus: http://stackoverflow.com/questions/5982472/gridview-onitemclicklistener-never-gets-invoked –

+0

Können Sie bitte für Gridcell kompletten XML-Code schreiben? – Harsh4789

+0

können Sie Ihren Code in Adapter –

Antwort

8

Das Problem ist mit der EditText innerhalb der row_cell. Wenn Sie auf das Objekt klicken, wird der Fokus aktiviert und verhindert, dass das gesamte Objekt erneut angeklickt werden kann. Wie Sie bemerkt haben, funktioniert nur ein langer Klick. Here you have a similar problem.

Um dieses Problem zu beheben Ich würde Ihre OnItemClickListeners von der Aktivität/Fragmente zu Ihrem GridViewAdapter bewegen, so statt:

@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:

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

ich so etwas tun würde, wird dieses seltsame Verhalten verhindern, das du gerade hast.

Aus Gründen der diesem Beispiel finden Sie in meinem Code unten finden:

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

berücksichtigen Bitte, dass ich alle entfernt Layoutattribute verantwortlich für 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; 

} 
} 

Wenn Sie möchten, kann ich auch auf GitHub diesen Code teilen, so dass Sie ein voll funktionsfähiges Beispiel haben wird.

Die zweite Option besteht darin, Ihre Implementierung so zu lassen, wie sie ist, und Hacks auszuführen, wenn die EditText fokussierbar und aktiviert ist. Hier haben Sie mit ähnlichen Themen:

  1. Android: Force EditText to remove focus?
  2. ListView items focus behaviour
  3. Focusable EditText inside ListView
  4. Android: Force EditText to remove focus?

Was mehr ist, beachten Sie bitte, that answer:

Verwenden Sie keine anklickbaren Objekte im Raster. In diesem Fall kann Android das Click-Ereignis von GridView nicht verarbeiten.

Verwenden Sie stattdessen etwas, um eine ähnliche Benutzeroberfläche anzuzeigen. Behandeln Sie dann die Klickaktionen dieses Objekts.

Nicht: Setzen Sie Button in die GridView, um einige Klickaktionen durchzuführen.

Do: Setzen Sie ImageView anstelle von ImageButton und behandeln Sie ClickView-Ereignisse von ImageView.

Bearbeiten: Finden Sie eine link to the project on my Github.

+0

danke @mmBs für die sehr umfassende Antwort! Wird dies am nächsten Tag oder so überprüfen. – RNJ

+0

Ich überprüfe das heute Abend @ mmBs. – RNJ

+0

Hallo @ mmBs. Es scheint nicht zu funktionieren und ich denke, das liegt daran, dass der textView/EditText Teil untereinander liegt. Ich sehe Android: layout_below = "@ id/grid_item_number". Für meinen Code sind sie eigentlich übereinander. Ich denke, du hast mich definitiv näher gebracht, aber es wird noch ein bisschen weitergehen. Es scheint, dass, wenn ich auf den TextView-Teil klicke, dann bekomme ich den Anruf, aber wenn ich auf den EditText Teil klicke, kommt es nicht durch – RNJ

2

Try

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

in Ihrem Gridcell hinzufügen -> Textview

3

Verwendung gridView.setOnItemClickListener(.....)und zu Ihrer Stammansicht unterhalb der Linie hinzufügen

android:descendantFocusability="blocksDescendants" 

Der Viewgroup blockiert seine Nachkommen erhalten den Fokus.

happyCoding;

1

Versuchen Sie die Recycler-Ansicht zu verwenden, wenn Sie sich damit auskennen.

Es gibt kein solches Problem, zusätzlich hat es seine eigenen Vorteile.

Folgen Sie der link für eine vollständige Erklärung.

1

Wenn Sie in Ihrem Zeilenlayout eine fokussierbare Ansicht haben, wird der onItemClickListener nicht aufgerufen. Für dieses Problem müssen Sie Ihren getView-Code anpassen und onClickListener() in convertView festlegen und den Callback über die Schnittstelle an Aktivitäten übergeben. Ich habe den Code Ihres Adapters wie folgt aktualisiert. Jetzt müssen Sie den GridViewItemClickListener für Ihre Aktivität implementieren und die Instanz übergeben, während Sie die Adapter-Instanz erstellen.

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

Wie funktioniert der Klick-Listener, wenn Sie das Stammelement in GridCell.java als nicht anklickbar festlegen?

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

diese Zeilen aus jedem Ihrer Komponenten in der GridCell.java

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

ich entfernen glaube nicht, das für Gridview erforderlich ist, aber manchmal für RecyclerView ist es erforderlich, Android haben: anklickbare = „true“ auf der Wurzel componenent von GridCell.java

1

Sie können innerhalb des Adapters Benutzer klicken Zuhörer es funktionieren wird, sollte es so funktionieren

öffentlichen Vi ew getView (letzte 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; 
} 
Verwandte Themen