问题
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