ListView personnalisé et menu contextuel. Comment l'obtenir?
J'ai deux mises en page des fichiers dans mon application. J'ai également une Activité extends ListActivity. Chaque élément de cette activité semble considérer item.xml fichier de mise en page. Je vais essayer d'aller menu contextuel lorsque faire de longues presss sur les articles, mais je ne le vois pas.
Dans mon activité j'ai essayer de registerForContextMenu(getListView()) et de remplacer les deux méthodes
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = this.getIntent().getExtras();
registerForContextMenu(getListView());
new PopulateAdapterTask().execute(ACTION_SELECT);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info;
try {
info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
} catch (ClassCastException e) {
return false;
}
long id = getListAdapter().getItemId(info.position);
Log.d(TAG, "id = " + id);
return true;
}
Main.xml
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp">
<ListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</FrameLayout>
</LinearLayout>
</TabHost>
Item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="15sp"
android:singleLine="true"
android:ellipsize="marquee"
android:scrollHorizontally = "true"
android:maxWidth="200dp"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="right"
>
<ImageButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:background="@null"
android:paddingRight="10dp"
android:paddingLeft="10dp"
/>
</LinearLayout>
</LinearLayout>
Tout cela ne fonctionne pas. Peut-être la raison en est dans LinearLayout? J'ai aussi trouver de sujet similaire Android: menu Contextuel ne s'affiche pas pour ListView avec des membres définis par LinearLayout? mais je n'ai plus compliqué élément de la liste.
Comment obtenir le menu contextuel dans mon cas?
Aussi dans mon activité, j'ai intérieure s'étend ArrayAdapter. Dans cette catégorie, dans la méthode getView je peux mettre OnCreateContextMenuListener sur chaque Vue, après que le menu contextuel s'affiche, mais je ne sais pas comment faire pour gérer des éléments clics. Si j'essaie de le faire dans la méthode onContextItemSelected, point.getMenuInfo() de l'objet est toujours nulle et je n'arrive pas à obtenir quelques informations.
private class ChannelAdapter extends ArrayAdapter<Channel> {
private List<Channel> channels;
public ChannelAdapter(Context context, int textViewResourceId, List<Channel> objects) {
super(context, textViewResourceId, objects);
this.channels = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.station_item, null);
}
v.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
});
Grâce. De l'espoir pour votre aide.
source d'informationauteur Georgy Gobozov
Vous devez vous connecter pour publier un commentaire.
Segments suivants du code de classe imbriquée ComplexObjectAdapter, inscrite dans Georgy Gobozov réponse, ne sont pas vraiment nécessaires:
Il fonctionne, tout simplement parce que l'intérieur de la fonction setOnCreateContextMenuListener() de la classe Vue, il appelle la fonction setLongClickable(vrai):
Cela signifie que le problème peut être résolu en définissant le Long Cliquable propriété pour chaque enfant, et après il est créé:
ou il peut également être résolu en définissant cette propriété dans le fichier XML du fichier de mise en page de l'affichage de la liste des éléments d'enfant, par exemple:
En fait, vous avez juste besoin de faire voir à long cliquable en appelant
Il n'est pas nécessaire de définir mannequin
setOnCreateContextMenuListener
parce que c'est n'est que de l'ensemble de l'élément de long cliquable.Je ne pense pas que vous voulez joindre un menu contextuel spécifique des éléments listView. En appelant registerForContextMenu(getListView ()), vous devriez obtenir cette fonctionnalité gratuitement. Je voudrais brancher votre application jusqu'à un débogueur après la suppression de la contextMenu crochets à partir de la carte de code et de définir un point d'arrêt à l'intérieur de onCreateContextMenu(). Mon soupçon est que ça s'appelle, mais la mise en page qui est gonflé n'est pas ce que vous attendez.
Le problème de base est que l'élément est en cours d'élaboration par le deuxième item.xml mise en page - si l'élément racine (LinearLayout) est ce qui est long pressé, plutôt que ce que l'original ListView fourni. Ainsi, lorsque vous gonflez le item.xml mise en page, vous devez appeler le setOnCreateContextMenuListener que vous avez fait dans le deuxième exemple. Le problème, c'est qu'il n'existe aucun moyen pour la mise en page de item.xml (qui est un LinearLayout) à communiquer à l'Activité pour laquelle la position a été choisi. C'est parce que le LinearLayout ne remplace pas le getContextMenuInfo() méthode qui dans une liste renvoie une AdapterView.AdapterContextMenuInfo (comme tout le monde semble forcer leurs ContextMenuInfo).
Donc, idéalement, vous voulez créer votre propre LinearLayout descendant qui fait la getContextMenuInfo public, crée un faux, si il n'y a pas là, et quand onCreateContextMenu est appelée dans votre adaptateur personnalisé, il l'attrape à partir de votre personnalisé LinearLayout et met la position/l'id de là, votre activité peut s'en retirer.
C'est ce que j'ai fait dans ma propre application et il fonctionne très bien et est une solution générique - vous pouvez mettre ce que vous voulez, en tant qu'il met en œuvre la ContextMenuInfo de l'interface (qui est juste un marqueur de l'interface).
Je n'ai pas maintenant pourquoi, il est nécessaire de définir une valeur null OnCreateContextMenuListener sur chaque ligne de liste (en plus de registerForContextMenu(...) et de mettre en œuvre onCreateContextMenu(...) et onContextItemSelected(...)