एक और टुकड़े के मुद्दे पर निराशा


271

जब मैं एक टुकड़े (जो #77000000पृष्ठभूमि के साथ पूर्ण स्क्रीन है ) को दिखा रहा हूं, तो एक अन्य टुकड़े पर (चलो इसे मुख्य कहते हैं), मेरा मुख्य टुकड़ा अभी भी क्लिकों पर प्रतिक्रिया करता है (हम एक बटन क्लिक कर सकते हैं, भले ही हम इसे न देखें)।

प्रश्न : पहले (मुख्य) टुकड़े पर क्लिक को कैसे रोका जाए?

संपादित करें

दुर्भाग्य से, मैं सिर्फ मुख्य टुकड़े को छिपा नहीं सकता, क्योंकि मैं दूसरे टुकड़े पर पारदर्शी पृष्ठभूमि का उपयोग कर रहा हूं (इसलिए, उपयोगकर्ता देख सकता है कि पीछे क्या स्थित है)।


आपने हमें किसके साथ काम करने के लिए दिया था, इसके आधार पर आपको Visibilityअपना उपयोग main Fragmentकरने की कोशिश करनी चाहिए GONEजब आप इसका उपयोग नहीं कर रहे हों।
19

1
यह देखे बिना कि आप अपने ऑनक्लिक्ड तरीके को कैसे लागू करते हैं, मुझे लगता है कि जब आप क्लिक कर रहे हैं तो आप "झूठे" वापस आ रहे हैं।
डीईवी

@DeeV, onClickविधि कुछ भी नहीं लौटाती है। लेकिन आप एक विचार देते हैं, धन्यवाद (मैं जल्द ही उत्तर पोस्ट करूंगा)।
दिमित्री ज़ेत्सेव

1
डी 'ओह। आप सही हे। onTouch इसे वापस करता है। मेरी इच्छा है कि मैं समझ गया कि एक स्पर्श घटना एक खंड के माध्यम से क्यों गिर गई। ऐसा नहीं करना चाहिए यदि आप स्पर्श इवेंट जारी नहीं कर रहे हैं।
डीईवी

@DeeV, ऐसा लगता है कि यदि आपका दृश्य (उदाहरण के लिए, दूसरे के शीर्ष पर) onTouch ईवेंट को नहीं पकड़ता है, तो सिस्टम उसी निर्देशांक के साथ अन्य दृश्यों की खोज जारी रखता है।
दिमित्री ज़ेत्सेव

जवाबों:


578

clickableदूसरे टुकड़े के गुण को सत्य पर सेट करें । दृश्य घटना को पकड़ लेगा ताकि इसे मुख्य टुकड़े में पारित नहीं किया जाएगा। इसलिए यदि दूसरा टुकड़ा का दृश्य एक लेआउट है, तो यह कोड होगा:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clickable="true" />

4
इसने मेरे लिए काम किया। यह ऊपर दिए गए समाधान @Dmitry जैतसेव की तुलना में आसान लगता है। क्या कोई कारण है कि यह एक बुरा विचार होगा? मैं किसी के बारे में सोच भी नहीं सकता, लेकिन मैं सिर्फ यकीन करना चाहता हूं।
एरिएट्स

1
यह मेरे लिए काम नहीं किया। मेरे पास एक RelativeLayoutटुकड़ा है, और मैंने clickeableसंपत्ति के साथ पूरा दृश्य निर्धारित किया है। @Dmitry का समाधान मेरी समस्या का समाधान करता है।
4gus71n

3
इसने मेरे लिए काम किया। एंड्रॉइड में "क्लिक करने योग्य" जाहिरा तौर पर कुछ हद तक iOS '"userInteractionEnabled" की तरह है
mvds

17
एंड्रॉइड हमें कठोर कोडिंग शर्तों के अधीन क्यों करता है ?!
लो-टैन

1
मैं ViewPager के साथ एक ही मुद्दा रहा हूँ। जब मैं पहले पृष्ठ पर स्क्रॉल करता हूं, तो यह दूसरे पृष्ठ पर भी पहुंच जाता है, और यह समाधान मेरे लिए काम नहीं करता है। कोई विचार?
गोचन अरिंक

72

समाधान बहुत सरल है। हमारे दूसरे टुकड़े में (जो हमारे मुख्य टुकड़े को ओवरलैप करता है) हमें बस onTouchघटना को पकड़ने की जरूरत है :

@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstance){
    View root = somehowCreateView();

    /*here is an implementation*/

    root.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            return true;
        }
    });
    return root;
}

आपके समाधान ने उसके लिए +1 काम किया लेकिन क्या आप मुझे बता सकते हैं कि हमें यह स्पष्ट रूप से करने की आवश्यकता क्यों है?
हंट

@ आप की जरूरत नहीं है यह करने के लिए सिर्फ एक और तरीका है (स्वीकृत उत्तर देखें)
दिमित्री ज़ेत्सेव

Android: अपने दूसरे टुकड़े के xml मुख्य लेआउट पर क्लिक करने योग्य = "सत्य"।
ऋषभ श्रीवास्तव

इस समाधान के साथ एक समस्या है, जब आप एक्सेसिबिलिटी टॉकबैक मोड ऑन करते हैं, तो यह व्यक्तिगत तत्वों को नहीं पढ़ेगा, इसके बजाय रूट व्यू पर ध्यान केंद्रित करता है।
अमित गर्ग

कोटलीन संस्करण: root.setOnTouchListener {_, _ -> true}
गैल रोम

21

बस जोड़ें clickable="true"और focusable="true"मूल लेआउट के लिए

 <android.support.constraint.ConstraintLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:clickable="true"
      android:focusable="true">

      <!--Your views-->

 </android.support.constraint.ConstraintLayout>

यदि आप उपयोग कर रहे हैं AndroidX, तो यह प्रयास करें

 <androidx.constraintlayout.widget.ConstraintLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:clickable="true"
      android:focusable="true">

          <!--Your views-->

 </androidx.constraintlayout.widget.ConstraintLayout>

क्या यह किसी तरह से स्वीकृत उत्तर से अलग है? focuseableवास्तव में आवश्यक नहीं है।
दिमित्री ज़ेत्सेव

2
मुझे लगता focusable="true"है कि यहां केवल एंड्रॉइड स्टूडियो में एक चेतावनी से बचने के लिए है।
आर्टेम एम।

9

जब आप दो टुकड़े एक ही कंटेनर दृश्य में रखा जाता है, तो आपको दूसरा टुकड़ा दिखाते समय पहले टुकड़े को छिपाना चाहिए।

यदि आप Fragment के बारे में समस्याओं को हल करने के बारे में अधिक प्रश्न जानना चाहते हैं, तो आप मेरी लाइब्रेरी देख सकते हैं: https://github.com/JustKiddingBaby/FragmentRigger

FirstFragment firstfragment;
SecondFragment secondFragment;
FragmentManager fm;
FragmentTransaction ft=fm.beginTransaction();
ft.hide(firstfragment);
ft.show(secondFragment);
ft.commit();

1
यह सही उत्तर होना चाहिए! श्रीमान धन्यवाद। मैंने इस प्रश्न को किसी अन्य प्रोजेक्ट पर हल किया है। लेकिन मैं भूल गया हूं कि मैंने इसे कैसे हल किया और आखिरकार, मुझे आपका जवाब मिल गया। धन्यवाद।
लाइसैट जूलियस

1
मुझे नहीं लगता कि यह सही समाधान है। खंड / गतिविधियाँ एक दृश्य स्टैक में काम करती हैं। आपको कॉल करना होगा। शीर्ष खंड के पॉप-अप होने के बाद फिर से .show, जिसका अर्थ है कि नीचे के टुकड़े को सूचित किया जाना शीर्ष शीर्ष पर चला गया है। इसे बनाए रखने के लिए अतिरिक्त तर्क जोड़ा गया है।
XY

4

आप के android:focusable="true"साथ जोड़ने की जरूरत है android:clickable="true"

Clickable इसका मतलब है कि यह एक पॉइंटर डिवाइस द्वारा क्लिक किया जा सकता है या एक टच डिवाइस द्वारा टैप किया जा सकता है।

Focusableइसका मतलब है कि यह कीबोर्ड की तरह इनपुट डिवाइस से फोकस हासिल कर सकता है। कीबोर्ड जैसे इनपुट डिवाइस यह तय नहीं कर सकते हैं कि इनपुट के आधार पर अपनी इनपुट घटनाओं को किस दृश्य को भेजें, इसलिए वे उन्हें उस दृश्य पर भेजते हैं जिस पर फोकस है।


2
और ध्यान देने योग्य = "सही" नए एंड्रॉइड स्टूडियो में चेतावनी से बचने के लिए आवश्यक है
होसाम हसन

2

एक से अधिक समाधान है कि हम में से कुछ ने इस धागे में योगदान दिया है, लेकिन मैं एक दूसरे समाधान का भी उल्लेख करना चाहूंगा। यदि आप मेरे जैसे XML में हर लेआउट के मूल ViewGroup के लिए क्लिक करने योग्य और ध्यान देने योग्य समान नहीं लगाते फैंसी। आप इसे अपने आधार पर भी डाल सकते हैं यदि आपके पास नीचे की तरह एक है;

override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ) : View? {
        super.onCreateView(inflater, container, savedInstanceState)

        val rootView = inflater.inflate(layout, container, false).apply {
            isClickable = true
            isFocusable = true
        }

        return rootView
    }

आप इनलाइन वैरिएबल का भी उपयोग कर सकते हैं लेकिन मैंने इसे अपने कारणों से पसंद नहीं किया।

मुझे आशा है कि यह लेआउट XMLs से नफरत करने वालों के लिए मदद करता है।


1

स्वीकार्य उत्तर "काम" करेगा, लेकिन प्रदर्शन लागत (ओवरड्रॉ, अभिविन्यास परिवर्तन पर फिर से मापने) का कारण भी होगा क्योंकि तल पर टुकड़ा अभी भी खींचा जा रहा है। हो सकता है कि आपको केवल टैग या आईडी द्वारा टुकड़ा मिल जाए और जब आपको फिर से दिखाने की आवश्यकता हो, तो GONE या VISIBLE पर दृश्यता सेट करें।

कोटलिन में:

fragmentManager.findFragmentByTag(BottomFragment.TAG).view.visibility = GONE

जब आप एनिमेशन का उपयोग करते हैं तो यह समाधान वैकल्पिक hide()और show()तरीकों के लिए बेहतर होता है FragmentTransaction। आप इसे onTransitionStart()और onTransitionEnd()के से कहते हैं Transition.TransitionListener


1

मेटोड 1:

आप सभी टुकड़े लेआउट में जोड़ सकते हैं

android:clickable="true"
android:focusable="true"
android:background="@color/windowBackground"

मेटोड 2: (प्रोग्रामिक रूप से)

FragmentBaseआदि से सभी टुकड़े बढ़ाएँ । फिर इस कोड को इसमें जोड़ेंFragmentBase

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    getView().setBackgroundColor(getResources().getColor(R.color.windowBackground));
    getView().setClickable(true);
    getView().setFocusable(true);
}

0

आप क्या कर सकते हैं u आप उस मुख्य टुकड़े के मूल लेआउट पर onClick संपत्ति का उपयोग करके पिछले टुकड़े के लेआउट को एक ब्लैंक क्लिक दे सकते हैं और गतिविधि में आप एक फ़ंक्शन बना सकते हैं doNothing(View view)और इसमें कुछ भी नहीं लिख सकते हैं। यह आपके लिए यह कर देगा।


0

यह डायलॉगफ्रेममेंट के लिए एक मामले की तरह लगता है। अन्यथा फ्रैगमेंट मैनेजर एक छिपाने के लिए और दूसरा दिखाने के लिए प्रतिबद्ध है। वह मेरे लिए काम कर चुका है।


0

android:clickable="true"मेरे लिए जोड़ने का काम नहीं किया। यह समाधान समन्वयक पर काम नहीं करता है जब यह एक मूल लेआउट है। इसलिए मैंने RelativeLayout को पैरेंट लेआउट के रूप में बनाया है, इसमें जोड़ा android:clickable="true"और CoordinatorLayout को इस RelativeLayout पर रखा।


0

मेरे पास एक ही एमएलएम के साथ कई टुकड़े थे।
घंटों बिताने के बाद, मैंने हटा दिया setPageTransformerऔर इसने काम करना शुरू कर दिया

   //  viewpager.setPageTransformer(false, new BackgPageTransformer())

मेरे पास तर्क-वितर्क था।

public class BackgPageTransformer extends BaseTransformer {

    private static final float MIN_SCALE = 0.75f;

    @Override
    protected void onTransform(View view, float position) {
        //view.setScaleX Y
    }

    @Override
    protected boolean isPagingEnabled() {
        return true;
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.