問題タブ [snapping]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
162 参照

arrays - 配列を使用して複数のオブジェクトを複数の場所にスナップする

グリッドを色付きのタイルで覆う単純なゲームを作成するのに苦労しています。配列を使用してドラッグ アンド ドロップ機能を確立しましたが、それらをグリッド上の位置に簡単にスナップさせる方法が見つかりません。グリッド上の位置を、snapA1 から snapJ10 までの名前のムービー クリップにしました。すべて 10 文字ずつのグループで、一致するインスタンス名が付けられていますが、これらのクリップは移動する必要がないため、配列から削除されています。私が抱え続けている問題は、私が使用する機能は、単一の場所へのスナップを許可するためにしか機能しないということです. 基本的に、2 つ以上のオブジェクトのグループが互いにスナップできるようにする簡単な方法を探しているだけです。できればコードを力ずくで実行する必要はありません。冗談ではありませんが、同じコードの 20,000 インスタンスです。以下は、これまでのところスナップターゲットの場所を1つだけ許可するコードです

0 投票する
3 に答える
18254 参照

android - RecyclerView アイテムをスナップして、すべての X アイテムがスナップ先の単一ユニットのように見なされるようにする方法は?

バックグラウンド

以下を使用して、RecyclerView をその中心にスナップすることができます。

例:

MainActivity.kt

activity_main.xml

hereなどの一部のライブラリで行われていたように、反対側にスナップすることもできます。

hereのように、ViewPager のように機能する RecyclerView を持つことができるライブラリもあります。

問題

多くのアイテムを含む RecyclerView (私の場合は水平) があり、すべての X 個のアイテム (X は定数) を単一のユニットとして扱い、それらの各ユニットにスナップするとします。

たとえば、少しスクロールすると、0 項目または X 項目のいずれかにスナップできますが、その間の何かにはスナップできません。

ある意味では、通常の ViewPager の場合と動作が似ていますが、各ページに X 個のアイテムが含まれているだけです。

たとえば、上で書いたサンプル コードの続きで、 X==3 と仮定すると、スナップはこのアイドル状態から行われます。

ここに画像の説明を入力

このアイドル状態に (十分にスクロールした場合、それ以外の場合は前の状態のままになります):

ここに画像の説明を入力

上で述べたライブラリと同様に、フリングまたはスクロールは ViewPager のように処理する必要があります。

さらに (同じ方向に) 次のスナップ ポイントまでスクロールすると、アイテム "6" 、"9" などに到達します...

私が試したこと

代替ライブラリを検索しようとしましたが、これに関するドキュメントも読み込もうとしましたが、役立つものは見つかりませんでした。

ViewPager を使用することも可能かもしれませんが、ViewPager はアイテムをうまくリサイクルしないため、最適な方法ではないと思います。スナップ方法に関しては、RecyclerView よりも柔軟性が低いと思います。

質問

  1. RecyclerView を設定して、X 個のアイテムごとにスナップし、各 X 個のアイテムをスナップ先の単一ページとして扱うことはできますか?

    もちろん、アイテムは RecyclerView 全体に十分なスペースを均等に占有します。

  2. RecyclerView がスナップされる前に、このアイテムを含む特定のアイテムにスナップしようとしているときに、コールバックを取得するにはどうすればよいでしょうか? これは、私がここで尋ねたのと同じ質問に関連しているためです。


Kotlin ソリューション

RecyclerView サイズがあることを確認する必要がなく、サンプルでリストの代わりにグリッドを使用することを選択した、 「Cheticamp」の回答 ( here ) に基づく実用的な Kotlin ソリューション:

MainActivity.kt

SnapToBlock.kt


アップデート

回答を承認済みとしてマークしましたが、問題なく機能するため、深刻な問題があることに気付きました。

  1. スムーズなスクロールがうまくいかないようです (正しい場所にスクロールしません)。そのようなスクロールのみが機能します(ただし、「にじみ」効果があります):

  2. ヘブライ語 (「עברית」) などの RTL (右から左) ロケールに切り替えると、まったくスクロールできません。

  3. onCreateViewHolderと呼ばれることが多いことに気づきました。実際、ViewHolders をリサイクルする必要がある場合でも、スクロールするたびに呼び出されます。これは、ビューが過剰に作成されていることを意味し、メモリ リークが発生している可能性もあります。

私はそれらを自分で修正しようとしましたが、今のところ失敗しています。

ここの誰かがそれを修正する方法を知っているなら、私は追加の新しい報奨金を与えます


更新: RTL/LTR の修正を取得したため、この投稿内の Kotlin ソリューションを更新しました。


更新: ポイント #3 については、recyclerView のビューのプールがあり、すぐにいっぱいになるためと思われます。これを処理するには、プールのサイズを拡大するだけrecyclerView.getRecycledViewPool() .setMaxRecycledViews(viewType, Integer.MAX_VALUE) で済みます。その中にあるビュー タイプごとに を使用します。これが本当に必要だという奇妙なこと。私はそれについてGoogleに投稿しました(ここここ)が、プールはデフォルトで無制限であるべきであると拒否されました. 最終的に、少なくともすべてのビュー タイプに対してより便利な機能を提供するように要求することにしました (こちら)。

0 投票する
1 に答える
571 参照

android - RecyclerView と ViewPager のスナップ機能を設定しながら、すぐに選択されるページを取得する方法

バックグラウンド

ViewPagerスクロールを実行した後、ビューにスナップしますRecyclerView。次のようなものを使用すると、スナップできます。

または、このライブラリに示されているように、ライブラリを使用して特定のエッジにスナップします。CommonsWare hereで言及されているこのライブラリViewPagerに示されているように、必要に応じてほぼ完全に模倣できます。

どちらも必要に応じて同じように機能する (単一のビューにスナップし、オプションで使用可能なスペース全体を使用する) ことができるため、この質問は両方についてです。

ViewPager にはビューのリサイクルに関するいくつかの問題がありますが、たとえば、このライブラリを使用して修正できます。

問題

RecyclerView/ViewPager がスクロール中にアイドル状態になるとすぐに、新しく表示されたビューの UI を更新する必要があります。

もちろん、ユーザーはまだタッチできるので、何が起きようとしているのかを知るのは問題になるので、スクロール状態を整えるときにタッチ イベントもブロックする必要があります。

これは、たとえば、ユーザーが単一のページをページ 0 からページ 1 に移動すると、スナップが開始されるとすぐにタッチ イベントがブロックされ、ページ 1 にスナップされたことを認識してこれを更新できることを意味します。ページ。

ここでの問題は、RecyclerView と ViewPager の両方がこの機能を提供していないことです。スクロールが停止した後にのみ、選択されたアイテムを取得できます。

私が試したこと

の場合ViewPager、アダプターにはsetPrimaryItemしかないため、悲しいことに、解決が完了した後にどのアイテムが選択されているかがわかります。私はaddOnPageChangeListener関数を持っています。これは、( onPageScrolledを使用して) いつでもスクロール位置を教えてくれますが、どちらの方向 (左/右) に行くのか教えてくれません。それが選択されようとしています。addOnPageChangeListenerスクロールの状態 (アイドル、整定、ドラッグ) も提供します。

スクロール状態のコールバックを取得できるためRecyclerView、スクロール状態が安定する時期とアイドル状態になる時期を取得できますが、安定しようとしているアイテムを取得する方法がわかりません。

タッチイベントのブロックについてですが、落ち着いたらその上にクリッカブルなビュー(コンテンツがないので、ユーザーには見えません)を置いて、GONEアイドル状態のときは非表示(可視性を に設定)できると思いますが、より良い方法があります。

アイドル状態と整定状態で使用setOnTouchListenerしてみRecyclerViewましたが、整定中にタッチしようとすると、現在のスクロール位置で動かなくなりました。

したがって、 と の両方にRecyclerViewViewPagerすべてを完了するための障害があります...

これが私が現在働いているものです:

ViewPager:

ここに画像の説明を入力

RecyclerView:

ここに画像の説明を入力

私が試したもののPOCコード(との両方ViewPagerRecyclerView

MainActivity.kt

cell.xml

activity_main.xml

こことここからgradleファイルの「非標準」依存関係

質問

  1. ViewPager/RecyclerView が落ち着くときのコールバックを取得するにはどうすればよいですか?どのアイテムがスナップされるかを含めて?

  2. 安定してからアイドル状態になるまで、タッチイベントをブロックするにはどうすればよいですか? 私が書いたものよりも良い方法はありますか (上部にクリック可能なビューを表示する) ?


アップデート:

ViewPager の場合、onPageSelectedコールバックを使用して、解決しようとしているアイテムを取得できるようです。この方法でページの ViewHolder を取得する最良の方法は何だろうか。必要なデータを保存しonBindViewHolderて自分で確認することもできますが、もっと良い方法があるのではないかと思います。

今欠けているのは、それを行うRecyclerView方法とタッチイベントをブロックする方法です(私が書いたものよりも良い方法がある場合)。ライブラリには という関数がありますがaddOnPageChangedListener、セトリングが終わってから呼び出されるので、ここでは役に立ちません。