android - إيقاف إديتكست من الحصول على التركيز في بدء النشاط


لدي Activity أندرويد، مع عنصرين:

  1. EditText
  2. ListView

عند بدء EditText ، يكون ل EditText الفور تركيز الإدخال (مؤشر وامض). أنا لا أريد أي عنصر تحكم أن يكون المدخلات التركيز عند بدء التشغيل. حاولت:

EditText.setSelected(false);

لا حظ. كيف يمكنني إقناع EditText بعدم تحديد نفسه عند بدء Activity ؟




Answers


إجابات ممتازة من لوك ومارك ولكن عينة رمز جيد مفقود:

<!-- Dummy item to prevent AutoCompleteTextView from receiving focus -->
<LinearLayout
    android:focusable="true" 
    android:focusableInTouchMode="true"
    android:layout_width="0px" 
    android:layout_height="0px"/>

<!-- :nextFocusUp and :nextFocusLeft have been set to the id of this component
to prevent the dummy from receiving focus again -->
<AutoCompleteTextView android:id="@+id/autotext"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:nextFocusUp="@id/autotext" 
    android:nextFocusLeft="@id/autotext"/>



هي المشكلة الفعلية التي كنت لا تريد فقط أن يكون التركيز على الإطلاق؟ أو كنت لا تريد أن تظهر لوحة المفاتيح الافتراضية نتيجة لتركيز EditText ؟ لا أرى حقا مشكلة مع EditText مع التركيز على البداية، ولكن من المؤكد أن مشكلة فتح نافذة سوفتينبوت عندما لم يطلب المستخدم صراحة التركيز على EditText (وفتح لوحة المفاتيح كنتيجة).

إذا كانت مشكلة لوحة المفاتيح الظاهرية، فراجع وثائق عنصر AndroidManifest.xml <أكتيفيتي> .

android:windowSoftInputMode="stateHidden" - دائما إخفاء ذلك عند دخول النشاط.

أو android:windowSoftInputMode="stateUnchanged" - لا تغييره (على سبيل المثال لا تظهر إذا لم يتم عرضه بالفعل، ولكن إذا كان مفتوحا عند دخول النشاط، اتركه مفتوحا).




يوجد حل أبسط. تعيين هذه السمات في تخطيط الوالد:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainLayout"
    android:descendantFocusability="beforeDescendants"
    android:focusableInTouchMode="true" >

والآن، عندما يبدأ النشاط هذا التخطيط الرئيسي سيحصل التركيز بشكل افتراضي.

أيضا، يمكننا إزالة التركيز من وجهات نظر الطفل في وقت التشغيل (على سبيل المثال، بعد الانتهاء من تحرير الطفل) من خلال إعطاء التركيز على التخطيط الرئيسي مرة أخرى، مثل هذا:

findViewById(R.id.mainLayout).requestFocus();

تعليق جيد من غيوم بيروت :

android:descendantFocusability="beforeDescendants" يبدو أن الافتراضي (قيمة صحيح هو 0). يعمل فقط عن طريق إضافة android:focusableInTouchMode="true" .

حقا، يمكننا أن نرى أن beforeDescendants تعيين افتراضيا في طريقة ViewGroup.initViewGroup() (أندرويد 2.2.2). ولكن لا يساوي 0. ViewGroup.FOCUS_BEFORE_DESCENDANTS = 0x20000;

بفضل غيوم.




الحل الوحيد الذي عثرت عليه هو:

  • إنشاء لينيرلايوت (أنا دونو إذا أنواع أخرى من تخطيط سوف تعمل)
  • تعيين سمات android:focusable="true" android:focusableInTouchMode="true"

ولن يحصل EditText على التركيز بعد بدء النشاط




ويبدو أن المشكلة تأتي من خاصية لا أستطيع أن أرى إلا في XML form للتخطيط.

تأكد من إزالة هذا السطر في نهاية الإعلان ضمن EditText شمل:

<requestFocus />

وهذا ينبغي أن يعطي شيئا من هذا القبيل:

<EditText
   android:id="@+id/emailField"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:inputType="textEmailAddress">

   //<requestFocus /> /* <-- without this line */
</EditText>



باستخدام المعلومات التي قدمتها ملصقات أخرى، استخدمت الحل التالي:

في تخطيط شمل

<!-- Dummy item to prevent AutoCompleteTextView from receiving focus -->
<LinearLayout
    android:id="@+id/linearLayout_focus"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:layout_width="0px"
    android:layout_height="0px"/>

<!-- AUTOCOMPLETE -->
<AutoCompleteTextView
    android:id="@+id/autocomplete"
    android:layout_width="200dip"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dip"
    android:inputType="textNoSuggestions|textVisiblePassword"/>

في أونكريت ()

private AutoCompleteTextView mAutoCompleteTextView;
private LinearLayout mLinearLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mylayout);

    //get references to UI components
    mAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.autocomplete);
    mLinearLayout = (LinearLayout) findViewById(R.id.linearLayout_focus);
}

وأخيرا، في أونريسوم ()

@Override
protected void onResume() {
    super.onResume();

    //do not give the editbox focus automatically when activity starts
    mAutoCompleteTextView.clearFocus();
    mLinearLayout.requestFocus();
}



ما يلي سوف تتوقف إديتكست من اتخاذ التركيز عند إنشاء، ولكن الاستيلاء عليها عند لمسها.

<EditText
    android:id="@+id/et_bonus_custom"
    android:focusable="false" />

لذلك يمكنك تعيين فوكوسابل إلى كاذبة في شمل، ولكن المفتاح هو في جافا، والتي قمت بإضافة المستمع التالية:

etBonus.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        v.setFocusable(true);
        v.setFocusableInTouchMode(true);
        return false;
    }
});

لأنك تعود كاذبة، أي لا تستهلك الحدث، فإن سلوك التركيز المضي قدما مثل العادي.




محاولة كليارفوكوس () بدلا من setSelected(false) . كل رأي في الروبوت لديه كل من التركيز والانتقائية، وأعتقد أن كنت ترغب في مجرد مسح التركيز.




كنت قد حاولت الجواب سيرفال بشكل فردي ولكن التركيز لا يزال في إديتكست. أنا فقط إدارة لحلها باستخدام اثنين من الحل أعلاه معا.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/mainLayout"
  android:descendantFocusability="beforeDescendants"
  android:focusableInTouchMode="true" >

(مرجع من الفضة https://.com/a/8639921/15695 )

وإزالتها

 <requestFocus />

في إديتكست

(مرجع من فلويداديكت https://.com/a/9681809 )




لم يعمل أي من هذه الحلول بالنسبة لي. طريقة إصلاح التركيز التلقائي كانت:

<activity android:name=".android.InviteFriendsActivity" android:windowSoftInputMode="adjustPan">
    <intent-filter >
    </intent-filter>
</activity>



حل بسيط: في AndroidManifest في استخدام علامة Activity

android:windowSoftInputMode="stateAlwaysHidden"



يمكنك فقط تعيين "فوكوسابل" و "فوكوسابل في وضع اللمس" إلى قيمة حقيقية على TextView الأول layout . وبهذه الطريقة عندما يبدأ النشاط سوف تركز TextView ولكن نظرا لطبيعة، وسوف ترى أي شيء يركز على الشاشة، وبطبيعة الحال، لن يكون هناك لوحة المفاتيح المعروضة ...




عملت التالية بالنسبة لي في Manifest . كتابة ،

<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>



كنت بحاجة إلى مسح التركيز من جميع المجالات برمجيا. لقد أضفت البيانين التاليين إلى تعريفي الرئيسي للتخطيط.

myLayout.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
myLayout.setFocusableInTouchMode(true);

هذا هو. إصلاح مشكلتي على الفور. شكرا، الفضة، لافتا لي في الاتجاه الصحيح.




إضافة android:windowSoftInputMode="stateAlwaysHidden" في علامة النشاط من ملف Manifest.xml .

مصدر




جرب ذلك قبل الحقل الأول القابل للتعديل:

<TextView  
        android:id="@+id/dummyfocus" 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:text="@string/foo"
        />

----

findViewById(R.id.dummyfocus).setFocusableInTouchMode(true);
findViewById(R.id.dummyfocus).requestFocus();



إذا كان لديك عرض آخر على نشاطك مثل ListView ، يمكنك أيضا القيام بما يلي:

ListView.requestFocus(); 

في onResume() لانتزاع التركيز من editText .

وأنا أعلم أن هذا السؤال قد تم الإجابة ولكن مجرد توفير حل بديل الذي عملت بالنسبة لي :)




إضافة التالي في onCreate الأسلوب:

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);



وبما أنني لا أحب أن تلوث شمل مع شيء يتعلق بالوظيفة، أنا خلقت هذه الطريقة التي "بشفافية" يسرق التركيز من وجهة نظر التركيز الأولى ثم يتأكد من إزالة نفسه عند الضرورة!

public static View preventInitialFocus(final Activity activity)
{
    final ViewGroup content = (ViewGroup)activity.findViewById(android.R.id.content);
    final View root = content.getChildAt(0);
    if (root == null) return null;
    final View focusDummy = new View(activity);
    final View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener()
    {
        @Override
        public void onFocusChange(View view, boolean b)
        {
            view.setOnFocusChangeListener(null);
            content.removeView(focusDummy);
        }
    };
    focusDummy.setFocusable(true);
    focusDummy.setFocusableInTouchMode(true);
    content.addView(focusDummy, 0, new LinearLayout.LayoutParams(0, 0));
    if (root instanceof ViewGroup)
    {
        final ViewGroup _root = (ViewGroup)root;
        for (int i = 1, children = _root.getChildCount(); i < children; i++)
        {
            final View child = _root.getChildAt(i);
            if (child.isFocusable() || child.isFocusableInTouchMode())
            {
                child.setOnFocusChangeListener(onFocusChangeListener);
                break;
            }
        }
    }
    else if (root.isFocusable() || root.isFocusableInTouchMode())
        root.setOnFocusChangeListener(onFocusChangeListener);

    return focusDummy;
}



في وقت متأخر، ولكن ربما مفيدة. إنشاء إديتكست وهمية في الجزء العلوي من التخطيط ثم استدعاء myDummyEditText.requestFocus() في onCreate()

<EditText android:id="@+id/dummyEditTextFocus" 
android:layout_width="0px"
android:layout_height="0px" />

ويبدو أن هذا يتصرف كما أتوقع. لا حاجة للتعامل مع التغييرات التكوين، وما إلى ذلك كنت في حاجة هذا لنشاط مع تكستفيو طويلة (تعليمات).




نعم فعلت نفس الشيء - إنشاء "وهمية" التخطيط الخطي الذي يحصل التركيز الأولي. وعلاوة على ذلك، أنا وضعت "المقبل" معرفات التركيز بحيث لا يمكن للمستخدم التركيز عليه أكثر بعد التمرير مرة واحدة:

<LinearLayout 'dummy'>
<EditText et>

dummy.setNextFocusDownId(et.getId());

dummy.setNextFocusUpId(et.getId());

et.setNextFocusUpId(et.getId());

الكثير من العمل فقط للتخلص من التركيز على وجهة نظر ..

شكر




بالنسبة لي، ما يعمل على جميع الأجهزة هو هذا:

    <!-- fake first focusable view, to allow stealing the focus to itself when clearing the focus from others -->

    <View
    android:layout_width="0px"
    android:layout_height="0px"
    android:focusable="true"
    android:focusableInTouchMode="true" />

وضعت للتو هذا وجهة نظر قبل وجهة نظر مركزة مشكلة، وهذا كل شيء.




أبسط شيء فعلته هو تعيين التركيز على رأي آخر في أونكريت:

    myView.setFocusableInTouchMode(true);
    myView.requestFocus();

هذا توقف لوحة المفاتيح لينة الخروج وليس هناك مؤشر وامض في إديتكست.




هذا هو الحل المثالي والأكثر أسهل.أنا دائما استخدام هذا في بلدي التطبيق.

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);



في onCreate من النشاط الخاص بك، فقط إضافة استخدام clearFocus() على عنصر إديتكست الخاص بك. فمثلا،

edittext = (EditText) findViewById(R.id.edittext);
edittext.clearFocus();

وإذا كنت ترغب في تحويل التركيز إلى عنصر آخر، استخدم requestFocus() على ذلك. فمثلا،

button = (Button) findViewById(R.id.button);
button.requestFocus();



يمكنك تحقيق ذلك من خلال إنشاء EditText وهمية مع عرض تخطيط والارتفاع تعيين 0dp ، وطلب التركيز على هذا الرأي. أضف مقتطف الشفرة التالي في مخطط شمل:

<EditText
    android:id="@+id/editText0"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:hint="@string/dummy"
    android:ems="10" 
    >
     <requestFocus />
    </EditText>



تأكد من إزالة السطر "<requestFocus />" من علامة EditText في شمل.

<EditText
   android:id="@+id/input"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content">

   <requestFocus /> <!-- remove this line --> 
</EditText>



<TextView
    android:id="@+id/TextView01"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:singleLine="true"
    android:ellipsize="marquee"
    android:marqueeRepeatLimit="marquee_forever"
    android:focusable="true"
    android:focusableInTouchMode="true"
    style="@android:style/Widget.EditText"/>



يمكنني استخدام التعليمات البرمجية التالية لإيقاف إديتكست من سرقة التركيز عند الضغط على زر بلدي.

addButton.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        View focused = internalWrapper.getFocusedChild();
        focused.setVisibility(GONE);
        v.requestFocus();
        addPanel();
        focused.setVisibility(VISIBLE);
    }
});

قم بإخفاء نص التعديل ثم قم بعرضه مرة أخرى. هذا يعمل بالنسبة لي كما إديتكست ليست في الرأي لذلك لا يهم ما إذا كان يظهر.

يمكنك محاولة إخفاء وإظهاره في الخلافة لمعرفة ما إذا كان ذلك يساعد على فقدان التركيز.




/** 
 * set focus to top level window
 * disposes descendant focus 
 * disposes softInput 
 * */
public static void topLevelFocus(Context context){
    if(Activity.class.isAssignableFrom(context.getClass())){
        ViewGroup tlView = (ViewGroup) ((Activity) context).getWindow().getDecorView();
        if(tlView!=null){
            tlView.setFocusable(true);
            tlView.setFocusableInTouchMode(true);
            tlView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
        }
    }
}