it-swarm.com.de

Android Fragment onClick button Methode

Ich versuche, die Methode in meinem onClick (View v) XML aufzurufen, aber sie funktioniert nicht mit Fragment. Das ist der Fehler.

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'

Java-Code:

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

XML:

<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" />
85
user3160725

Ihre Tätigkeit muss haben

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

nicht fragmentieren.

Wenn Sie nicht möchten, dass die oben genannten Aktivitäten ausgeführt werden. Initialisieren Sie die Schaltfläche im Fragment und stellen Sie den Listener auf den gleichen Wert ein.

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

Dann

@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;
}
174
Raghunandan

Eine andere Möglichkeit besteht darin, Ihr Fragment View.OnClickListener implementieren zu lassen und onClick (View v) in Ihrem Fragment zu überschreiben. Wenn Sie möchten, dass Ihr Fragment mit der Aktivität spricht, fügen Sie einfach eine Schnittstelle mit den gewünschten Methoden hinzu und lassen Sie die Aktivität die Schnittstelle implementieren und die Methoden überschreiben.

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.htmlhttp://developer.Android.com/training/basics/fragments/communicating). html

13
cjayem13

Dies ist kein Problem, dies ist ein Design von Android. Siehe hier :

Sie sollten jedes Fragment als modulare und wiederverwendbare Aktivitätskomponente entwerfen. Das heißt, da jedes Fragment sein eigenes Layout und sein eigenes Verhalten mit seinen eigenen Lebenszyklus-Rückrufen definiert, können Sie ein Fragment in mehrere Aktivitäten einbeziehen. Sie sollten es daher für die Wiederverwendung entwerfen und vermeiden, ein Fragment direkt von einem anderen Fragment aus zu manipulieren.

Eine mögliche Problemumgehung wäre, in Ihrer MainActivity Folgendes zu tun:

Fragment someFragment;    

...onCreate etc instantiating your fragments

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

und dann in deiner Fragment-Klasse:

public void myClickMethod(View v){
    switch(v.getid()){
       // Your code here
    }
 } 
6
CzarMatt
@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;
}

Du bist ok !!!!

3
Pong Petrung

Die anderen haben bereits gesagt, dass Methoden in onClick in Aktivitäten und nicht in Fragmenten durchsucht werden. Trotzdem, wenn Sie es wirklich wollen, ist es ist möglich.

Grundsätzlich hat jede Ansicht ein Tag (wahrscheinlich null). Wir setzen das Tag der Stammansicht auf das Fragment, das diese Ansicht aufgeblasen hat. Anschließend können Sie die übergeordneten Elemente der Ansicht durchsuchen und das Fragment mit der angeklickten Schaltfläche abrufen. Jetzt ermitteln wir den Methodennamen und verwenden Reflection, um dieselbe Methode aus dem abgerufenen Fragment aufzurufen. Einfach!

in einer Klasse, die Fragment: erweitert

@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
}

Alle Aktivitäten werden von derselben ButtonHandlingActivity abgeleitet:

public class PageListActivity extends ButtonHandlingActivity

ButtonHandlingActivity.Java:

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 ...
    }

}

Es muss Methoden für alle XML-onClick-Handler definieren.

com/example/customandroid/OnClickFragments.Java:

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));
    }
}

Und das nächste Abenteuer wird Proguard Obfuscation sein ...

PS

Es liegt natürlich an Ihnen, Ihre Anwendung so zu gestalten, dass die Daten im Modell und nicht in Aktivitäten oder Fragmenten (die Controller aus dem MVC , Model-View-Controller Sicht). Das Ansicht ist das, was Sie über XML definieren, sowie die benutzerdefinierten Ansichtsklassen (wenn Sie sie definieren, verwenden die meisten Leute nur das, was bereits vorhanden ist). Eine Faustregel: Wenn einige Daten die Bildschirmdrehung definitiv überstehen müssen, gehören sie zu Modell.