2017-07-19 56 views
1

我有一个Android应用程序有一个Horizo​​ntalScrollView嵌入两个RecyclerViews。顶部RecyclerView有类别,当您选择一个类别时,底部的RecyclerView会列出该类别中的项目。为了检测选定的类别,我尝试使用Touch事件。当EditText获取触摸事件时,该行被选中。这部分工作很好。问题是我还需要能够编辑类别列表中的某些字段。如果我在EditText上绑定Touch事件,则EditText在您点击它时不会获得焦点。我尝试使用FocusChanged事件,但有时在水平滚动时,顶部RecyclerView的焦点被设置为第一个类别的EditText,从而导致所选类别发生更改。有没有办法在MvvmCross中绑定Touch事件并仍然让它导致绑定控件获得焦点?MvvmCross绑定触摸事件防止重点MvxItemTemplate

这是我的项目模板的布局:

<?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="horizontal" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:paddingTop="2dp" 
    android:paddingBottom="2dp" 
    local:MvxBind="This View"> 
    <TextView 
     android:layout_width="300dp" 
     android:layout_height="wrap_content" 
     style="@style/TableEditText" 
     local:MvxBind="Text Name; LongClick Name_LongClick; Touch Touch" 
     android:id="@+id/txtName" /> 
    <EditText 
     android:layout_width="110dp" 
     android:layout_height="wrap_content" 
     style="@style/TableEditText" 
     android:inputType="numberDecimal|numberSigned" 
     android:selectAllOnFocus="true" 
     local:MvxBind="Text Cubes, Converter=FloatToStringConverter; Touch Touch" 
     android:id="@+id/txtCubes" /> 
    <EditText 
     android:layout_width="110dp" 
     android:layout_height="wrap_content" 
     style="@style/TableEditText" 
     android:inputType="numberDecimal|numberSigned" 
     android:selectAllOnFocus="true" 
     local:MvxBind="Text Weight, Converter=IntToStringConverter; Touch Touch" 
     android:id="@+id/txtWeight" /> 
    <EditText 
     android:layout_width="500dp" 
     android:layout_height="wrap_content" 
     style="@style/TableEditText" 
     android:inputType="textCapSentences" 
     local:MvxBind="Text Note; Touch Touch" 
     android:id="@+id/txtNote" /> 
    <ImageButton 
     android:src="@drawable/ic_action_delete" 
     android:scaleType="fitCenter" 
     android:padding="3dp" 
     android:layout_width="40dp" 
     android:layout_height="40dp" 
     android:layout_marginLeft="5dp" 
     android:layout_marginRight="5dp" 
     android:layout_gravity="center" 
     local:MvxBind="Click DeleteClicked" 
     android:id="@+id/btnDeleteCategory" /> 
</LinearLayout> 

这是我的触摸事件挂钩:

public MvxCommand Touch 
    { 
     get 
     { 
      return new MvxCommand(() => 
      { 
       SurveyView act = (Mvx.Resolve<IMvxAndroidCurrentTopActivity>().Activity as SurveyView) ?? null; 
       if (act != null) 
       { 
        act.SetCurrCategory(this); 
       } 
      }); 
     } 
    } 

这是我定制的触摸事件绑定:

public class MvxViewTouchBinding 
    : MvxAndroidTargetBinding 
{ 
    private readonly View _view; 
    private IMvxCommand _command; 

    public MvxViewTouchBinding(View view) : base(view) 
    { 
     _view = view; 
     _view.Touch += ViewOnTouch; 
    } 

    private void ViewOnTouch(object sender, View.TouchEventArgs eventArgs) 
    { 
     if (_command != null) 
     { 
      _command.Execute(); 
     } 
    } 

    public override void SetValue(object value) 
    { 
     _command = (IMvxCommand)value; 
    } 

    protected override void Dispose(bool isDisposing) 
    { 
     if (isDisposing) 
     { 
      _view.Touch -= ViewOnTouch; 
     } 
     base.Dispose(isDisposing); 
    } 

    protected override void SetValueImpl(object target, object value) 
    { 
    } 

    public override Type TargetType 
    { 
     get { return typeof(IMvxCommand); } 
    } 

    public override MvxBindingMode DefaultMode 
    { 
     get { return MvxBindingMode.OneWay; } 
    } 
} 

这是在Setup.cs中

 registry.RegisterCustomBindingFactory<View>("Touch", 
                view => new MvxViewTouchBinding(view)); 
+1

试试这个 - https://stackoverflow.com/a/36360795/2754727 – pnavk

+2

尝试设置'eventArgs.Handled = false;' – Cheesebaron

+0

@Cheesebaron这样做了!感谢奶酪! –

回答

0

我不得不把ViewOnTouch处理器更改为:

private void ViewOnTouch(object sender, View.TouchEventArgs eventArgs) 
    { 
     eventArgs.Handled = false; 

     if (_command != null) 
     { 
      _command.Execute(); 
     } 
    } 

显然已处理默认为真,这将导致事件链终止这个被称为后。将其设置为false会告诉系统该事件尚未正确处理,因此它会调用下一个处理程序。我猜测后续处理程序会设置焦点。谢谢@Cheesebaron