2013-03-01 159 views
1

我有一个ViewPager可以保存4个片段/面板,每个半角的园景画面。ViewPager焦点问题

_______________ _______________ _______________ _______________ 
|1    |2    |3    |4    | 
|    |    |    |    | 
|    |    | ___________ | ___________ | 
|    |    | | EditText1 | | | EditText2 | | 
|    |    | |___________| | |___________| | 
|_______________|_______________|_______________|_______________| 

面板3和4每个都有一个EditText。

在程序开始时,用户显示屏幕2 & 3(它们可以滑动回到看到屏幕1, 和屏幕4,直到选择3上的列表项不存在)。

所以,承载板(和相关联的ViewPager)的视图使得到

viewPager.SetCurrentItem(PANEL3,true); // const int PANEL3 = 2; - zero offset 

这会导致显示2 & 3,并给出3的焦点(其给出EditText1焦点)的呼叫。

当用户选择3的东西,使得4至在滑动(使得现在3 & 4示出), 另一个呼叫在宿主视图

viewPager.SetCurrentItem(PANEL4,true); // const int PANEL4 = 3; - zero offset 

以至于现在面板4得到由焦点(这给了EditText2焦点)。


这里是问题:

随着面板3 & 4显示,在EditText2具有焦点,如果我再点击进入EditText1,这将导致softkeyboard到弹出,焦点将回到EditText2 (光标在EditText2中,任何键入都会被输入)。

我需要知道什么导致焦点恢复到EditText2。

我在猜测对viewPager.SetContentView(PANEL4)的调用会导致面板焦点状态被保留在ViewPager的某个地方,当softkeyboard弹出并导致一些“刷新”事件触发时,ViewPager正在恢复焦点状态(即PANEL4),尽管我不确定。我在主机视图和每个面板中都做了很多打印输出,并且softkeyboard弹出窗口不会导致任何标准生命周期事件被触发,但是我确实知道viewPager的OnLayout会触发。


欢迎任何帮助或见解,谢谢。


Cheesebaron:

这是支持信息,以帮助其布局相关文件中说明,如果发生在我的解决方案的意见一个不裹在一个ViewGroup(LinearLayout中)的通货膨胀问题。

如果PagedFragmentRecordNoteBoxInput不包裹在LinearLayout中,我们有

<?xml version="1.0" encoding="utf-8"?> 
<FieldInspection.Droid.Views.Custom.PagedFragmentRecordNoteBox.PagedFragmentRecordNoteBoxInput 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/fi_record_note_box_input" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#FFFFFFFF" 
    android:gravity="top" 
    android:textSize="20sp" 
    android:textColor="#FF000000" 
    android:layout_margin="20dip"/> 

和充气代码PagedFragmentRecordNoteBox更改

protected override RecordNoteBoxInput InstantiateInput() 
{ 
    View v = _inflater.Inflate(Resource.Layout.PagedFragmentRecordNoteBoxInput, null); 

    _pagedFragmentFieldInput = (PagedFragmentRecordNoteBoxInput) v; 

    _pagedFragmentFieldInput.OuterClass = this; 

    return (RecordNoteBoxInput)_pagedFragmentFieldInput; 
} 

然后产生除外:

07-02 16:21:32.494: I/MonoDroid(18642): UNHANDLED EXCEPTION: Android.Views.InflateException: Exception of type 'Android.Views.InflateException' was thrown. 
07-02 16:21:32.494: I/MonoDroid(18642): at Android.Runtime.JNIEnv.CallObjectMethod (intptr,intptr,Android.Runtime.JValue[]) <0x00080> 
07-02 16:21:32.494: I/MonoDroid(18642): at Android.Views.LayoutInflater.Inflate (int,Android.Views.ViewGroup) <0x0018f> 
07-02 16:21:32.494: I/MonoDroid(18642): at FieldInspection.Droid.Views.Custom.PagedFragmentRecordNoteBox.InstantiateInput() <0x0002b> 
07-02 16:21:32.494: I/MonoDroid(18642): at FieldInspection.Droid.Views.Custom.RecordNoteBox.Init (Android.Content.Context) <0x00063> 
07-02 16:21:32.494: I/MonoDroid(18642): at FieldInspection.Droid.Views.Custom.RecordNoteBox..ctor (Android.Content.Context,Android.Util.IAttributeSet) <0x0002f> 
07-02 16:21:32.494: I/MonoDroid(18642): at FieldInspection.Droid.Views.Custom.PagedFragmentRecordNoteBox..ctor (Android.Content.Context,Android.Util.IAttributeSet) <0x00023> 
07-02 16:21:32.494: I/MonoDroid(18642): at (wrapper dynamic-method) object.705e129e-2c0d-42db-87f7-db1842b85d7c (intptr,object[]) <0x0005f> 
07-02 16:21:32.494: I/MonoDroid(18642): at Java.Interop.TypeManager.n_Activate (intptr,intptr,intptr,intptr,intptr,intptr) <0x000f7> 
07-02 16:21:32.494: I/MonoDroid(18642): at (wrapper native-to-managed) Java.Interop.TypeManager.n_Activate (intptr,intptr,intptr,intptr,intptr,intptr) <0x0006f> 
07-02 16:21:32.494: I/MonoDroid(18642): at (wrapper delegate-invoke) <Module>.invoke_intptr__this___intptr_intptr_intptr_JValue[] (intptr,intptr,intptr,Android.Runtime.JValue[]) <0x000ab> 
07-02 16:21:32.494: I/MonoDroid(18642): at Android.Runtime.JNIEnv.CallObjectMethod (intptr,intptr,Android.Runtime.JValue[]) <0x00053> 
07-02 16:21:32.494: I/MonoDroid(18642): at Android.Views.LayoutInflater.Inflate (int,Android.Views.ViewGroup,bool) <0x001f3> 
07-02 16:21:32.494: I/MonoDroid(18642): at FieldInspection.Droid.Views.ParcelRecordDetailInspectionView.Render() <0x0002f> 
07-02 16:21:32.494: I/MonoDroid(18642): at FieldInspection.Droid.Views.ParcelRecordDetailInspectionView.OnCreateView (Android.Views.LayoutInflater,Android.Views.ViewGroup,Android.OS.Bundle) <0x000af> 
07-02 16:21:32.494: I/MonoDroid(18642): at Android.App.Fragment.n_OnCreateView_Landroid_view_LayoutInflater_Landroid_view_ViewGroup_Landroid_os_Bundle_ (intptr,intptr,intptr,intptr,intptr) <0x0009f> 
07-02 16:21:32.494: I/MonoDroid(18642): at (wrapper dynamic-method) object.5d994140-166d-44ce-ac16-71f1e1698262 (intptr,intptr,intptr,intptr,intptr) <0x0005b> 
07-02 16:21:32.494: I/MonoDroid(18642): --- End of managed exception stack trace --- 
07-02 16:21:32.494: I/MonoDroid(18642): android.view.InflateException: Binary XML file line #5: Error inflating class FieldInspection.Droid.Views.Custom.PagedFragmentRecordNoteBox.PagedFragmentRecordNoteBoxInput 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:691) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.view.LayoutInflater.inflate(LayoutInflater.java:466) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.view.LayoutInflater.inflate(LayoutInflater.java:396) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.view.LayoutInflater.inflate(LayoutInflater.java:352) 
07-02 16:21:32.494: I/MonoDroid(18642):  at mono.android.TypeManager.n_activate(Native Method) 
07-02 16:21:32.494: I/MonoDroid(18642):  at mono.android.TypeManager.Activate(TypeManager.java:7) 
07-02 16:21:32.494: I/MonoDroid(18642):  at fieldinspection.droid.views.custom.PagedFragmentRecordNoteBox.<init>(PagedFragmentRecordNoteBox.java:29) 
07-02 16:21:32.494: I/MonoDroid(18642):  at java.lang.reflect.Constructor.constructNative(Native Method) 
07-02 16:21:32.494: I/MonoDroid(18642):  at java.lang.reflect.Constructor.newInstance(Constructor.java:417) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.view.LayoutInflater.createView(LayoutInflater.java:586) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.view.LayoutInflater.parseInclude(LayoutInflater.java:800) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:729) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:742) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:742) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:742) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.view.LayoutInflater.inflate(LayoutInflater.java:489) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.view.LayoutInflater.inflate(LayoutInflater.java:396) 
07-02 16:21:32.494: I/MonoDroid(18642):  at fieldinspection.droid.views.ParcelRecordDetailInspectionView.n_onCreateView(Native Method) 
07-02 16:21:32.494: I/MonoDroid(18642):  at fieldinspection.droid.views.ParcelRecordDetailInspectionView.onCreateView(ParcelRecordDetailInspectionView.java:52) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:828) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1032) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.app.BackStackRecord.run(BackStackRecord.java:622) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1382) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:437) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.support.v13.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:167) 
07-02 16:21:32.494: I/MonoDroid(18642):  at android.supp 
07-02 16:21:32.504: E/mono(18642): Unhandled Exception: 
07-02 16:21:32.504: E/mono(18642): Android.Views.InflateException: Exception of type 'Android.Views.InflateException' was thrown. 
07-02 16:21:32.504: E/mono(18642): at Android.Runtime.JNIEnv.CallObjectMethod (intptr,intptr,Android.Runtime.JValue[]) <0x00080> 
07-02 16:21:32.504: E/mono(18642): at Android.Views.LayoutInflater.Inflate (int,Android.Views.ViewGroup) <0x0018f> 
07-02 16:21:32.504: E/mono(18642): at FieldInspection.Droid.Views.Custom.PagedFragmentRecordNoteBox.InstantiateInput() <0x0002b> 
07-02 16:21:32.504: E/mono(18642): at FieldInspection.Droid.Views.Custom.RecordNoteBox.Init (Android.Content.Context) <0x00063> 
07-02 16:21:32.504: E/mono(18642): at FieldInspection.Droid.Views.Custom.RecordNoteBox..ctor (Android.Content.Context,Android.Util.IAttributeSet) <0x0002f> 
07-02 16:21:32.504: E/mono(18642): at FieldInspection.Droid.Views.Custom.PagedFragmentRecordNoteBox..ctor (Android.Content.Context,Android.Util.IAttributeSet) <0x00023> 
07-02 16:21:32.504: E/mono(18642): at (wrapper dynamic-method) object.705e129e-2c0d-42db-87f7-db1842b85d7c (intptr,object[]) <0x0005f> 
07-02 16:21:32.504: E/mono(18642): at Java.Interop.TypeManager.n_Activate (intptr,intptr,intptr,intptr,intptr,intptr) <0x000f7> 
07-02 16:21:32.504: E/mono(18642): at (wrapper native-to-managed) Java.Interop.TypeManager.n_Activate (intptr,intptr,intptr,intptr, 
07-02 16:21:32.504: I/mono(18642): [ERROR] FATAL UNHANDLED EXCEPTION: Android.Views.InflateException: Exception of type 'Android.Views.InflateException' was thrown. 
07-02 16:21:32.504: I/mono(18642): at Android.Runtime.JNIEnv.CallObjectMethod (intptr,intptr,Android.Runtime.JValue[]) <0x00080> 
07-02 16:21:32.504: I/mono(18642): at Android.Views.LayoutInflater.Inflate (int,Android.Views.ViewGroup) <0x0018f> 
07-02 16:21:32.504: I/mono(18642): at FieldInspection.Droid.Views.Custom.PagedFragmentRecordNoteBox.InstantiateInput() <0x0002b> 
07-02 16:21:32.504: I/mono(18642): at FieldInspection.Droid.Views.Custom.RecordNoteBox.Init (Android.Content.Context) <0x00063> 
07-02 16:21:32.504: I/mono(18642): at FieldInspection.Droid.Views.Custom.RecordNoteBox..ctor (Android.Content.Context,Android.Util.IAttributeSet) <0x0002f> 
07-02 16:21:32.504: I/mono(18642): at FieldInspection.Droid.Views.Custom.PagedFragmentRecordNoteBox..ctor (Android.Content.Context,Android.Util.IAttributeSet) <0x00023> 
07-02 16:21:32.504: I/mono(18642): at (wrapper dynamic-method) object.705e129e-2c0d-42db-87f7-db1842b85d7c (intptr,object[]) <0x0005f> 
07-02 16:21:32.504: I/mono(18642): at Java.Interop.TypeManager.n_Activate (intptr,intptr,intptr,intptr,intptr,intptr) <0x000f7> 
07-02 16:21:32.504: I/mono(18642): at (wrapper native-to-managed) Java.Interop.TypeManager.n_Activate (intptr,intptr,i 
07-02 16:21:32.524: W/InputDispatcher(215): channel '41b69d78 net.monocross.fieldinspection/fieldinspection.droid.FieldInspectionMain (server)' ~ Consumer closed input channel or an error occurred. events=0x8 
07-02 16:21:32.524: E/InputDispatcher(215): channel '41b69d78 net.monocross.fieldinspection/fieldinspection.droid.FieldInspectionMain (server)' ~ Channel is unrecoverably broken and will be disposed! 
07-02 16:21:32.524: W/InputDispatcher(215): Attempted to unregister already unregistered input channel '41b69d78 net.monocross.fieldinspection/fieldinspection.droid.FieldInspectionMain (server)' 
07-02 16:21:32.524: D/Zygote(116): Process 18642 exited cleanly (1) 
07-02 16:21:32.524: W/InputDispatcher(215): channel '41aef860 net.monocross.fieldinspection/fieldinspection.droid.views.CalendarView (server)' ~ Consumer closed input channel or an error occurred. events=0x8 
07-02 16:21:32.524: E/InputDispatcher(215): channel '41aef860 net.monocross.fieldinspection/fieldinspection.droid.views.CalendarView (server)' ~ Channel is unrecoverably broken and will be disposed! 
07-02 16:21:32.524: W/InputDispatcher(215): Attempted to unregister already unregistered input channel '41aef860 net.monocross.fieldinspection/fieldinspection.droid.views.CalendarView (server)' 
07-02 16:21:32.524: I/ActivityManager(215): Process net.monocross.fieldinspection (pid 18642) has died. 
+0

我想我可能会拥有它。当用户选择其中一个EditText时,我需要从包含单击的EditText的片段/面板回调主机活动,并调用viewPager.SetCurrentItem()来更新当前面板。然后,当软键触发视图重绘(请参阅下面的堆栈跟踪)并因此请求焦点时,正确的面板将被聚焦。 – samosaris 2013-03-01 18:32:37

回答

0

我的答案就在于该堆栈跟踪,这是从的EditText子EditText2上面提到的OnFocusChange()覆盖范围内(美好的时光跟踪此):

注:这仅仅是出于存档目的,有可能帮助未来的读者解决这个问题。我不会接受这个作为我的答案,并且仍然乐于帮助(再次感谢)。


dalvik.system.VMStack.getThreadStackTrace(本机方法) java.lang.Thread.getStackTrace(Thread.java:591) appname.droid.views.EditText2.n_onFocusChanged(本机方法) 程序的名字。 droid.views.EditText2.onFocusChanged(EditText2.java:53) android.view.View.handleFocusGainInternal(View.java:3680) android.view.View.requestFocus(View.java:5373) android.view.ViewGroup .onRequestFocusInDescendants(ViewGroup.java:2154) android.view.ViewGroup.requestFocus(ViewGroup.java:2110) android.view.ViewGroup.onRequestFocusInDescendants(ViewGroup.java :2154) android.view.ViewGroup.requestFocus(ViewGroup.java:2110) android.view.ViewGroup.onRequestFocusInDescendants(ViewGroup.java:2154) android.view.ViewGroup.requestFocus(ViewGroup.java:2110) 机器人.view.ViewGroup.onRequestFocusInDescendants(ViewGroup.java:2154) android.view.ViewGroup.requestFocus(ViewGroup.java:2113) android.view.ViewGroup.onRequestFocusInDescendants(ViewGroup.java:2154) android.view.ViewGroup。 requestFocus的(ViewGroup.java:2110) android.view.View.requestFocus(View.java:5323) android.support.v4.view.ViewPager.populate(ViewPager.java:1051) android.support.v4.view.ViewPager.populate(ViewPager.java:881) android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1366) android.view.View.measure(View.java :12728) android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698) android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369) android.widget.LinearLayout.measureVertical(LinearLayout.java:660) 机器人.widget.LinearLayout.onMeasure(LinearLayout.java:553) android.view.View.measure(View.java:12728) android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698) android.widget.FrameLayout。 onMeasure(FrameLayout.java:293) android.view.View.measure(View.java:12728) 个android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698) android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369) android.widget.LinearLayout.measureVertical(LinearLayout.java:660) android.widget。 LinearLayout中。onMeasure(LinearLayout.java:553) android.view.View.measure(View.java:12728) android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698) android.widget.FrameLayout.onMeasure(FrameLayout.java :293) com.android.internal.policy.impl.PhoneWindow $ DecorView.onMeasure(PhoneWindow.java:2092) android.view.View.measure(View.java:12728) android.view.ViewRootImpl.performTraversals( ViewRootImpl.java:1064) android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442) android.os.Handler.dispatchMessage(Handler.java:99) android.os.Looper.loop(Looper.java:137 ) android.app.ActivityThread.main(ActivityThread.java:4424) java.lang.reflect.Method.invokeN ative(Native Method) java.lang.reflect.Method.invoke(Method.java:511) com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:784) com.android.internal。 os.ZygoteInit.main(ZygoteInit.java:551) dalvik.system.NativeStart.main(本机方法)

public class ViewPager extends ViewGroup 
{ 
    ... 

    void populate 
    { 
     ... 

     if (hasFocus()) { 
      View currentFocused = findFocus(); 
      ItemInfo ii = currentFocused != null ? infoForAnyChild(currentFocused) : null; 
      if (ii == null || ii.position != mCurItem) { 
       for (int i=0; i<getChildCount(); i++) { 
       View child = getChildAt(i); 
       ii = infoForChild(child); 
       if (ii != null && ii.position == mCurItem) { 
        if (child.requestFocus(FOCUS_FORWARD)) { 
         break; 
        } 
       } 
      } 
     } 

     ... 
    } 

    ... 
} 
+0

我不知道你是否知道了,但我可以通过更改它检查的位置来解决你所遇到的问题,如果ii.position!= mCurrentItem。如果你制作得更加严格(即只有在物品不在屏幕上时才使用),那么正确的视图将保持专注。 – 2014-03-26 21:11:42

+0

@CameronKetcham这次修复有更多的迭代,我有另一篇文章回答这个问题。这不是一个小问题,需要许多迭代才能完全正确地修复它。 – samosaris 2014-03-27 17:18:03

0

我找到的解决方案是不繁琐,但它足以,而不是过多的开销。

由于Android的默认行为是将触摸/点击事件提供给子视图,在这种情况下,其中EditText的,我不得不继承EditText的子类并重写他们的OnTouchEvent成员。

代表团在这种情况下是不够的

myEditText.Touch += EditTextTouchEventHandler; 

,因为我还是想的默认行为的EditText上(内置)触摸事件(其中做了一些不错的东西像位置,使用者的触摸光标,而不仅仅是在文本框的开头)。

在的onTouchEvent,视图,传呼,认为这EditText上是居住在被告知这个点击事件的片段,和EditText上聚焦,手动处理(所以当任何刷新一切发生的时候 - 即键盘弹出 - 因此,一个RequestFocus触发,最后一次点击的EditText不会松散焦点(正如所指出的那样)。通过Android推荐的父级侦听器模式完成片段“回调”,即

另外,ViewPager的RequestChildFocus方法必须被覆盖,所以事件可以被拦截和吃掉,在它的地方,手动调用了第二个RequestChildFocus2方法,该方法又调用基类Reque stChildFocus。

的包含所述ViewPager定义和实现接口

public interface IFragmentToViewPagerEvent 
{ 
    void ParcelRecordFieldClickEvent(Fragment child, View focused); 
} 

而且每个段将保持到活性,浇铸到该接口的引用,所以该片段可以通过inteface到ViewPager通信活动方法(另一个接口可以声明Fragments实现ViewPager可以调用片段 - 然后通讯的两个方向都被覆盖)。

private ParcelView.IFragmentToViewPagerEvent _fragmentToViewPagerEvent; 

public override void OnAttach(Activity activity) 
{ 
    base.OnAttach(activity); 

    _fragmentToViewPagerEvent = (ParcelView.IFragmentToViewPagerEvent) activity; 
} 

继承人的子类的样子:

RecordNoteBoxInput被创造是一个EditText,这是被放置在一个标签一个自定义类,即扩大 填补包含它的标签,上面统一宽度边界四周。创建

public class RecordNoteBoxInput : EditText 
{ 
    // sometime u need this, other times you don't - mono's missing nuts that android don't 
    //public RecordNoteBoxInput(IntPtr jRef, JniHandleOwnership handle) : base(jRef, handle) { } 

    public RecordNoteBoxInput(Context context) : base(context) { } 
    public RecordNoteBoxInput(Context context, IAttributeSet attributes) : base(context, attributes) { } 
    public RecordNoteBoxInput(Context context, IAttributeSet attributes, int defStyle) : base(context, attributes, defStyle) { } 
} 

public class RecordNoteBox : LinearLayout 
{ 
    protected Context _context; 
    protected LayoutInflater _inflater; 

    protected RecordNoteBoxInput _inputFiled; 

    public RecordNoteBoxInput Input 
    { 
     get { return _inputFiled; } 
     set { _inputFiled = value; } 
    } 

    protected virtual RecordNoteBoxInput InstantiateInput() 
    { 
     return (RecordNoteBoxInput)_inflater.Inflate(Resource.Layout.RecordNoteBoxInput, this, false); 
    } 

    protected void Init(Context context) 
    { 
     _context = context; 
     _inflater = LayoutInflater.From(context); 
     _inputFiled = InstantiateInput(); 

     this.AddView(_inputFiled); 
    } 

    // sometime u need this, other times you don't - mono's missing nuts that android don't 
    //public RecordNoteBox(IntPtr jRef, JniHandleOwnership handle) : base(jRef, handle) { } 

    public RecordNoteBox(Context context) : base(context) { Init(context); } 
    public RecordNoteBox(Context context, IAttributeSet attributes) : base(context, attributes) { Init(context); } 
    public RecordNoteBox(Context context, IAttributeSet attributes, int defStyle) : base(context, attributes, defStyle) { Init(context); } 

} 

PagedFragmentRecordNoteBox使得内部RecordNoteBox 组成的EditText的的onTouchEvent可以重写,允许有机会信号向含有ViewPager其中的EditText没有拥有焦点。 SetCurrentItem()无法使用,因为我使用半屏ViewPager页面(在ViewPagerAdapter中为PageWidth返回0.5f),当前位于右侧的任何页面将最终在调用SetCurrentItem时自动移动到左侧,因为这是ViewPager的默认行为,我不愿意重写这个函数。另外,这个函数还有一个内部/私有版本,如果不重写整个ViewPager类,我无法控制它。

public class PagedFragmentRecordNoteBox : RecordNoteBox 
{ 
    public Fragment ParentFragment { get; set; } 
    public RecordView.IFragmentToViewPagerEvent PagerListener { get; set; } 

    private PagedFragmentRecordNoteBoxInput _pagedFragmentFieldInput; 

    // sometime u need this, other times you don't - mono's missing nuts that android don't 
    //public PagedFragmentRecordNoteBox(IntPtr jRef, JniHandleOwnership handle) : base(jRef, handle) { } 

    public PagedFragmentRecordNoteBox(Context context) : base(context) { } 
    public PagedFragmentRecordNoteBox(Context context, IAttributeSet attributes) : base(context, attributes) { } 
    public PagedFragmentRecordNoteBox(Context context, IAttributeSet attributes, int defStyle) : base(context, attributes, defStyle) { } 

    protected override RecordNoteBoxInput InstantiateInput() 
    { 
     // Since I was getting inflation exception when the layout file 
     // PagedFragmentRecordRecordNoteBoxInput.axml had only a single, not wrapped in any ViewGroup, I had to 
     // wrap it up in a linear layout (whatever). Since this view will be added somewhere else, it needs to 
     // be removed from the wrapper (hence the call to RemoveAllViews - comment it out to see what happens). 

     //LayoutInflater inflater = (LayoutInflater)_context.ApplicationContext.GetSystemService(Context.LayoutInflaterService); 
     View v = _inflater.Inflate(Resource.Layout.PagedFragmentRecordRecordNoteBoxInput, null); 

     _pagedFragmentFieldInput = ((ViewGroup)v).FindViewById<PagedFragmentRecordNoteBoxInput>(Resource.Id.fi_record_note_box_input); 

     ((ViewGroup)v).RemoveAllViews(); 

     _pagedFragmentFieldInput.OuterClass = this; 

     return (RecordNoteBoxInput)_pagedFragmentFieldInput; 
    } 

    protected class PagedFragmentRecordNoteBoxInput : RecordNoteBoxInput 
    { 
     public PagedFragmentRecordNoteBox OuterClass { get; set; } 

     private Context _context { get; set; } 

     // sometime u need this, other times you don't - mono's missing nuts that android don't 
     //public PagedFragmentRecordNoteBoxInput(IntPtr jRef, JniHandleOwnership handle) : base(jRef, handle) { } 

     public PagedFragmentRecordNoteBoxInput(Context context) : base(context) { _context = context; } 
     public PagedFragmentRecordNoteBoxInput(Context context, IAttributeSet attributes) : base(context, attributes) { _context = context; } 
     public PagedFragmentRecordNoteBoxInput(Context context, IAttributeSet attributes, int defStyle) : base(context, attributes, defStyle) { _context = context; } 

     public override bool OnTouchEvent(MotionEvent e) 
     { 
      OuterClass.PagerListener.ParcelRecordFieldClickEvent(OuterClass.ParentFragment, this); 

      return base.OnTouchEvent(e); 
     } 
    } 
} 

然后,在OnCreateView上有一个EditText的片段,我会成立的EditText上(或它的子类),如

_thisView = (ViewGroup) _inflater.Inflate(Resource.Layout.Record, _container, false); 

PagedFragmentRecordNoteBox userNotes = _thisView.FindViewById<PagedFragmentRecordNoteBox>(Resource.Id.ll_record_note_box); 

PagedFragmentRecordNoteBox userNotes.ParentFragment = this; 
PagedFragmentRecordNoteBox userNotes.PagerListener = _fragmentToViewPagerEvent; 

是托管的主要活动ViewPager样子

public class ParcelView : Activity 
{ 
    protected ViewPager _viewPager; 
    private List<Android.App.Fragment> _fragments; 

    public interface IFragmentToViewPagerEvent 
    { 
     void ParcelRecordFieldClickEvent(Fragment child, View focused); 
    } 

    void IFragmentToViewPagerEvent.ParcelRecordFieldClickEvent(Fragment child, View focused) 
    { 
     _viewPager.RequestChildFocus2(null, focused); 
    } 
} 

所需的最后一个块是重写ViewPager的RequestChildFocus()方法和吃它的请求:

public class ViewPager2 : ViewPager 
{ 
    private view _clearFocused; 

    public override void RequestChildFocus(View child, View focused) 
    { 
     //base.RequestChildFocus(child, focused); 
    } 

    public void RequestChildFocus2(View child, View focused) 
    {    
     if(_clearFocused != null) 
     { 
      _clearFocused.ClearFocus(); 
     } 

     _clearFocused = focused; 

     base.RequestChildFocus(child, focused); 
    } 

} 

在布局文件中定义如下

Fragment.axml(所述片段中的一个主要的布局):

... 
    <TabHost 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@android:id/tabhost" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 

    <LinearLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/ll_record_detail_tab" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:orientation="vertical" 
     android:background="#FF200000"> 

     <FieldInspection.Droid.Views.MyTabWidget 
     android:id="@android:id/tabs" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content"/> 

     <FrameLayout 
     android:id="@android:id/tabcontent" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent"> 

     ... 

     <include layout="@layout/RecordNoteBox"/> 

     ... 

     </FrameLayout> 

    </LinearLayout> 

    </TabHost> 
    ... 

RecordNoteBox.axml

<?xml version="1.0" encoding="utf-8"?> 
<!--fieldinspection.droid.views.custom.RecordNoteBox--> 
<fieldinspection.droid.views.custom.PagedFragmentRecordNoteBox 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/ll_record_note_box" 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#FF555555"> 

</fieldinspection.droid.views.custom.PagedFragmentRecordNoteBox> 

RecordNotBoxInput.axml

<?xml version="1.0" encoding="utf-8"?> 
<fieldinspection.droid.views.custom.FieldInput 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/fi_record_note_box_input" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#FFFFFFFF" 
    android:gravity="top" 
    android:textSize="20sp" 
    android:textColor="#FF000000" 
    android:layout_margin="20dip"/> 

PagedFragmentRecordNoteBoxInput.axml - 注意其包裹在一个LinearLayout中。这是为了避免通货膨胀的例外。还不确定为什么有些视图需要被包装在ViewGroup中以便被夸大,但是他们会这样做(甚至更奇怪的是ViewGroup是View的子类,所以我可以弄明白)。

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/ll_record_note_box_input_container" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"> 

    <FieldInspection.Droid.Views.Custom.PagedFragmentRecordNoteBox.PagedFragmentRecordNoteBoxInput 
    android:id="@+id/fi_record_note_box_input" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#FFFFFFFF" 
    android:gravity="top" 
    android:textSize="20sp" 
    android:textColor="#FF000000" 
    android:layout_margin="20dip"/> 

    </LinearLayout>