2

Flex モバイル アプリケーション (iOS および Android にデプロイ) での Spark リストの実装に関して、非常に深刻な問題に直面しています。問題は、アイテムに触れたときにリストの選択が常に機能するとは限らないことです。実際、down状態が設定されている場合でも、アイテムが選択されず、以前に選択されていたアイテムが選択されたままになることがあります。

ListとクラスをListBase調べたところ、リストがマウス/タッチ イベントを受け取ることがわかりました。は起動され、実際には、適切にコミットされる選択とそうでない選択に対して同じように動作しますListitem_mouseDownHandler私がこれまでに見つけた違いは、commitPropertiesメソッド (に属するListBase) が失敗した選択に対して呼び出されることは決してないため、 も呼び出されないため、選択ListcommitSelection変更されないという事実につながります。

なぜこれが機能しないのかについて、より深い洞察を持っている人はいますか? 私は自分でこれを理解しているとは思わないので、どんな助けにも感謝します。

この問題を再現したい場合は、Flex モバイル プロジェクトをセットアップし、次のように単純なインライン レンダラーといくつかの汎用オブジェクトを使用して表示するリストを追加します。

<s:List id="myList" width="100%" height="100%">
    <s:dataProvider>
        <s:ArrayCollection>
            <fx:Object label="Item1" />
                         .....
            <fx:Object label="Item30" />
        </s:ArrayCollection>
    </s:dataProvider>
</s:List>

次に、デバイス上で指でアイテムをランダムに選択し、何が起こるかを確認します。画面に触れてもアイテムが選択されず、時々下の色が表示されます。

編集: ああ、4 回中 3 回に固執しないでください。問題を確認するには、4 回よりも少し頻繁に試行する必要がありますが、およそ 75% が適切な推定値だと思います。

Edit2: 明らかに同じ問題が発生しているため、Flex Jira にバグ レポートを提出しました: https://issues.apache.org/jira/browse/FLEX-33169

4

6 に答える 6

4

Apache Flex JIRA でのこのランダムな問題の本当の原因であると思われるものを投稿しました。興味があるかもしれません。

https://issues.apache.org/jira/browse/FLEX-33169?focusedCommentId=13557088&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-13557088

ご意見をお聞かせください。

于 2013-01-18T10:02:49.913 に答える
1

私は同じ問題を抱えています。明確にしたい:

  • 問題は次のとおりです。タッチでリストからアイテムを選択すると、選択が変更されない場合があります。これが発生した場合は、選択を変更する前に2〜3回タッチする必要があります。
  • これはiPadおよびiPhoneデバイスでのみ発生し、シミュレーターでは発生しません。
  • 影響を受ける状況を理解するのは簡単ではないため、再現するのは困難です。
  • 特別にスクロール動作後、軽いタッチで発生すると思います(ただし、タッチが発生しているので、「軽さ」は問題ありません...)

解決策はありませんが、ユーザーエクスペリエンスに影響を与える深刻なバグであることを強調するために、皆さんと共有したいと思います(これについては、アプリストアで否定的なレビューもありました...)。

チャオ

于 2012-08-13T13:01:48.980 に答える
1

この問題は私を非常に苛立たせています。これは深刻であり、ユーザー エクスペリエンスに非常に悪い影響を与えています。(その問題を再現できない場合は、iPhone または Android スマートフォンでテストしてください。iPad では発生しないようです)。少し調整した後...解決策が見つかったことを願っていますが、より深くテストすることをお勧めします。この方法で拡張されたリストを使用する必要があります。

package com.panurge.mobile
{
    import flash.events.MouseEvent;

    import mx.core.IVisualElement;
    import mx.core.mx_internal;
    import mx.events.TouchInteractionEvent;

    import spark.components.List;
    import spark.events.IndexChangeEvent;
    import spark.events.RendererExistenceEvent;

    public class ListSelectionFix extends List
    {

        protected var itemMouseDown:Object;
        protected var changeEventDispatched:Boolean = false;


        use namespace mx_internal;

        public function ListSelectionFix()
        {
            super();
            // we need this to cancel previous selection if a scroll action occurs
            this.addEventListener(TouchInteractionEvent.TOUCH_INTERACTION_START, onInteractionStart);
            // we need this to preventing dispatch change event twice
            this.addEventListener(IndexChangeEvent.CHANGE, onIndexChange);
        }

        protected function onIndexChange(event:IndexChangeEvent):void
        {
            //trace("onIndexChanging", itemMouseDown, changeEventDispatched);
            if (itemMouseDown != null){

                if (changeEventDispatched){
                    changeEventDispatched = false;
                    event.preventDefault();
                }
            }
        }


        override protected function dataGroup_rendererAddHandler(event:RendererExistenceEvent):void
        {
            super.dataGroup_rendererAddHandler(event);

            var renderer:IVisualElement = event.renderer;

            if (!renderer)
                return;

            renderer.addEventListener(MouseEvent.MOUSE_UP, item_mouseUpHandler);
        }

        override protected function dataGroup_rendererRemoveHandler(event:RendererExistenceEvent):void
        {
            super.dataGroup_rendererRemoveHandler(event);

            var renderer:IVisualElement = event.renderer;

            if (!renderer)
                return;

            renderer.removeEventListener(MouseEvent.MOUSE_UP, item_mouseUpHandler);
        }

        override protected function item_mouseDownHandler(event:MouseEvent):void
        {

            itemMouseDown = event.currentTarget;

            //trace("item_mouseDownHandler");
            super.item_mouseDownHandler(event);
        }

        protected function onInteractionStart(event:TouchInteractionEvent):void
        {
            //trace("onInteractionStart");
            // set this to null when the scroll is starting again to avoid dispatch on item_mouseUpHandler
            itemMouseDown = null;

        }

        protected function item_mouseUpHandler(event:MouseEvent):void
        {
            if (itemMouseDown == null || event.isDefaultPrevented())
                return;

            //trace("item_mouseUpHandler");

            // if we are in the same item renderer then we can safely select the item touched
            if (event.currentTarget == itemMouseDown){

                var _selectedIndex:int = this.dataProvider.getItemIndex(event.currentTarget.data);
                setSelectedIndex(_selectedIndex, true);
                changeEventDispatched = true;
                itemMouseDown.selected = true;
                //event.stopImmediatePropagation();
                event.preventDefault();
                // is dispatch by setSelectedIndex()
                //dispatchEvent(new IndexChangeEvent(IndexChangeEvent.CHANGE));

            }
        }
    }

解決することを願っています。お知らせ下さい。

于 2012-10-07T22:58:48.530 に答える
1

提出されたバグ (https://issues.apache.org/jira/browse/FLEX-33169) にこれを投稿しましたが、この情報もここに投稿することにしました。

これがバグかどうかはわかりません。

マウスのあるデスクトップでは、リストはマウスを押した項目を選択します。ただし、タッチ操作モードのデバイスでは、リストはマウスを離すとアイテムを選択します。これの主な理由は、ユーザーが実際にアイテムを選択するのではなく、スクロールしたい場合があるためです (たとえば、アイテムを選択すると、新しい画面に遷移する可能性があります)。Down は Selected とは異なり、アイテムは Down 状態から downAndSelected 状態 (さらに Selected 状態) になるか、または通常の状態に戻ります。down と selected の違いは微妙ですが、down は、ユーザーが選択する可能性のあるものの上にいることをユーザーに示すことですが、selected は実際にそれを選択したことを意味します。

マウスを押し下げると、List はクリックされた項目を追跡し、スクロールが開始されていない場合は、マウスを離すとその項目が選択されます。List.removeMouseHandlersForDragStart() と List.touchInteractionStartHandler() にブレークポイントを設定すると、何が起こっているかを確認できます。スクロールがトリガーされている場合は、List.touchInteractionStartHandler() が呼び出されていることがわかります。

それが実際に問題である場合は、スクロールが発生しないようにする方法があります。スクロールはすぐには開始されませんが、実際にスクロールであると判断する前に、ユーザーが指を一定量動かしたことを確認するために待機します。そのロジックは TouchScrollHelper.sbRoot_mouseMoveHandler() にあります。スクロールに必要な量は、Scroller.mx_internal::minSlopInches で制御できます。「touchInteractionStarting」(TouchInteractionEvent.TOUCH_INTERACTION_STARTING) イベントで event.preventDefault() を呼び出して、すべてのスクロールを停止することもできます。

それが問題でない場合は、これが何が起こっているのかをデバッグするための出発点になることを願っています.

古い Adob​​e wiki には、これらの動作の一部を説明するドキュメントがありました (ただし、コードの詳細はそれほど多くありません) が、残念ながら、それは失われているようです。願わくば、アドビの誰かがそれを復活させる時間を見つけてくれることを願っています。

于 2012-08-22T03:16:12.130 に答える
0

以下に示すコードを、「デフォルト」の Flex 4.6 で使用しました。Flex 4.6 には、AIR 3.1 がネイティブに付属していると思います。使用していると述べた 3.3 ではありません。

説明されている問題を再現できませんでした。Motorola Xoom (Android 3)、HTC Evo 3D (Android 4)、iPad 第 1 世代、および iPad 第 3 世代でテストしました。

iPad では、指をあまりにも速く押したり、リスト行の間の線に触れたりすると、アイテムが選択されないことがあることに気付きました。しかし、これを再現するのは困難でした。これらの状況では、ダウン状態は決して設定されませんでした。プレスが登録しなかったかのようです。これは、そのような状況でのタッチが軽すぎたためだと思います。

私の結論は次のいずれかです。

  1. AIR 3.1 では現れない AIR 3.3 のバグがあるということです。
  2. iPad 2 で、他のデバイスでは起きていない奇妙なことが起きています。
  3. Flex 4.6 と AIR 3.3 のカスタム マージに問題があります。

テストで使用したコード:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160">
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>

    <s:List id="myList" width="100%" height="100%">
        <s:dataProvider>
            <s:ArrayCollection>
                <fx:Object label="Item1" />
                <fx:Object label="Item2" />
                <fx:Object label="Item3" />
                <fx:Object label="Item4" />
                <fx:Object label="Item5" />
                <fx:Object label="Item6" />
                <fx:Object label="Item7" />
                <fx:Object label="Item8" />
                <fx:Object label="Item9" />
                <fx:Object label="Item10" />
                <fx:Object label="Item11" />
                <fx:Object label="Item12" />
                <fx:Object label="Item13" />
                <fx:Object label="Item14" />
                <fx:Object label="Item15" />
                <fx:Object label="Item16" />
                <fx:Object label="Item17" />
                <fx:Object label="Item18" />
                <fx:Object label="Item19" />
                <fx:Object label="Item20" />
                <fx:Object label="Item21" />
                <fx:Object label="Item22" />
                <fx:Object label="Item23" />
                <fx:Object label="Item24" />
                <fx:Object label="Item25" />
                <fx:Object label="Item26" />
                <fx:Object label="Item27" />
                <fx:Object label="Item28" />
                <fx:Object label="Item29" />
                <fx:Object label="Item30" />
            </s:ArrayCollection>
        </s:dataProvider>
    </s:List>

</s:Application>
于 2012-08-07T11:35:01.683 に答える
0

さて、暫定的な解決策 (ただし、他の問題が発生しないかどうかはまだわからないため、これはハックだと考えています) は次のとおりです。

スパークリストをサブクラス化し、オーバーライドしてitem_mouseDownHandler、選択したインデックスを具体的に設定します。

 override protected function item_mouseDownHandler(event:MouseEvent):void {
     setSelectedIndex((event.currentTarget as IItemRenderer).itemIndex);
 }

繰り返しますが、これは一目で機能しますが、もちろんテストが必要です。最新情報をお届けします!

于 2012-07-31T14:59:56.000 に答える