Xamarin Android EggsToGo (swipe gesture) listener in view doesnt work with ListView

我只是一个虾纸丫 提交于 2019-12-23 04:05:58

问题


I have a problem with EggsToGo (swipe left/right effect) listener in a ListView control. I had problem HERE and found the problem with EggsToGo exactly with a ListView listener... when I have a listener on my ListView so the ScrollView doesnt work there.... Is there some solution how I can make EggsToGo listener on view that will work on ListView?

My test project is HERE - the problem is in the FirstFragment (First view). When I have a listener on listview, the scrollview doesnt work. But when I don't have a listener, the swipe doesn't work....

Here is code my view:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <include
        layout="@layout/toolbar_back_layout" />
<!-- Test Top Layout -->
    <include
        layout="@layout/view_shopname_lastupdate_ribbon" />
<!-- Layout Date and Picker-->
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:background="@android:color/white"
        android:layout_height="50dp"
        android:paddingRight="20dp"
        android:paddingLeft="20dp"
        android:gravity="center_vertical">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:text="Období:"
            local:MvxLang="Text Period"
            android:textSize="16dp"
            android:textStyle="normal"
            android:textColor="@color/main_dark_gray"
            android:ellipsize="marquee"
            android:maxLines="1"
            android:gravity="center"
            android:layout_marginRight="10dp" />
        <MvxSpinner
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:id="@+id/periodSpinner"
            local:MvxBind="ItemsSource PeriodList; SelectedItem SelectedPeriod"
            android:spinnerMode="dropdown" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_weight="1">
             <oxyplot.xamarin.android.PlotView
               android:id="@+id/dailySalesModel"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:layout_weight="1"
               android:background="@android:color/white" />
             <MvxListView
              android:id="@+id/dailySalesListView"
              android:layout_weight="1"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              local:MvxBind="ItemsSource DailySales"
              local:MvxItemTemplate="@layout/view_dailysalesitem"
              android:divider="@color/main_gray"
              android:dividerHeight="1dp"
              android:choiceMode="none"
              android:layout_gravity="start"
              android:background="@android:color/white"
              android:listSelector="@android:color/transparent"
              android:paddingTop="15dp" />
        </LinearLayout>
        <include
            layout="@layout/view_bottomribbon" />
    </LinearLayout>
</LinearLayout>

Here is code my fragment:

   [MvxFragment(typeof(MainViewModel), Resource.Id.content_frame, true)]
    public class DailySalesFragment : BaseBackFragment<DailySalesViewModel>, View.IOnTouchListener
    {
        private Easter _easter;
        private View _view;
        protected override int FragmentId => Resource.Layout.fragment_dailysales;

        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            var ignore = base.OnCreateView(inflater, container, savedInstanceState);

            _view = this.BindingInflate(FragmentId, null);

            var orientation = Resources.Configuration.Orientation;

            if (orientation == Orientation.Landscape)
            {
                var metrics = Resources.DisplayMetrics;

                var height = CoreHelper.ConvertPixelsToDp(metrics.HeightPixels, Resources);

                if (height <= 360)
                {
                    var topLayout = _view.FindViewById<LinearLayout>(Resource.Id.topLayout);
                    if (topLayout != null)
                    {
                        topLayout.Visibility = ViewStates.Gone;
                    }
                }
            }

            var plotView = _view.FindViewById<PlotView>(Resource.Id.dailySalesModel);
            var bindset = this.CreateBindingSet<DailySalesFragment, DailySalesViewModel>();
            bindset.Bind(plotView).For(q => q.Model).To(vm => vm.Model);
            bindset.Apply();

            _easter = new Easter(new KonamiCode());

            var easyEgg = new CustomEgg("Easy")
                .WatchForSequence(Command.SwipeLeft(), Command.SwipeRight());

            _easter = new Easter(easyEgg);
            _easter.CommandDetected += cmd => DoSwipe(cmd.Value);

            var model = _view.FindViewById<PlotView>(Resource.Id.dailySalesModel);
            var listView = _view.FindViewById<MvxListView>(Resource.Id.dailySalesListView);
            model?.SetOnTouchListener(this);
            listView?.SetOnTouchListener(this);

            InitializeSwipeButtons();
            InitializeShopPicker();

            return _view;
        }

        public override void OnConfigurationChanged(Configuration newConfig)
        {
            base.OnConfigurationChanged(newConfig);
            ViewModel.RefreshView();
        }

        private void InitializeShopPicker()
        {
            var shopLayout = _view.FindViewById<LinearLayout>(Resource.Id.shopLayout);
            if (shopLayout != null)
            {
                shopLayout.Click += delegate
                {
                    ShowShopPickerDialog();
                };
            }
        }

        private void ShowShopPickerDialog()
        {
            var dialog = new ShopPickerDialogFragment(ViewModel.ShopId);
            dialog.DialogClosed += OnDialogClosed;
            dialog.Show(this.Activity.FragmentManager, null);
        }

        private async void OnDialogClosed(object sender, Helpers.ShopPickerDialogEventArgs e)
        {
            if (e.IsChanged)
            {
                var shop = e.Shop;
                await ViewModel.ChangeShop(shop);
            }
        }

        private void InitializeSwipeButtons()
        {
            var leftButton = _view.FindViewById<ImageButton>(Resource.Id.leftButton);
            if (leftButton != null)
            {
                leftButton.Click += delegate
                {
                    DoSwipe("RIGHT");
                };
            }

            var rightButton = _view.FindViewById<ImageButton>(Resource.Id.rightButton);
            if (rightButton != null)
            {
                rightButton.Click += delegate
                {
                    DoSwipe("LEFT");
                };
            }
        }

        private void DoSwipe(string swipeText)
        {
            if (swipeText.Equals("LEFT"))
            {
                FragmentManager.BeginTransaction()
                    .SetCustomAnimations(Resource.Animation.slide_from_right, Resource.Animation.slide_to_left)
                    .Replace(Resource.Id.content_frame, GroupSalesFragment.NewInstance(null))
                    .Commit();
            }

            if (swipeText.Equals("RIGHT"))
            {
                FragmentManager.BeginTransaction()
                    .SetCustomAnimations(Resource.Animation.slide_from_left, Resource.Animation.slide_to_right)
                    .Replace(Resource.Id.content_frame, ReportsFragment.NewInstance(null))
                    .Commit();
            }

            ViewModel.SwipeView(swipeText);
        }

        private int ConvertDpToPixels(int dp)
        {
            var pixels = dp * Resources.DisplayMetrics.Density;
            return (int)pixels;
        }

        private void RefreshLayout(object sender, EventArgs e)
        {
            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += WorkerDoWork;
            worker.RunWorkerCompleted += WorkerCompleted;
            worker.RunWorkerAsync();
        }

        private void WorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            _dailySalesSwipeRefreshLayout.Refreshing = false;
        }

        private void WorkerDoWork(object sender, DoWorkEventArgs e)
        {
            Task.Run(ViewModel.ExecuteRefreshAsync);
        }

        public bool OnTouch(View v, MotionEvent e)
        {
            _easter.OnTouchEvent(e);
            return true;
        }
    }

回答1:


When I have a listener on listview, the scrollview doesnt work. But when I don't have a listener, the swipe doesn't work

It has something wrong with Easter's OnTouch method, I dont know its logic but you could do it by yourself in OnTouch to implement this feature.

You could use SetOnTouchListener method for your whole FirstFragment layout, and implement your logic in your OnTouch method, here is my code :

var view = base.OnCreateView(inflater, container, savedInstanceState);
......
view.SetOnTouchListener(this);
//model?.SetOnTouchListener(this);
//listView?.SetOnTouchListener(this);

float mPosX = 0;
float mCurPosX = 0;
float mPosY = 0;
float mCurPosY = 0;
public bool OnTouch(View v, MotionEvent e)
{
    switch (e.Action)
    {
       case MotionEventActions.Down:
            mPosX = e.GetX();
            mCurPosX = mPosX;
            mPosY = e.GetY();
            mCurPosY = mPosY;
            break;
       case MotionEventActions.Move:
            mCurPosX = e.GetX();
            mCurPosY = e.GetY();

            float xDistance = Math.Abs(mCurPosX - mPosX);
            float yDistance = Math.Abs(mCurPosY - mPosY);
            if (xDistance > yDistance && mCurPosX - mPosX > 0)//Swip Right
            {
                DoSwipe("RIGHT");
            }
            else if (xDistance > yDistance && mCurPosX - mPosX < 0)//Swip Left
            {
                DoSwipe("LEFT");
            }
            break;
        default:
            break;
    }
    return true;
}

Effect like this.



来源:https://stackoverflow.com/questions/46073827/xamarin-android-eggstogo-swipe-gesture-listener-in-view-doesnt-work-with-listv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!