অ্যান্ড্রয়েড ফ্র্যাগমেন্ট অনক্লিক বাটন পদ্ধতি


91

আমি আমার অনক্লিক (ভি ভি) এক্সএমএলটিতে পদ্ধতিটি আহ্বান করার চেষ্টা করছি, তবে ফ্রেগমেন্টের সাথে কাজ করে না। এটি ত্রুটি।

01-17 12:38:36.840: E/AndroidRuntime(4171): java.lang.IllegalStateException: 
Could not find a method insertIntoDb(View) in the activity class main.MainActivity 
for onClick handler on view class android.widget.Button with id 'btn_conferma'

জাভা কোড:

public void insertIntoDb(View v) {
...
} 

এক্সএমএল:

<Button
        android:id="@id/btn_conferma"
        style="?android:attr/borderlessButtonStyle"
        android:layout_width="0.0dip"
        android:layout_height="45dp"
        android:layout_marginLeft="2dp"
        android:layout_weight="1.0"
        android:background="@drawable/bottoni"
        android:gravity="center_horizontal|center_vertical"
        android:onClick="insertIntoDb"
        android:text="SALVA"
        android:textColor="#ffffff"
        android:textSize="16sp" />

4
দয়া করে স্ট্যাকট্রেস এবং প্রাসঙ্গিক কোডের আরও পোস্ট করুন
ইমানুয়েল

4
এখানে যেমন ডেভেলপার.অ্যান্ড্রয়েড / গাইড / টপিক্স / লুই / কন্ট্রোলস / এ বলা হয়েছে , "লেআউটটির হোস্টিং ক্রিয়াকলাপটি অবশ্যই সংশ্লিষ্ট পদ্ধতিটি প্রয়োগ করতে হবে।" আপনার ক্ষেত্রে, আপনি আপনার টুকরাটিতে সংশ্লিষ্ট পদ্ধতি প্রয়োগ করেছেন। এর কারণে, এটি ইলিজালস্টেট এক্সেপশনটি ছুড়ে ফেলে কারণ এটি ক্রিয়াকলাপে সম্পর্কিত পদ্ধতিটি খুঁজে পায় না। হয়তো, আপনি একটি কৌতুক হিসাবে এই পোস্টে দেখানো আবেদন করতে পারেন stackoverflow.com/a/6271637/2515815
hcelaloner

InsertIntoDb (দেখুন) পদ্ধতিটি অবশ্যই মেইন.মেনএটিভিটিতে থাকতে হবে এবং খণ্ড শ্রেণিতে নয়।
betorcs

সবচেয়ে ভালো সমাধান stackoverflow.com/questions/7570575/...
AndroidGeek

উত্তর:


186

আপনার কার্যকলাপ অবশ্যই আছে

public void insertIntoDb(View v) {
...
} 

খণ্ড না

আপনি যদি ক্রিয়াকলাপে উপরেরটি না চান। খণ্ডে বোতামটি আরম্ভ করুন এবং শ্রোতাদের সাথে একই সেট করুন।

<Button
    android:id="@+id/btn_conferma" // + missing

তারপরে

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

   View view = inflater.inflate(R.layout.fragment_rssitem_detail,
    container, false);
   Button button = (Button) view.findViewById(R.id.btn_conferma);
   button.setOnClickListener(new OnClickListener()
   {
             @Override
             public void onClick(View v)
             {
                // do something
             } 
   }); 
   return view;
}

এটি আমার প্রজেক্টে টুকরোটি ক্রাশ হয়ে যায় যা এপিআই 21 ব্যবহার করে? কোনও বিকল্প সমাধান / পরামর্শ?
ডারথ কোডার

@ দার্থকোডার আমি এটি ভাবি না। আপনার কোডটি উপস্থাপন করতে হবে। এটি এখানে পোস্ট করা এই কোডের সাথে সম্পর্কিত নাও হতে পারে
রঘুনন্দন

@ সানু ললিপপ প্রি লোলিপপের সাথে কিছু করার নেই। বিশদ সহ আরও একটি প্রশ্ন পোস্ট করুন ..
রঘুনন্দন

ক্লিকের ইভেন্টটি কখনই ট্রিগার করা হয় না যখন আমি উপরের উত্তর হিসাবে করি।
টেড

4
উপরের মন্তব্যে আমি কিছুটা অবাক হয়েছি। কোনও অপরাধ নয়, তবে কোনও বিবরণ পোস্ট না করে কেবল "এটি কাজ করে না" বলা খুব অলাভজনক ... এবং আমার হিসাবে, "এটি ঠিক কাজ করে"।
zzheng

15

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

public class FragName extends Fragment implements View.OnClickListener { 
    public FragmentCommunicator fComm;
    public ImageButton res1, res2;
    int c;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_test, container, false);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            fComm = (FragmentCommunicator) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement FragmentCommunicator");
        }
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        res1 = (ImageButton) getActivity().findViewById(R.id.responseButton1);
        res1.setOnClickListener(this);
        res2 = (ImageButton) getActivity().findViewById(R.id.responseButton2);
        res2.setOnClickListener(this);
    }
    public void onClick(final View v) { //check for what button is pressed
            switch (v.getId()) {
                case R.id.responseButton1:
                  c *= fComm.fragmentContactActivity(2);
                  break;
                case R.id.responseButton2:
                  c *= fComm.fragmentContactActivity(4);
                  break;
                default:
                  c *= fComm.fragmentContactActivity(100);
                  break;
    }
    public interface FragmentCommunicator{
        public int fragmentContactActivity(int b);
    }



public class MainActivity extends FragmentActivity implements FragName.FragmentCommunicator{
    int a = 10;
    //variable a is update by fragment. ex. use to change textview or whatever else you'd like.

    public int fragmentContactActivity(int b) {
        //update info on activity here
        a += b;
        return a;
    }
}

http://developer.android.com/training/basics/firstapp/starting-activity.html http://developer.android.com/training/basics/fra اب ts/communicating.html


4
আমি এটি সর্বদা করি তবে তবুও মনে হয় এটি কুৎসিত
আলেকজান্ডার ফারবার

আমি প্রথমে খুব করেছি কিন্তু এখন এটি প্রায় দ্বিতীয় হাত হয়ে গেছে; প্লাস এটি আসলে আরও জটিল অ্যাপ্লিকেশনগুলিতে সহায়তা করেছে তবে মৌলিক কোনও কিছুর জন্য এটি ওভারকিল বলে মনে হয়।
সিজেইম 13

@ সিজেইম ১৩, আপনি কি দয়া করে "এটি অতিরিক্ত ওভারকিল কেন" বিশদভাবে বলতে পারেন?
eRaisedToX

9

এটি কোনও সমস্যা নয়, এটি অ্যান্ড্রয়েডের একটি নকশা। এখানে দেখুন :

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

আপনার মেইনএকটিভিটিতে এই জাতীয় কিছু করা একটি সম্ভাব্য কাজ হতে পারে:

Fragment someFragment;    

...onCreate etc instantiating your fragments

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

এবং তারপরে আপনার খণ্ড শ্রেণিতে:

public void myClickMethod(View v){
    switch(v.getid()){
       // Your code here
    }
 } 

4

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

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

প্রসারিত একটি শ্রেণিতে Fragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_id, container, false);

    OnClickFragments.registerTagFragment(rootView, this); // <========== !!!!!

    return rootView;
}

public void onButtonSomething(View v) {
    Log.d("~~~","~~~ MyFragment.onButtonSomething");
    // whatever
}

সমস্ত ক্রিয়াকলাপ একই বোতামহ্যান্ডলিংঅ্যাক্টিভিটি থেকে উদ্ভূত:

public class PageListActivity extends ButtonHandlingActivity

বাটনহ্যান্ডলিংঅ্যাক্টিভিটি.জভা:

public class ButtonHandlingActivity extends Activity {

    public void onButtonSomething(View v) {
        OnClickFragments.invokeFragmentButtonHandlerNoExc(v);
//or, if you want to handle exceptions:
//      try {
//          OnClickFragments.invokeFragmentButtonHandler(v);
//      } catch ...
    }

}

এটিতে সমস্ত এক্সএমএল অনক্লিক হ্যান্ডলারের জন্য পদ্ধতি নির্ধারণ করতে হবে।

com / উদাহরণ / কাস্টোমন্ড্রয়েড / অনক্লিকফ্রেগমেন্টস.জভা:

package com.example.customandroid;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Fragment;
import android.view.View;

public abstract class OnClickFragments {
    public static class FragmentHolder {
        Fragment fragment;
        public FragmentHolder(Fragment fragment) {
            this.fragment = fragment;
        }
    }
    public static Fragment getTagFragment(View view) {
        for (View v = view; v != null; v = (v.getParent() instanceof View) ? (View)v.getParent() : null) {
            Object tag = v.getTag();
            if (tag != null && tag instanceof FragmentHolder) {
                return ((FragmentHolder)tag).fragment;
            }
        }
        return null;
    }
    public static String getCallingMethodName(int callsAbove) {
        Exception e = new Exception();
        e.fillInStackTrace();
        String methodName = e.getStackTrace()[callsAbove+1].getMethodName();
        return methodName;
    }
    public static void invokeFragmentButtonHandler(View v, int callsAbove) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
        String methodName = getCallingMethodName(callsAbove+1);
        Fragment f = OnClickFragments.getTagFragment(v);
        Method m = f.getClass().getMethod(methodName, new Class[] { View.class });
        m.invoke(f, v);
    }
    public static void invokeFragmentButtonHandler(View v) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
        invokeFragmentButtonHandler(v,1);
    }
    public static void invokeFragmentButtonHandlerNoExc(View v) {
        try {
            invokeFragmentButtonHandler(v,1);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    public static void registerTagFragment(View rootView, Fragment fragment) {
        rootView.setTag(new FragmentHolder(fragment));
    }
}

এবং পরবর্তী অ্যাডভেঞ্চার অবরুদ্ধ হয়ে উঠবে ...

পুনশ্চ

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


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

    View view = inflater.inflate(R.layout.writeqrcode_main, container, false);
    // Inflate the layout for this fragment

    txt_name = (TextView) view.findViewById(R.id.name);
    txt_usranme = (TextView) view.findViewById(R.id.surname);
    txt_number = (TextView) view.findViewById(R.id.number);
    txt_province = (TextView) view.findViewById(R.id.province);
    txt_write = (EditText) view.findViewById(R.id.editText_write);
    txt_show1 = (Button) view.findViewById(R.id.buttonShow1);

    txt_show1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.e("Onclick","Onclick");

            txt_show1.setVisibility(View.INVISIBLE);
            txt_name.setVisibility(View.VISIBLE);
            txt_usranme.setVisibility(View.VISIBLE);
            txt_number.setVisibility(View.VISIBLE);
            txt_province.setVisibility(View.VISIBLE);
        }
    });
    return view;
}

আপনি ঠিক আছেন !!!!


4
আপনি কি ব্যাখ্যা করতে পারেন যে এটি কীভাবে প্রশ্নের উত্তর দেয়? আপনার বাক্যটি শেষে আপনার অর্থ কী?
তেপীম্ম

3

কোটলিন ব্যবহারকারীদের জন্য:

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?, 
    savedInstanceState: Bundle?) : View?
{
    // Inflate the layout for this fragment
    var myView = inflater.inflate(R.layout.fragment_home, container, false)
    var btn_test = myView.btn_test as Button
    btn_test.setOnClickListener {
        textView.text = "hunny home fragment"
    }

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