অন্য নিয়ন্ত্রণে ফোকাস সেট না করে ফোকাস কীভাবে সরানো যায়?


98

আমি আমার ইউআইগুলি স্বজ্ঞাত হতে চাই; প্রতিটি স্ক্রিনের স্বাভাবিকভাবেই এবং অবিচ্ছিন্নভাবে অ্যাপ্লিকেশনটির পরবর্তী ধাপে ব্যবহারকারীকে গাইড করা উচিত। এটি বাদ দিয়ে আমি যতটা সম্ভব বিভ্রান্তিকর এবং বিভ্রান্তিকর জিনিসগুলি তৈরি করার চেষ্টা করি।

শুধু মজা করছি :-)

আমি তিনটি পেয়েছি TableRow, প্রত্যেকটিতে কেবল পঠনযোগ্য এবং অ-ফোকাসযোগ্য এডিটেক্সট নিয়ন্ত্রণ এবং তার ডানদিকে একটি বোতাম রয়েছে। প্রতিটি বোতাম একই ক্রিয়াকলাপ শুরু করে তবে একটি ভিন্ন যুক্তি দিয়ে। ব্যবহারকারী সেখানে একটি নির্বাচন করেন এবং উপ-কার্যকলাপ সমাপ্ত হয়, EditTextব্যবহারকারীর নির্বাচনের সাথে উপযুক্ত পপুলিং করে appropriate

এটি ক্লাসিক ক্যাসকেডিং মানগুলির প্রক্রিয়া; প্রতিটি নির্বাচন পরবর্তী নির্বাচনের জন্য উপলভ্য বিকল্পগুলি সঙ্কুচিত করে ইত্যাদি etc. সুতরাং আমি বর্তমান সারিতে সম্পাদনা পাঠ্যক্রমের মান না হওয়া পর্যন্ত পরবর্তী প্রতিটি সারিতে উভয় নিয়ন্ত্রণ অক্ষম করছি।

অগ্রাধিকারের এই ক্রমে আমাকে দুটি কাজের একটি করতে হবে:

  1. যখন একটি বোতাম ক্লিক করা হয়, ততক্ষণে অন্য কোনও বোতামে ফোকাস সেট না করেই ফোকাসটি সরিয়ে ফেলুন
  2. ক্রিয়াকলাপ শুরু হওয়ার পরে প্রথম বোতামটিতে ফোকাস সেট করুন

সাব-অ্যাক্টিভিটি ফিরে আসার পরে সমস্যাটি উদ্ভাসিত হয়; ক্লিক করা বোতামটি ফোকাস ধরে রাখে।

পুনরায়: উপরে # 1 - কোনও removeFocus()পদ্ধতি বা অনুরূপ কিছু বলে মনে হচ্ছে না

পুনরায়: উপরে # 2 - আমি requestFocus()পরের সারিটির বোতামটিতে ফোকাস সেট করতে ব্যবহার করতে পারি , এবং এটি উপ-কার্যকলাপ ফিরে আসার পরে কাজ করে তবে কোনও কারণে এটি পিতামাতার ক্রিয়াকলাপে কাজ করে নাonCreate()

আমার উভয় দিকেই ইউআই ধারাবাহিকতা দরকার - উপ-ক্রিয়াকলাপ শেষ হওয়ার পরে কোনও বোতাম ফোকাস করে না বা প্রতিটি বাটন কোনও নির্বাচনের আগে খুব প্রথম (এবং শুধুমাত্র) সক্রিয় বোতাম সহ লজিক প্রবাহে তার স্থানের উপর নির্ভর করে ফোকাস গ্রহণ করে।

উত্তর:


178

ক্লিয়ারফোকস () ব্যবহার করে আপনি যেমনটি পেয়েছেন তেমনই আমার পক্ষে কাজ করছে বলে মনে হচ্ছে না (অন্য উত্তরের মন্তব্যে দেখেছি), তবে শেষ পর্যন্ত আমার জন্য যা কাজ করেছে তা যুক্ত করছে:

<LinearLayout 
    android:id="@+id/my_layout" 
    android:focusable="true" 
    android:focusableInTouchMode="true" ...>

আমার একেবারে শীর্ষ স্তরের লেআউট ভিউতে (একটি রৈখিক বিন্যাস)। সমস্ত বোতাম / সম্পাদনাটেক্সটস ইত্যাদি থেকে ফোকাস সরাতে, আপনি কেবল তাই করতে পারেন

LinearLayout myLayout = (LinearLayout) activity.findViewById(R.id.my_layout);
myLayout.requestFocus();

ফোকাসের জন্য অনুরোধ করা কিছুই করা হয়নি যতক্ষণ না আমি দৃশ্যের দৃষ্টি নিবদ্ধযোগ্য হিসাবে সেট করি।


একটি ক্ষণস্থায়ী মুহুর্তের জন্য আমি ভেবেছিলাম এটি কার্যকর হতে পারে। "এর সরলতায় কত সুন্দর!" আমি নিজেকে বলেছিলাম. হায়রে, এটা হতে পারে না। এমনকি যখন আমি অনুরোধফোকাস () সরিয়ে ফেলি তখনও পরবর্তী সারির বোতামটি ফোকাস হয়ে যায়। এটি দ্বিতীয় পছন্দ হিসাবে ঠিক হবে, তবে আমি যদি কেবল কোনওভাবে অনক্রিট () এর প্রথম বোতামটিতে ফোকাস সেট করতে পারি।
ইনটেক্সএক্স

@ ইনটেক্সএক্স: আমি আজ আবার এই সমস্যার মুখোমুখি হয়েছি এবং এর সমাধান খুঁজে পেয়েছি। আমি জানি আপনি এখন অন্য কোনও রুটে নেমে গেছেন, তবে যদি আবার কখনও একই নৌকায় নিজেকে খুঁজে পান তবে এটি চেষ্টা করে দেখুন!
ক্রিয়াকলাপ

"আমি জানি আপনি এখন অন্য কোনও রুটে নেমে গেছেন" ব্যাক আপ নিতে এখনও খুব বেশি দেরি হয়নি :-) আমি চেষ্টা করে দেখব, ধন্যবাদ।
ইনটেক্সএক্স

ডার্ন প্রায়, কিন্তু বেশ না। হ্যাঁ, এটি সর্বশেষ-ক্লিক করা বোতামটি ফোকাস নেয়, তবে এটি পরে কোনও বোতাম ফোকাস পেতে বাধা দেয়। এর অর্থ হ'ল আমার অ-টাচ ব্যবহারকারীরা কোনও বোতামটি ক্লিক করতে পারবেন না। এটা কি আপনার জন্য একই করছে?
ইনটেক্সএক্স

6
এটি স্ক্রোলভিউতে কাজ করবে না। আপনার শীর্ষ দৃশ্যটি যদি স্ক্রোলভিউ হয় তবে এটির সন্তানের উপর এটি ব্যবহার করুন।
উরো পোডক্রিয়নিক

81

পুরানো প্রশ্ন, তবে আমার যখন একইরকম সমস্যা হয়েছে তখন আমি তা জুড়ে এসেছি এবং ভেবেছিলাম যে আমি কী শেষ করব তা ভাগ করে নেব।

ফোকাস অর্জন করা ভিউ প্রতিটি সময় আলাদা ছিল তাই আমি খুব জেনেরিক ব্যবহার করেছি:

View current = getCurrentFocus();
if (current != null) current.clearFocus();

12
এটি করার মার্জিত উপায়। যে কেউ ক্লিয়ারফোকস () কল করার আগে getCurrentFocus () থেকে নালীর একটি মান পরীক্ষা করতে চাইতে পারে
ভেরিং

4
+1 হ্যাঁ, আপনাকে সেই নাল চেকে ফেলে দিতে হবে! - জাভা কেন কেবল কোনও নিরাপদ-ট্র্যাভারসাল-অপারেটর প্রয়োগ করতে পারে না? এটি যতটা সহজ getCurrentFocus()?.clearFocus();, এত সুন্দর এবং মার্জিত হবে: - /
লেভাইট

4
@ উইল্লমা: হ্যাঁ, এটাই আমার অর্থ হ'ল
ভেরিং

5
পছন্দ করুন :-) তবে জাভা যদি এমন কোনও অপারেটর বাস্তবায়ন করে তবে অ্যান্ড্রয়েডটি ধরতে এখনও 4 বছর লাগবে।
গ্রেগ ব্রাউন

4
@ লিভিট, আপনি সম্ভবত এটি এখনই খুঁজে পেয়েছেন, তবে কোটলিন।
প্রোদিয়া

9
  1. আপনি ব্যবহার করতে পারেন View.clearFocus()

  2. View.requestFocus()থেকে ডাকা ব্যবহার করুন onResume()


@ সিলিকোনাগল: এখন এটি খুব অদ্ভুত। (ক্লিয়ারফোকস () বিটিডব্লিউটির পয়েন্টারটির জন্য ধন্যবাদ - আমি এটি সম্পর্কে অবগত ছিলাম না) আমি যখন প্রথম বোতামটি ক্লিক করি তখন একটি নির্বাচন করে, এবং তারপরে ফিরে আসি, প্রথম বোতামটি আর ফোকাস পেতে পারে না। আমি আমার কোডের কোথাও এই বোতামটির জন্য ফোকাসযোগ্য সেট করে দিচ্ছি না। আমি আপনাকে আমার কোডটি দেখাতে চাই, তবে এই সম্পাদনা উইন্ডোতে পর্যাপ্ত অক্ষর নেই এবং তাই নতুন হওয়াতে আমি ঠিক কোড পোস্ট করতে সক্ষম হতে অন্য উত্তরটি প্রবেশ করানো উচিত কিনা তা নিশ্চিত নই।
ইনটেক্সএক্স

@ সিলিকোনাগল: দুর্ভাগ্যক্রমে ক্লিয়ারফোকস () কাজ করে না - সাব-অ্যাক্টিভিটি ফিরে আসার সময় বোতামগুলি ফোকাস ধরে রাখে।
ইনটেক্সএক্স

@ সিলিকোনাগল: ঠিক আছে, প্রথম মন্তব্যটি নিয়ে কিছু মনে করবেন না। আমি বোতামের ক্লিক ইভেন্টে সেটফোকসযোগ্য (মিথ্যা) ব্যবহার করছি এবং উপ-কার্যকলাপ ফিরে আসার পরে এটি আবার চালু করতে ভুলে যাচ্ছিলাম। ক্লিয়ারফোকাস () এর এখনও কোনও প্রভাব নেই - কেন আমি ভাবছি? আমিঅ্যাক্টিভিটিস রেজাল্ট () থেকে সমস্ত বোতামে এটি কল করছি, তবে ক্লিক করা বোতামটি এখনও ফোকাসটি ধরে রেখেছে। অস্বাভাবিক.
ইনটেক্সএক্স 1

@ সিলিকোনাগল: @ অ্যাকশনশ্রিম্প: আমি ফোকাস-সংক্রান্ত সমস্ত কমান্ড এবং সেটিংস মুছে ফেলার সিদ্ধান্ত নিয়েছি। আমার আসল উদ্দেশ্যটি ছিল অক্ষম বোতামগুলিতে ফোকাস প্রতিরোধ করা, তবে এটি যদি এটির জন্য ব্যয় করে তবে এটি মূল্য হয় না। কোনও অনুরোধের সাথে ফোকাস (), ক্লিয়ারফোকস () বা সেটফোকাসেবল () নেই, সাব-অ্যাক্টিভিটি ফেরার পরে কোনও বোতাম ফোকাস ধরে রাখে না। এটি দু'টি সপ্তাহের চেয়ে কম - আমার ধারণা আমি ব্যবহারকারীকে একটি অক্ষম বোতামটিতে ফোকাস সেট করতে সক্ষম হয়ে থাকতে পারি।
ইনটেক্সএক্স 1

অক্ষম উপাদান focusable আমি যতদূর জানি ... ব্যবহার (মিথ্যা) setEnabled নেই
siliconeagle

9

android:descendantFocusability="beforeDescendants"

নীচে কিছু বিন্যাস বিকল্পের সাথে ক্রিয়াকলাপে নিম্নলিখিতটি ব্যবহার করা পছন্দসই হিসাবে কাজ করেছে বলে মনে হচ্ছে।

 getWindow().getDecorView().findViewById(android.R.id.content).clearFocus();

রুট ভিউতে নিম্নলিখিত পরামিতিগুলির সাথে সম্পর্কিত।

<?xml
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:descendantFocusability="beforeDescendants" />

https://developer.android.com/references/android/view/ViewGroup#attr_android:descendantFocusability

উত্তর ধন্যবাদ: https://forums.xamarin.com/discussion/1856/how-to-disable-auto-focus-on-edit-text

উইন্ডোসফট ইনপুটমোড সম্পর্কে

সচেতন হওয়ার মতো আরও একটি বিতর্ক রয়েছে। ডিফল্টরূপে, অ্যান্ড্রয়েড স্বয়ংক্রিয়ভাবে আপনার ক্রিয়াকলাপের প্রথম সম্পাদনা পাঠ্য বা ফোকাসযোগ্য নিয়ন্ত্রণের জন্য প্রাথমিক ফোকাস বরাদ্দ করবে। এটি স্বাভাবিকভাবে অনুসরণ করে যে ইনপুটমেথড (সাধারণত সফ্ট কীবোর্ড) নিজেই দেখিয়ে ফোকাস ইভেন্টটিতে প্রতিক্রিয়া জানায়। অ্যান্ড্রয়েড ম্যানিফেস্ট.এক্সএমএলে উইন্ডোসফট ইনপুটমোড অ্যাট্রিবিউট, যখন স্টেট অলওয়েজহিডে সেট করা থাকে, তখন স্বয়ংক্রিয়ভাবে নির্ধারিত প্রাথমিক ফোকাসটিকে উপেক্ষা করার জন্য কীবোর্ডকে নির্দেশ দেয়।

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

দুর্দান্ত রেফারেন্স


6
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          android:id="@+id/ll_root_view"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical">

LinearLayout llRootView = findViewBindId(R.id.ll_root_view);
llRootView.clearFocus();

আমি ইতিমধ্যে প্রোফাইল তথ্য আপডেট শেষ হয়ে গেলে এবং আমার বিন্যাসের এডিটেক্সট থেকে সমস্ত ফোকাস অপসারণ করি

====> আপডেট: প্যারেন্ট লেআউট কনটেন্টে আমার এডিট টেক্সট যুক্ত লাইন:

android:focusableInTouchMode="true"

3

android:windowSoftInputMode="stateHidden"ম্যানিফেস্টে আপনার ক্রিয়াকলাপে কেবল যুক্ত করার বিষয়ে।

এই বিষয়ে মন্তব্য করা কোনও স্মার্ট লোক থেকে নেওয়া: https://stackoverflow.com/a/2059394/956975


3

আমি দেখার জন্য দৃষ্টি নিবদ্ধযোগ্যতা অক্ষম করার এবং সক্ষম করার চেষ্টা করেছি এবং এটি আমার জন্য কাজ করেছে (ফোকাসটি পুনরায় সেট করা হয়েছিল):

focusedView.setFocusable(false);
focusedView.setFocusableInTouchMode(false);
focusedView.setFocusable(true);
focusedView.setFocusableInTouchMode(true);

2

প্রথমত, এটি 100% কাজ করবে ........

  1. onResume()পদ্ধতি তৈরি করুন ।
  2. এর ভিতরে onResume()এমন দৃশ্যটি খুঁজে বার করুন যা বার বার ফোকাস করছেfindViewById()
  3. এই দৃশ্যে এই onResume()সেটটির ভিতরে requestFocus()
  4. এই দৃশ্যে এই onResume()সেটটির ভিতরে clearFocus
  5. একই লেআউটের এক্সএমএল এ যান এবং সেই শীর্ষ দৃশ্যটি সন্ধান করুন যা আপনি মনোনিবেশ করতে চান এবং focusableসত্য এবং focusableInTuchসত্য সেট করতে চান ।
  6. onResume()এটি ভিতরে উপরের শীর্ষে দেখুন দ্বারাfindViewById
  7. সর্বশেষে এই দর্শনটিতে এই onResume()সেটটির ভিতরে requestFocus()
  8. এবং এখন উপভোগ করুন ......

2
android:focusableInTouchMode="true"
android:focusable="true"
android:clickable="true"

এডিট করুন আপনার ভিউগ্রুপে যা এতে আপনার এডিটেক্সটভিউ অন্তর্ভুক্ত রয়েছে। এটি আমার সীমাবদ্ধ বিন্যাসে সঠিকভাবে কাজ করে। এই সাহায্য আশা করি


1

আপনি মূল ক্রিয়াকলাপের রাজ্যটি সংরক্ষণ করার ক্ষমতাটি বন্ধ করার চেষ্টা করতে পারেন (এটি এটিকে ভুলে যায় যে কী নিয়ন্ত্রণে কী পাঠ্য ছিল এবং কী ফোকাস করেছিল)। আপনার এডিটেক্সট এর কী আছে তা মনে রাখার এবং সেগুলি পুনরায় চালু করুন () পুনরায় স্থাপনের আপনার অন্য কিছু উপায় থাকতে হবে। আপনার উপ-ক্রিয়াকলাপগুলিকে স্টার্টঅ্যাক্টিভিটি ফর রিসাল্ট () দিয়ে চালু করুন এবং আপনার মূল ক্রিয়াকলাপে একটি onActivityResult () হ্যান্ডলার তৈরি করুন যা সম্পাদনা পাঠকে সঠিকভাবে আপডেট করবে। আপনি যে পদ্ধতিতে ফোকাস করতে চান সেটি যথাযথভাবে সেট করতে পারেন আপনি একই সাথে আপনি MyButton.post (নতুন রান্নেবল () {রান () {myButton.requestFocus ();}}) ব্যবহার করে সম্পাদনা পাঠ্য পুনরায় তৈরি করতে পারেন;

ভিউ.পোস্ট () পদ্ধতিটি প্রাথমিকভাবে ফোকাস সেট করার জন্য দরকারী কারণ উইন্ডোটি তৈরি হওয়ার পরে জিনিসগুলি স্থির হয়ে যাওয়ার পরে রান্নেবল কার্যকর করা হবে, ফোকাস প্রক্রিয়াটি সেই সময়ের মধ্যে সঠিকভাবে কাজ করতে দেয়। অনক্রিট / স্টার্ট / পুনঃসূচনা () এর সময় ফোকাস সেট করার চেষ্টা করার ক্ষেত্রে সাধারণত সমস্যা থাকে, আমি খুঁজে পেয়েছি।

দয়া করে নোট করুন এটি সিউডো কোড এবং অ-পরীক্ষিত, তবে এটি আপনি সম্ভবত চেষ্টা করতে পারেন এমন একটি সম্ভাব্য দিক।


দ্বিতীয় চিন্তার বিষয়ে ... ক্রিয়াকলাপের সংরক্ষিত অবস্থা বন্ধ না করে প্রথমে ভিউ.পস্ট () স্টাফ ব্যবহার করার চেষ্টা করুন। এটি নিজেই আপনার জন্য কৌশলটি করতে পারে।
চাচা কোড বানর

হায়রে আমাদের কাছে এটি পরীক্ষা করার সহজ উপায় আর নেই। আমি তখন থেকে নেটিভ কোডের মডেলটি পরিত্যাগ করার এবং মোবাইল অ্যাপ্লিকেশনগুলির জন্য এইচটিএমএল 5 / সিএসএস 3 এর সাথে যাওয়ার সিদ্ধান্ত নিয়েছি এবং এইভাবে আমার সিস্টেমটিকে সেই অনুযায়ী পুনরায় তৈরি করেছি। তবে যা আপনাকে খুব গভীরভাবে উত্তর বলে মনে হচ্ছে তার জন্য আপনাকে ধন্যবাদ। আমি এটা ভোট দিয়েছি।
ইন্টেক্সএক্স

0

নিম্নলিখিত চেষ্টা করুন (কলিং clearAllEditTextFocuses();)

private final boolean clearAllEditTextFocuses() {
    View v = getCurrentFocus();
    if(v instanceof EditText) {
        final FocusedEditTextItems list = new FocusedEditTextItems();
        list.addAndClearFocus((EditText) v);

        //Focus von allen EditTexten entfernen
        boolean repeat = true;
        do {
            v = getCurrentFocus();
            if(v instanceof EditText) {
                if(list.containsView(v))
                    repeat = false;
                else list.addAndClearFocus((EditText) v);
            } else repeat = false;
        } while(repeat);

        final boolean result = !(v instanceof EditText);
        //Focus wieder setzen
        list.reset();
        return result;
    } else return false;
}

private final static class FocusedEditTextItem {

    private final boolean focusable;

    private final boolean focusableInTouchMode;

    @NonNull
    private final EditText editText;

    private FocusedEditTextItem(final @NonNull EditText v) {
        editText = v;
        focusable = v.isFocusable();
        focusableInTouchMode = v.isFocusableInTouchMode();
    }

    private final void clearFocus() {
        if(focusable)
            editText.setFocusable(false);
        if(focusableInTouchMode)
            editText.setFocusableInTouchMode(false);
        editText.clearFocus();
    }

    private final void reset() {
        if(focusable)
            editText.setFocusable(true);
        if(focusableInTouchMode)
            editText.setFocusableInTouchMode(true);
    }

}

private final static class FocusedEditTextItems extends ArrayList<FocusedEditTextItem> {

    private final void addAndClearFocus(final @NonNull EditText v) {
        final FocusedEditTextItem item = new FocusedEditTextItem(v);
        add(item);
        item.clearFocus();
    }

    private final boolean containsView(final @NonNull View v) {
        boolean result = false;
        for(FocusedEditTextItem item: this) {
            if(item.editText == v) {
                result = true;
                break;
            }
        }
        return result;
    }

    private final void reset() {
        for(FocusedEditTextItem item: this)
            item.reset();
    }

}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.