Ich verwende react-native
für die Android-Entwicklung. Ich habe eine Sicht darauf, wenn der Benutzer lange drückt, möchte ich eine animierte Ansicht anzeigen, die gezogen werden kann. Ich könnte dies mit PanResponder
erreichen, was gut funktioniert.
Aber was ich tun möchte, ist, wenn der Benutzer lange drückt, der Benutzer in der Lage sein sollte, dieselbe Berührung fortzusetzen / zu drücken und die neu angezeigte Animierte Ansicht zu ziehen.
Wenn Sie mit der Google Drive App vertraut sind, hat sie ähnliche Funktionen. Wenn ein Benutzer ein Element in der Liste lange drückt, wird ein ziehbares Element angezeigt. Der Benutzer kann das Objekt sofort ziehen.
Ich denke, wenn ich das Responder
dynamisch auf das ziehbare Element ändern könnte, nachdem es angezeigt wird, dann würde dies funktionieren.
Die Frage ist
Bietet react-native eine Möglichkeit, den Responder dynamisch zu ändern?
Was ich bisher versucht habe
Ich habe versucht, die Logik von onStartShouldSetPanResponderCapture
, onMoveShouldSetPanResponderCapture
, onMoveShouldSetPanResponder
, onPanResponderTerminationRequest
zu ändern, so dass sobald der ziehbare Gegenstand angezeigt wird, die Containeransicht den Anfang und die Bewegung nicht erfassen und akzeptieren sollte Die Beendigungsanforderung gibt auch den Wert "false" an die Beendigungsanforderung des ziehbaren Elements zurück und die Rückgabe des Werts "true" an das Ereignis sollte Ereignisse erfassen.
Ein Work-around, der für mich funktioniert, ist, den ziehbaren Gegenstand oben auf dem Behälter mit weniger Undurchsichtigkeit zu zeigen und ihn als falsch festzuhalten. Sobald der Benutzer lange darauf drückt, ändere ich die Deckkraft, so dass es deutlich sichtbar ist. Mit diesem Ansatz kann der Benutzer die Berührung fortsetzen, um den Gegenstand zu ziehen. Aber der Container ist eigentlich eine Listenzeile. Daher müsste ich viele ziehbare Objekte erstellen, da der Benutzer eine beliebige Zeile lang drücken kann.
Aber ich denke, das ist keine gute Lösung und wenn ich den Responder ändern könnte, wäre das großartig.
Ich verwende onStartShouldSetPanResponderCapture
für die Android-Entwicklung. Ich habe eine Sicht darauf, wenn der Benutzer lange drückt, möchte ich eine animierte Ansicht anzeigen, die gezogen werden kann. Ich könnte dies mit onStartShouldSetPanResponderCapture
erreichen, was gut funktioniert.
Aber was ich tun möchte, ist, wenn der Benutzer lange drückt, der Benutzer in der Lage sein sollte, dieselbe Berührung fortzusetzen / zu drücken und die neu angezeigte Animierte Ansicht zu ziehen.
Wenn Sie mit der Google Drive App vertraut sind, hat sie ähnliche Funktionen. Wenn ein Benutzer ein Element in der Liste lange drückt, wird ein ziehbares Element angezeigt. Der Benutzer kann das Objekt sofort ziehen.
Ich denke, wenn ich das setNativeProps
dynamisch auf das ziehbare Element ändern könnte, nachdem es angezeigt wird, dann würde dies funktionieren.
Die Frage ist
Bietet react-native eine Möglichkeit, den Responder dynamisch zu ändern?
Was ich bisher versucht habe
Ich habe versucht, die Logik von ListView
, ListView
, TouchableOpacity
, onLongPress
zu ändern, so dass sobald der ziehbare Gegenstand angezeigt wird, die Containeransicht den Anfang und die Bewegung nicht erfassen und akzeptieren sollte Die Beendigungsanforderung gibt auch den Wert "false" an die Beendigungsanforderung des ziehbaren Elements zurück und die Rückgabe des Werts "true" an das Ereignis sollte Ereignisse erfassen.
Ein Work-around, der für mich funktioniert, ist, den ziehbaren Gegenstand oben auf dem Behälter mit weniger Undurchsichtigkeit zu zeigen und ihn als falsch festzuhalten. Sobald der Benutzer lange darauf drückt, ändere ich die Deckkraft, so dass es deutlich sichtbar ist. Mit diesem Ansatz kann der Benutzer die Berührung fortsetzen, um den Gegenstand zu ziehen. Aber der Container ist eigentlich eine Listenzeile. Daher müsste ich viele ziehbare Objekte erstellen, da der Benutzer eine beliebige Zeile lang drücken kann.
Aber ich denke, das ist keine gute Lösung und wenn ich den Responder ändern könnte, wäre das großartig.
Einfache Antwort
Nach meinem besten Wissen, no , können Sie den Responder einer View nicht dynamisch ändern.
Der Grund, warum Methoden wie this._previousLeft
nicht für eine untergeordnete Ansicht funktionieren, die Sie ziehen möchten, besteht darin, dass diese Methoden auf touch start und definitionsgemäß auf das untergeordnete Element ausgelöst werden Die Ansicht, die this._previousTop
in dem von Ihnen beschriebenen Verhalten implementiert, existiert noch nicht, wenn die Berührung gestartet wird.
Aber es gibt keinen Grund, warum die Pan-Responder-Methoden in der untergeordneten Ansicht implementiert werden sollten:
Die Lösung
Wenn Sie einen Schritt zurück von der Implementierung machen, ist die tatsächliche Funktionalität, die erforderlich ist, dass einige -Komponente in Ihrer Anwendung ein Pan-Responder sein muss. Wenn sich der Pan-Responder bewegt, erhalten Sie das Touch-Ereignis. An dieser Stelle können Sie top
in untergeordneten Ansichten angeben, um die Änderungen in der Schwenkgeste widerzuspiegeln.
Wenn Sie also eine untergeordnete Ansicht verschieben möchten, müssen Sie dieses untergeordnete Element nicht zum Responder machen. Sie können einfach den Elternteil zum Responder machen und dann die Kind-Requisiten vom Elternknoten aktualisieren.
Ich habe unten eine Beispiel-App implementiert, und hier ist eine Schritt für Schritt Erklärung, was passiert:
Sie haben eine Komponente, die left
rendert. Das setNativeProps
ist dein Pan-Responder. Jede Zelle in der Listenansicht hat eine View
, die auf lange Druckvorgänge reagiert.
Wenn das Ereignis "long press" eintritt (die Property _handlePanResponderMove
wird von der Zeile ausgelöst), rendern Sie die übergeordnete Komponente erneut mit einer schwebenden Ansicht im Vordergrund. Die absolute Position dieser Ansicht wird von zwei Eigenschaften gesteuert, die der übergeordneten Komponente ListView
und %code% gehören.
Nun ist es für diese unverankerte untergeordnete Ansicht nicht wichtig, auf Berührungen zu reagieren. Der Elternteil antwortet bereits. Das ganze Kind interessiert sich für seine zwei Position Eigenschaften. Um die schwebende Kindkomponente zu verschieben, müssen Sie lediglich die Eigenschaften %code% und %code% aktualisieren, indem Sie %code% der Komponente %code% des Kindes in der %code% -Funktion von %code% verwenden. .
Zusammenfassung
Wenn Sie Berührungen bearbeiten, müssen Sie nicht die Komponente verschieben, die tatsächlich berührt wird, um Berührungsereignisse abzurufen. Für die Komponente, die gerade verschoben wird, muss ihre Positionseigenschaft nur aktualisiert werden, wenn auf Berührungsereignisse wartet.
Hier finden Sie den vollständigen Code für die in der Google Drive App beschriebene langePress / Pan-Geste:
Das funktioniert bei mir mit RN 0.29. Ich bin mir sicher, dass es viele Optimierungen gibt, die hier gemacht werden könnten, aber ich habe nur versucht, das allgemeine Konzept in einem schnellen Morgen des Hackens zu illustrieren.
Ich hoffe, das hilft!
Tags und Links android react-native draggable uiresponder