টুকরাগুলির মধ্যে এক্সএমএল অনক্লিক ব্যবহার করে কীভাবে বোতাম ক্লিকগুলি হ্যান্ডেল করবেন


440

প্রাক-হানিকম্ব (অ্যান্ড্রয়েড 3), প্রতিটি ক্রিয়াকলাপ onClickএকটি লেআউটের এক্সএমএলে ট্যাগের মাধ্যমে বোতাম ক্লিকগুলি পরিচালনা করতে নিবন্ধিত হয়েছিল :

android:onClick="myClickMethod"

এই পদ্ধতির মধ্যে আপনি ব্যবহার করতে পারেন view.getId()এবং বোতাম যুক্তি করতে একটি স্যুইচ স্টেটমেন্ট।

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

final Button button = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        // Perform action on click
    }
});

সমস্যাটি হ'ল যখন আমার লেআউটটি স্ফীত হয় তবে এটি হোস্টিং ক্রিয়াকলাপ যা বাটন ক্লিকগুলি প্রাপ্ত করে, স্বতন্ত্র খণ্ডগুলি নয়। উভয় একটি ভাল পদ্ধতির আছে কি

  • বোতাম ক্লিকগুলি পেতে টুকরাটি নিবন্ধন করবেন?
  • ক্লিক ইভেন্টগুলি ক্রিয়াকলাপ থেকে তারা যে খণ্ডটির সাথে সম্পর্কিত?

1
আপনি কি এই খণ্ডটির অনক্রিটের মধ্যে নিবন্ধিত শ্রোতাদের পরিচালনা করতে পারবেন না?
সিএল

24
@ জডস হ্যাঁ, তবে আমি ব্যবহার করতে চাই না setOnClickListenerএবং findViewByIdপ্রতিটি বোতামের জন্য, তাই যুক্ত onClickকরা হয়েছিল, জিনিসগুলিকে আরও সহজ করে তুলতে।
স্মিথ 324

4
গৃহীত উত্তরের দিকে তাকিয়ে আমি মনে করি সেটঅনলিক্লিকলিস্টার ব্যবহার করা এক্সএমএল অনক্লিক পদ্ধতির সাথে আঁকড়ে থাকার চেয়ে আরও আলগাভাবে মিলিত। ক্রিয়াকলাপটি যদি প্রতিটি ক্লিককে সঠিক খণ্ডে 'ফরোয়ার্ড' করতে হয় তবে এর অর্থ হ'ল প্রতি বার একটি খণ্ড যুক্ত হওয়ার সাথে কোডটি পরিবর্তন করতে হবে। খণ্ডের বেস শ্রেণি থেকে ডিকুয়াল করতে একটি ইন্টারফেস ব্যবহার করা এতে সহায়তা করে না। যদি খণ্ডটি সঠিক বোতামের সাথে নিবন্ধিত হয় তবে ক্রিয়াকলাপটি পুরোপুরি অজ্ঞেয় থেকে যায় যা আরও ভাল স্টাইলের আইএমও। অ্যাডরজন প্রিনক্জের উত্তরও দেখুন।
অ্যাড্রিয়ান কোস্টার

@ স্মিথ ৩৪৪ এর সাথে আদ্রিয়ানের সাথে একমত হতে হবে। অ্যাডোরজানের উত্তরটি দেখুন এবং দেখুন এর পরে জীবন আর ভাল হয় না।
ব্যবহারকারী 1567453

উত্তর:


175

আপনি কেবল এটি করতে পারেন:

কার্যক্রম:

Fragment someFragment;    

//...onCreate etc instantiating your fragments

public void myClickMethod(View v) {
    someFragment.myClickMethod(v);
}

টুকরা:

public void myClickMethod(View v) {
    switch(v.getId()) {
        // Just like you were doing
    }
}    

@ আমেনের জবাবে যারা কম সংযোগ চেয়েছিলেন তাই খণ্ডগুলি পুনরায় ব্যবহারযোগ্য

ইন্টারফেস:

public interface XmlClickable {
    void myClickMethod(View v);
}

কার্যক্রম:

XmlClickable someFragment;    

//...onCreate, etc. instantiating your fragments casting to your interface.
public void myClickMethod(View v) {
    someFragment.myClickMethod(v);
}

টুকরা:

public class SomeFragment implements XmlClickable {

//...onCreateView, etc.

@Override
public void myClickMethod(View v) {
    switch(v.getId()){
        // Just like you were doing
    }
}    

52
এটি এখন আমি মূলত যা করছি তা কিন্তু যখন আপনার একাধিক টুকরো থাকে প্রতিটি ক্লিক ইভেন্টগুলি গ্রহণ করার প্রয়োজন হয় তখন এটি অনেকটা মেসওয়্যার হয়। আমি কেবল সাধারণভাবে টুকরো টুকরোগুলি হয়ে পড়েছি কারণ দৃষ্টান্তগুলি তাদের চারপাশে দ্রবীভূত হয়েছে।
স্মিথ 324

128
আমি একই সমস্যাটিতে চলেছি, এবং আমি আপনার প্রতিক্রিয়াটির প্রশংসা করলেও এটি কোনও সফ্টওয়্যার ইঞ্জিনিয়ারিং দৃষ্টিকোণ থেকে পরিষ্কার কোড নয়। এই কোডটির ফলে ক্রিয়াকলাপটি খণ্ডটির সাথে দৃly়ভাবে মিলিত হয়। টুকরাগুলির বাস্তবায়ন বিশদটি না জেনে আপনি একাধিক ক্রিয়াকলাপে একই টুকরো পুনরায় ব্যবহার করতে সক্ষম হবেন।
আমিন

1
"সুইচ (v.getId ()) {" হওয়া উচিত এবং "স্যুইচ (v.getid ())
not

5
আপনার নিজের ইন্টারফেসটি সংজ্ঞায়িত করার পরিবর্তে, আপনি ইউপোরির বর্ণিত হিসাবে ইতিমধ্যে বিদ্যমান অনক্লিকলিস্টনার ব্যবহার করতে পারেন।
fr00tyl00p

1
আমি যখন এটি পড়লাম তখন আমি চিৎকার করেছিলাম, এটি এতটাই হ'ল ... এডোরজানপ্রিনকজ-এর নীচের উত্তরটি যাওয়ার উপায়।
Wjdavis5

603

অনক্লিক ইভেন্টগুলি পরিচালনা করার জন্য আমি নিম্নলিখিত সমাধানটি ব্যবহার করতে পছন্দ করি। এটি ক্রিয়াকলাপ এবং খণ্ডগুলির জন্যও কাজ করে।

public class StartFragment extends Fragment implements OnClickListener{

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_start, container, false);

        Button b = (Button) v.findViewById(R.id.StartButton);
        b.setOnClickListener(this);
        return v;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.StartButton:

            ...

            break;
        }
    }
}

9
অনক্রেটভিউতে, আমি ভিউগ্রুপ ভি এর সমস্ত শিশু আইটেমগুলি লুপ করি এবং আমার যে সমস্ত বোতামের সন্ধান পাওয়া যায় তার জন্য অনক্লিক্লিস্টনার সেট করি। সমস্ত বোতামের জন্য শ্রোতাকে ম্যানুয়ালি সেট করার চেয়ে এটি অনেক ভাল।
একজন ব্যক্তি

17
ভোট দিয়েছেন। এটি খণ্ডগুলি পুনরায় ব্যবহারযোগ্য করে তোলে। না হলে খণ্ড ব্যবহার কেন?
বোরিয়াস

44
এই একই কৌশলটি কি 1987 সালে প্রোগ্রামিং উইন্ডোজ ফিরে আসেনি? চিন্তার কিছু নেই. গুগল দ্রুত চলে আসে এবং এটি বিকাশকারী উত্পাদনশীলতা সম্পর্কে। আমি নিশ্চিত যে ইভেন্ট হ্যান্ডলিং 1991-ইয়ার ভিজ্যুয়াল বেসিকের মতো ভাল না হওয়া পর্যন্ত এটি বেশি দিন থাকবে না।
এডওয়ার্ড ব্রে

7
ডান আমদানি আপনি অনক্লিকলিস্টারের জন্য ব্যবহার করেছেন? ইন্টেলিজ আমাকে অ্যান্ড্রয়েড.ভিউ.ভিউ.অনক্লিকলিস্টার প্রস্তাব দেয় এবং এটি কাজ করে না: / (অনক্লিক কখনও চলবে না)
জোটা

4
@ নাথানঅসমান আমার মনে হয় প্রশ্নটি এক্সএমএল অনক্লিকের সাথে সম্পর্কিত ছিল, তাই গৃহীত উত্তরগুলি সঠিক সমাধান সরবরাহ করে।
নাভিদ আহমদ

29

আমার মনে সমস্যাটি হ'ল দৃশ্যটি এখনও ক্রিয়াকলাপ, খণ্ড নয়। খণ্ডগুলির নিজস্ব কোনও স্বাধীন দৃষ্টিভঙ্গি নেই এবং পিতামাতার ক্রিয়াকলাপ দর্শনটির সাথে এটি সংযুক্ত। ঘটনাটি ক্রিয়াকলাপে কেন শেষ হয় তা খণ্ড নয়। এটি দুর্ভাগ্যজনক তবে আমি মনে করি এই কাজটি করার জন্য আপনার কিছু কোডের প্রয়োজন হবে।

রূপান্তরকালে আমি যা করছি তা কেবল ক্লিক শ্রোতাদের যুক্ত করা যা পুরাতন ইভেন্টের হ্যান্ডলারকে কল করে।

এই ক্ষেত্রে:

final Button loginButton = (Button) view.findViewById(R.id.loginButton);
loginButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(final View v) {
        onLoginClicked(v);
    }
});

1
ধন্যবাদ - আমি এটিকে একটি সামান্য সংশোধন করে ব্যবহার করেছি যাতে আমি টুকরোটি ভিউ (যেমন inflater.inflate (R.layout.my_fragment_xML_resource) এর ফলাফল) অন লোগিন ক্লিক করা () এ পাস করছি যাতে এটি খণ্ডগুলি উপ-দর্শনগুলিতে অ্যাক্সেস করতে পারে, যেমন এডিটেক্সট, ভিউ.ফাইন্ডভিউবিআইআইডি () এর মাধ্যমে () যদি আমি কেবল ক্রিয়াকলাপের দৃশ্যের মধ্য দিয়ে যাই তবে ভিউ.ফাইন্ডভিউবিআইআইডি কল করুন (R.id.myfragmentwidget_id) নালার ফিরে আসে)।
মাইকেল নেলসন

এটি আমার প্রজেক্টে 21 এপিআইয়ের সাথে কাজ করে না। এই পদ্ধতিটি কীভাবে ব্যবহার করবেন সে সম্পর্কে কোনও চিন্তাভাবনা?
দারথ কোডার

এটির চমত্কার বেসিক কোড, প্রতিটি অ্যাপ্লিকেশনটিতে বেশ ব্যবহৃত। আপনার জন্য যা ঘটছে তা আপনি বর্ণনা করতে পারেন?
ব্রিল প্যাপিন

1
যে সমস্যাটি ঘটেছে তার ব্যাখ্যার জন্য এই উত্তরে আমার উত্সাহ তৈরি করুন কারণ খণ্ডটির বিন্যাসটি ক্রিয়াকলাপের দৃষ্টিতে সংযুক্ত রয়েছে।
ফলো

25

প্রসঙ্গত ক্রিয়াকলাপে কোনও পদ্ধতি যুক্ত না করে বা অনক্লিকলিস্টনার প্রয়োগ না করেই আমি সম্প্রতি এই সমস্যাটি সমাধান করেছি। আমি নিশ্চিত নই যে এটি কোনও "বৈধ" সমাধান কিনা, তবে এটি কার্যকর হয়।

এর উপর ভিত্তি করে: https://developer.android.com/tools/data-binding/guide.html# বাইন্ডিং_ইভেন্টস

এটি ডেটা বাইন্ডিংয়ের সাহায্যে করা যেতে পারে: কেবলমাত্র আপনার খণ্ডের উদাহরণটি একটি ভেরিয়েবল হিসাবে যুক্ত করুন, তারপরে আপনি অনক্লিকের সাথে যে কোনও পদ্ধতিতে লিঙ্ক করতে পারেন।

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.example.testapp.fragments.CustomFragment">

    <data>
        <variable android:name="fragment" android:type="com.example.testapp.fragments.CustomFragment"/>
    </data>
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_place_black_24dp"
            android:onClick="@{() -> fragment.buttonClicked()}"/>
    </LinearLayout>
</layout>

এবং খণ্ড লিঙ্কিং কোডটি হবে ...

public class CustomFragment extends Fragment {

    ...

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_person_profile, container, false);
        FragmentCustomBinding binding = DataBindingUtil.bind(view);
        binding.setFragment(this);
        return view;
    }

    ...

}

1
আমার কেবল একটি অনুভূতি আছে, যেহেতু আমি এই সমাধান কাজটি করতে পারছি না তার কিছু বিশদ অনুপস্থিত
টিমা

ডকুমেন্টেশনের "বিল্ড এনভায়রনমেন্ট" থেকে আপনার কিছু অনুপস্থিত হতে পারে: ডেভেলপার.অ্যান্ড্রয়েড
টোলেটস / ডেটা- বাইন্ডিং /

@ এলডো এক্সএমএলে অনক্লিক পদ্ধতির জন্য আমি বিশ্বাস করি আপনার অ্যান্ড্রয়েড থাকা উচিত: অনক্লিক = "@ {() -> টুকরা।" পরিবর্তে বোতামটি ক্লিক করুন ()। "।" অন্যদের জন্যও আপনার খণ্ডের ভিতরে বাটন ক্লিক () ফাংশনটি ঘোষণা করা উচিত এবং আপনার যুক্তিটি ভিতরে রাখা উচিত।
হায়াক নাহপেটিয়ান

এক্সএমএলে এটি হওয়া উচিতandroid:name="fragment" android:type="com.example.testapp.fragments.CustomFragment"/>
COYG

1
আমি শুধু এই এবং চেষ্টা nameএবং typeগুণাবলীর variableট্যাগ উচিত না আছে android:উপসর্গ। সম্ভবত অ্যান্ড্রয়েড লেআউটগুলির একটি পুরানো সংস্করণ রয়েছে যা এটির প্রয়োজন হয় না?
জনিলম্বদা

6

বাটারকনেফ সম্ভবত বিশৃঙ্খলা সমস্যার জন্য সেরা সমাধান। এটি তথাকথিত "পুরাতন পদ্ধতি" বয়লারপ্লেট কোড উত্পন্ন করতে টীকায়িত প্রসেসর ব্যবহার করে।

তবে অনক্লিক পদ্ধতিটি এখনও কাস্টম ইনফ্ল্যাটার সহ ব্যবহার করা যেতে পারে।

ব্যবহারবিধি

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup cnt, Bundle state) {
    inflater = FragmentInflatorFactory.inflatorFor(inflater, this);
    return inflater.inflate(R.layout.fragment_main, cnt, false);
}

বাস্তবায়ন

public class FragmentInflatorFactory implements LayoutInflater.Factory {

    private static final int[] sWantedAttrs = { android.R.attr.onClick };

    private static final Method sOnCreateViewMethod;
    static {
        // We could duplicate its functionallity.. or just ignore its a protected method.
        try {
            Method method = LayoutInflater.class.getDeclaredMethod(
                    "onCreateView", String.class, AttributeSet.class);
            method.setAccessible(true);
            sOnCreateViewMethod = method;
        } catch (NoSuchMethodException e) {
            // Public API: Should not happen.
            throw new RuntimeException(e);
        }
    }

    private final LayoutInflater mInflator;
    private final Object mFragment;

    public FragmentInflatorFactory(LayoutInflater delegate, Object fragment) {
        if (delegate == null || fragment == null) {
            throw new NullPointerException();
        }
        mInflator = delegate;
        mFragment = fragment;
    }

    public static LayoutInflater inflatorFor(LayoutInflater original, Object fragment) {
        LayoutInflater inflator = original.cloneInContext(original.getContext());
        FragmentInflatorFactory factory = new FragmentInflatorFactory(inflator, fragment);
        inflator.setFactory(factory);
        return inflator;
    }

    @Override
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        if ("fragment".equals(name)) {
            // Let the Activity ("private factory") handle it
            return null;
        }

        View view = null;

        if (name.indexOf('.') == -1) {
            try {
                view = (View) sOnCreateViewMethod.invoke(mInflator, name, attrs);
            } catch (IllegalAccessException e) {
                throw new AssertionError(e);
            } catch (InvocationTargetException e) {
                if (e.getCause() instanceof ClassNotFoundException) {
                    return null;
                }
                throw new RuntimeException(e);
            }
        } else {
            try {
                view = mInflator.createView(name, null, attrs);
            } catch (ClassNotFoundException e) {
                return null;
            }
        }

        TypedArray a = context.obtainStyledAttributes(attrs, sWantedAttrs);
        String methodName = a.getString(0);
        a.recycle();

        if (methodName != null) {
            view.setOnClickListener(new FragmentClickListener(mFragment, methodName));
        }
        return view;
    }

    private static class FragmentClickListener implements OnClickListener {

        private final Object mFragment;
        private final String mMethodName;
        private Method mMethod;

        public FragmentClickListener(Object fragment, String methodName) {
            mFragment = fragment;
            mMethodName = methodName;
        }

        @Override
        public void onClick(View v) {
            if (mMethod == null) {
                Class<?> clazz = mFragment.getClass();
                try {
                    mMethod = clazz.getMethod(mMethodName, View.class);
                } catch (NoSuchMethodException e) {
                    throw new IllegalStateException(
                            "Cannot find public method " + mMethodName + "(View) on "
                                    + clazz + " for onClick");
                }
            }

            try {
                mMethod.invoke(mFragment, v);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new AssertionError(e);
            }
        }
    }
}

6

আমি onClickখণ্ডগুলিতে কাজ করার সময় এক্সএমএলে বৈশিষ্ট্যটি ব্যবহার করার চেয়ে কোডটিতে ক্লিক হ্যান্ডলিংয়ের পরিবর্তে যেতে চাই ।

আপনার ক্রিয়াকলাপগুলিকে টুকরো টুকরো টুকরো করার সময় এটি আরও সহজ হয়ে যায়। আপনি android:onClickপ্রতিটি caseব্লক থেকে সরাসরি ক্লিক হ্যান্ডলারের (পূর্বে এক্সএমএল সেট করা ) কল করতে পারেন ।

findViewById(R.id.button_login).setOnClickListener(clickListener);
...

OnClickListener clickListener = new OnClickListener() {
    @Override
    public void onClick(final View v) {
        switch(v.getId()) {
           case R.id.button_login:
              // Which is supposed to be called automatically in your
              // activity, which has now changed to a fragment.
              onLoginClick(v);
              break;

           case R.id.button_logout:
              ...
        }
    }
}

এটা টুকরা মধ্যে ক্লিকে হ্যান্ডলিং বিষয় আসে, তখন এর চেয়ে আমার কাছে সহজ মনে হচ্ছে android:onClick


5

এটি অন্য উপায় :

1. এইরকম একটি বেসফ্রেগমেন্ট তৈরি করুন:

public abstract class BaseFragment extends Fragment implements OnClickListener

2.Use

public class FragmentA extends BaseFragment 

পরিবর্তে

public class FragmentA extends Fragment

3. আপনার ক্রিয়াকলাপে:

public class MainActivity extends ActionBarActivity implements OnClickListener

এবং

BaseFragment fragment = new FragmentA;

public void onClick(View v){
    fragment.onClick(v);
}

আশা করি এটা সাহায্য করবে.


আপনার উত্তরের 1 বছর, 1 মাস এবং 1 দিন: বিমূর্ত বেসফ্র্যাগমেন্ট তৈরির জন্য প্রতিটি খণ্ড শ্রেণিতে অনক্লিকলিস্টারের পুনরাবৃত্তি না করা ছাড়া অন্য কোনও কারণ আছে কি?
দিমিত্রিওস কে।

5

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

    final View.OnClickListener imageOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            chosenImage = ((ImageButton)v).getDrawable();
        }
    };

    ViewGroup root = (ViewGroup) getView().findViewById(R.id.imagesParentView);
    int childViewCount = root.getChildCount();
    for (int i=0; i < childViewCount; i++){
        View image = root.getChildAt(i);
        if (image instanceof ImageButton) {
            ((ImageButton)image).setOnClickListener(imageOnClickListener);
        }
    }

2

আমি উত্তরগুলি দেখতে দেখতে এগুলি একরকম পুরানো। সম্প্রতি গুগল পরিচয় করিয়ে DataBinding যা নিয়ন্ত্রণ করা অনেক সহজ হয় onClick অথবা আপনার XML- এর বরাদ্দ।

এখানে এটি উদাহরণস্বরূপ যা আপনি এটি পরিচালনা করতে পারেন তা দেখতে পারেন:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
   <data>
       <variable name="handlers" type="com.example.Handlers"/>
       <variable name="user" type="com.example.User"/>
   </data>
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.firstName}"
           android:onClick="@{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/>
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.lastName}"
           android:onClick="@{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/>
   </LinearLayout>
</layout>

ডেটাবাইন্ডিং সম্পর্কে খুব সুন্দর টিউটোরিয়াল রয়েছে যা আপনি এটি এখানে খুঁজে পেতে পারেন ।


2

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

আমি বেস ফ্রেমমেন্ট ক্লাসে স্টাইলযোগ্য বৈশিষ্ট্য যুক্ত করতে পারি কিনা তা আমি তদন্ত করছি।

মূল ধারণাটি হ'ল অনক্লিক কলব্যাকের সাথে ডিল করার সময় একই কার্যকারিতাটি দেখায় যা প্রয়োগ করে।


1

ব্লুন্ডেলের উত্তরে যুক্ত করা, আপনার
যদি প্রচুর অনক্লিকস সহ আরও টুকরো থাকে:

কার্যক্রম:

Fragment someFragment1 = (Fragment)getFragmentManager().findFragmentByTag("someFragment1 "); 
Fragment someFragment2 = (Fragment)getFragmentManager().findFragmentByTag("someFragment2 "); 
Fragment someFragment3 = (Fragment)getFragmentManager().findFragmentByTag("someFragment3 "); 

...onCreate etc instantiating your fragments

public void myClickMethod(View v){
  if (someFragment1.isVisible()) {
       someFragment1.myClickMethod(v);
  }else if(someFragment2.isVisible()){
       someFragment2.myClickMethod(v);
  }else if(someFragment3.isVisible()){
       someFragment3.myClickMethod(v); 
  }

} 

আপনার খণ্ডে:

  public void myClickMethod(View v){
     switch(v.getid()){
       // Just like you were doing
     }
  } 

1

যদি আপনি অ্যান্ড্রয়েড: অনক্লিক = "" ব্যবহার করে এক্সএমএলতে নিবন্ধন করেন তবে কলব্যাক সম্মানিত ক্রিয়াকলাপকে দেওয়া হবে যার প্রসঙ্গে আপনার খণ্ডটি (getActivity ()) এর অন্তর্ভুক্ত। যদি ক্রিয়াকলাপে এ জাতীয় পদ্ধতি না পাওয়া যায়, তবে সিস্টেম একটি ব্যতিক্রম ছুঁড়ে দেবে।


ধন্যবাদ, দুর্ঘটনা কেন ঘটছে তা অন্য কেউ ব্যাখ্যা করেন নি

1

আপনি ডিউপলড ইভেন্টের জন্য ইভেন্টবাস ব্যবহার বিবেচনা করতে পারেন .. আপনি খুব সহজে ইভেন্টগুলির জন্য শুনতে পারেন। আপনি নিশ্চিত করতে পারেন যে ইভেন্টটি ইউআই থ্রেডে প্রাপ্ত হচ্ছে (রানওনউইথ্রেড কল করার পরিবর্তে .. প্রতিটি ইভেন্টের সদস্যতার জন্য নিজের জন্য)

https://github.com/greenrobot/EventBus

গিথুব থেকে:

অ্যানড্রয়েড অপ্টিমাইজড ইভেন্ট বাস যা ক্রিয়াকলাপ, টুকরো, থ্রেডস, পরিষেবাদি ইত্যাদির মধ্যে যোগাযোগকে সহজ করে তোলে কম কোড, আরও ভাল মানের


1

আমি অ্যাডজর্ন লিংকসের উত্তরে যুক্ত করতে চাই ।

আপনার যদি একাধিক হ্যান্ডলারের প্রয়োজন হয় তবে আপনি কেবল ল্যাম্বদা রেফারেন্স ব্যবহার করতে পারেন

void onViewCreated(View view, Bundle savedInstanceState)
{
    view.setOnClickListener(this::handler);
}
void handler(View v)
{
    ...
}

এখানে কৌশলটি হ'ল handlerপদ্ধতির স্বাক্ষর স্বাক্ষরের সাথে মেলে View.OnClickListener.onClick। এইভাবে, আপনার View.OnClickListenerইন্টারফেসের প্রয়োজন হবে না ।

এছাড়াও, আপনার কোনও সুইচ স্টেটমেন্টের প্রয়োজন হবে না।

দুঃখের বিষয়, এই পদ্ধতিটি কেবলমাত্র ইন্টারফেসের মধ্যেই সীমাবদ্ধ যার জন্য একটি পদ্ধতি বা ল্যাম্বডা প্রয়োজন।


1

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

বাঁধাই অভিমানী তথ্য এত হয় সক্ষম করা থাকে, এখানে একটি জেনেরিক সমাধান আমি উত্থাপন করতে পারেন; কিছুটা দীর্ঘ তবে এটি অবশ্যই কার্যকর হয় (কিছু সতর্কতার সাথে):

পদক্ষেপ 1: কাস্টম অনক্লিক বাস্তবায়ন

এটি টেপ-অন ভিউ (যেমন বোতাম) এর সাথে সম্পর্কিত প্রসঙ্গগুলির মাধ্যমে খণ্ড-সচেতন অনুসন্ধান চালাবে:


// CustomOnClick.kt

@file:JvmName("CustomOnClick")

package com.example

import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import java.lang.reflect.Method

fun onClick(view: View, methodName: String) {
    resolveOnClickInvocation(view, methodName)?.invoke(view)
}

private data class OnClickInvocation(val obj: Any, val method: Method) {
    fun invoke(view: View) {
        method.invoke(obj, view)
    }
}

private fun resolveOnClickInvocation(view: View, methodName: String): OnClickInvocation? =
    searchContexts(view) { context ->
        var invocation: OnClickInvocation? = null
        if (context is Activity) {
            val activity = context as? FragmentActivity
                    ?: throw IllegalStateException("A non-FragmentActivity is not supported (looking up an onClick handler of $view)")

            invocation = getTopFragment(activity)?.let { fragment ->
                resolveInvocation(fragment, methodName)
            }?: resolveInvocation(context, methodName)
        }
        invocation
    }

private fun getTopFragment(activity: FragmentActivity): Fragment? {
    val fragments = activity.supportFragmentManager.fragments
    return if (fragments.isEmpty()) null else fragments.last()
}

private fun resolveInvocation(target: Any, methodName: String): OnClickInvocation? =
    try {
        val method = target.javaClass.getMethod(methodName, View::class.java)
        OnClickInvocation(target, method)
    } catch (e: NoSuchMethodException) {
        null
    }

private fun <T: Any> searchContexts(view: View, matcher: (context: Context) -> T?): T? {
    var context = view.context
    while (context != null && context is ContextWrapper) {
        val result = matcher(context)
        if (result == null) {
            context = context.baseContext
        } else {
            return result
        }
    }
    return null
}

দ্রষ্টব্য: আসল অ্যান্ড্রয়েড বাস্তবায়নের উপর ভিত্তি করে ( https://android.googlesource.com/platform/frameworks/base/+/a175a5b/core/java/android/view/View.java#3025 দেখুন )

পদক্ষেপ 2: লেআউট ফাইলগুলিতে ঘোষণামূলক অ্যাপ্লিকেশন

তারপরে, ডেটা বাইন্ডিং সচেতন এক্সএমএল এর:

<layout>
  <data>
     <import type="com.example.CustomOnClick"/>
  </data>

  <Button
    android:onClick='@{(v) -> CustomOnClick.onClick(v, "myClickMethod")}'
  </Button>
</layout>

আদেশ সহকারে

  • একটি 'আধুনিক' FragmentActivityভিত্তিক বাস্তবায়ন অনুমান করে
  • স্ট্যাকের মধ্যে কেবলমাত্র "শীর্ষ-সর্বাধিক" (অর্থাত্ শেষ ) খণ্ডের পদ্ধতি অনুসন্ধান করতে পারে (যদিও এটি ঠিক করা যেতে পারে, প্রয়োজনে)

0

এটি আমার জন্য কাজ করে চলেছে: (অ্যান্ড্রয়েড স্টুডিও)

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.update_credential, container, false);
        Button bt_login = (Button) rootView.findViewById(R.id.btnSend);

        bt_login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                System.out.println("Hi its me");


            }// end onClick
        });

        return rootView;

    }// end onCreateView


0

সেরা সমাধান আইএমএইচও:

খণ্ডে:

protected void addClick(int id) {
    try {
        getView().findViewById(id).setOnClickListener(this);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void onClick(View v) {
    if (v.getId()==R.id.myButton) {
        onMyButtonClick(v);
    }
}

তারপরে ফ্রেগমেন্টের অনভিউ স্টেটরেস্টার্ড:

addClick(R.id.myButton);

0

আপনার ক্রিয়াকলাপটি অবশ্যই অবশ্যই ব্যবহার করা হিসাবে কলব্যাক গ্রহণ করছে:

mViewPagerCloth.setOnClickListener((YourActivityName)getActivity());

যদি আপনি চান যে আপনার খণ্ডটি কলব্যাক গ্রহণ করতে পারে তবে এটি করুন:

mViewPagerCloth.setOnClickListener(this);

এবং খণ্ডে onClickListenerইন্টারফেস প্রয়োগ করুন

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