2013-06-19 12 views
7

Die Herausforderung, ein GestureDetector einen ListPreference Befestigung ist 2-fach:Wie wird GestureDetector an eine ListPreference angehängt?

  1. einen Griff an einen ListPreference bekommen, die nur in einem preferences.xml definiert ist (das heißt nicht in Java-Code instanziiert).
  2. ListPreference ist weder eine View- noch eine Activity-Unterklasse.

Ist es überhaupt möglich, eine GestureDetector an eine ListPreference anzuschließen?

Wenn ja, wie würde man darüber gehen? Wo würde ich den Code schreiben, um GestureDetector zu instantiieren und den Listener zu implementieren?

+2

Könnten Sie mir bitte sagen, was das Hauptziel dieser Implementierung ist - was ist das erwartete Ergebnis und wofür wird der 'GestureDetector' verwendet? – g00dy

+0

@ g00dy Alles, was ich von diesem Punkt abbekomme, ist ein langes Drücken auf einen beliebigen Gegenstand in der Liste (und natürlich den Index des Gegenstandes, der lange gedrückt wurde). – scatmoi

Antwort

4

Wenn ich die Frage nicht richtig verstanden habe, ist die Antwort wahrscheinlich einfacher, als Sie vielleicht denken. Der Quellcode für ListPreferece lehrt, dass es wenig mehr als ein Wrapper um einen AlertDialog ist, der seine verschiedenen Optionen in einem ListView anzeigt. Jetzt, AlertDialog können Sie tatsächlich einen Griff auf die ListView es Wraps bekommen, die wahrscheinlich alles ist, was Sie brauchen.

In einem der Kommentare haben Sie angegeben, dass Sie in diesem Stadium nur einen langen Druck auf ein beliebiges Element in der Liste erkennen möchten. Anstatt also mit GestureDetector zu antworten, benutze ich einfach einen OnItemLongClickListener.

public class ListPreferenceActivity extends PreferenceActivity implements OnPreferenceClickListener { 

    private ListPreference mListPreference; 

    @Override protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     addPreferencesFromResource(R.xml.list_prefs); 

     mListPreference = (ListPreference) findPreference("pref_list"); 
     mListPreference.setOnPreferenceClickListener(this); 
    } 

    @Override 
    public boolean onPreferenceClick(Preference preference) { 
     AlertDialog dialog = (AlertDialog) mListPreference.getDialog(); 
     dialog.getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { 
      @Override public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) { 
       Toast.makeText(getApplicationContext(), "Long click on index " + position + ": " 
         + parent.getItemAtPosition(position).toString(), Toast.LENGTH_SHORT).show(); 
       return false; 
      } 
     }); 
     return false; 
    } 

} 

Das Ergebnis (die der Toast auf lange Klick Anzeigen):

enter image description here

Mit einem Verweis auf die ListView, können Sie auch ein OnTouchListener, befestigen GestureDetector usw. Bis zu Ihnen von hier zu gehen.

+0

Ja, Sie haben die Frage richtig verstanden. :-) +1, Akzeptieren und Belohnen des Bonus. Nun ... gibt es eine Chance, dass die Besetzung von '(AlertDialog)' nicht funktioniert ** in einigen Android-Version/Flavor/Distro/Anpassung? – scatmoi

+0

@scatmoi: Die Umwandlung sollte für alles sicher sein, was von 'DialogPreference' ausgeht, da dies die Erweiterung der Klassen erzwingt, um den' Dialog' mit 'onPrepareDialogBuilder (Builder für AlertDialog.Builder) 'zu erstellen. Ich habe mich kurz umgeschaut und 'ListPreference' hat das vertraglich auf mindestens Android 1.5 (Cupcake) reduziert. In der Tat hat sich 'ListPreference' im Laufe der Jahre kaum verändert ... Wie auch immer, nur aus Vernunftgründen würde es nicht schaden, vor der Besetzung eine' instanceof'-Prüfung hinzuzufügen. :) –

0

Ich habe zuvor einen GestrueDetector auf eine ScrollView mit setOnTouchListener gesetzt und nach einer ähnlichen Methode für ListPreference gesucht, aber da die ListPreference keine solche Methode enthält, glaube ich nicht, dass dies möglich ist.

+2

Der Kernpunkt der Herausforderung hier ist, dass 'ListPreference' ** ist ** eine Ansicht, aber es ist nicht definiert in einem Layout XML und somit nicht über [findViewById()] (http: // stackoverflow. com/q/17192066/1088880). Oder kann es? Ich fange an zu denken, dass der einzige Weg dahin ist, eine Unterklasse von ListPreference zu definieren und zu verwenden, dann in ihrem 'onCreate()', [setOnTouchListener()] (http://developer.android.com/reference/android/ view/View.html # setOnTouchListener (android.view.View.OnTouchListener)). – scatmoi

+0

Sie können möglicherweise ein 'getView(). SetOnTouchListener()' tun. Nicht sicher, wie genau. – TronicZomB

1

Wie @TronicZomB vorgeschlagen, ist dies nicht direkt möglich.

Sie können dies umgehen, indem Sie Ihre eigene ListPreference-abgeleitete Klasse erstellen und ihre Ansicht in der geerbten onBindDialogView() abrufen.

Beachten Sie jedoch, dass letzteres schwierig ist, da onBindDialogView() nur aufgerufen wird, wenn onCreateDialogView() nicht null zurückgibt, und dies kann nur passieren, wenn Sie Ihre eigene benutzerdefinierte Ansicht für YourListPreference erstellen.

Die empfohlene Vorgehensweise ist build a custom Preference.

Sobald Sie dies getan haben, haben Sie einen Verweis auf die Ansicht von YourListPreference, die für das Anfügen von GestureDetector erforderlich ist, da einer der Schritte setOnTouchListener() für die Ansicht erfordert.

+0

Ihre Methode funktioniert möglicherweise, aber es ist zu umständlich. @ MH. Ansatz ist eleganter (aber ich weiß nicht, ob es mit zukünftigen Android-Versionen kompatibel ist). – scatmoi