Android фрагмент кнопка onClick метод


Я пытаюсь вызвать метод в моем onClick (View v) XML, но не работает с фрагментом. Это и есть ошибка.

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'

MainActivity.java

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" />
5 70

5 ответов:

ваша деятельность должна быть

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

другой вариант может заключаться в том, чтобы иметь представление реализации фрагмента.OnClickListener и переопределить onClick (вид v) в вашем фрагменте. Если вам нужно, чтобы ваш фрагмент разговаривал с активностью, просто добавьте интерфейс с нужным методом(ами) и попросите activity реализовать интерфейс и переопределить его метод(ы).

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/fragments/communicating.html

это не проблема, это дизайн Android. Смотрите здесь:

вы должны проектировать каждый фрагмент как модульную и многоразовую деятельность деталь. То есть, потому что каждый фрагмент определяет свой собственный макет и его собственное поведение с собственными обратными вызовами жизненного цикла, вы можете включить один фрагмент в нескольких действиях, поэтому вы должны разработать для повторного использования и избегайте прямого манипулирования одним фрагментом из другого фрагмента.

A возможным обходным путем было бы сделать что-то вроде этого в вашей MainActivity:

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

другие уже сказали, что методы в onClick ищутся в действиях, а не во фрагментах. Тем не менее, если вы действительно этого хотите, это и возможно.

в принципе, каждый вид имеет тег (вероятно, нулевой). Мы устанавливаем тег корневого представления на фрагмент, который раздул это представление. Затем легко выполнить поиск родителей представления и получить фрагмент, содержащий нажатую кнопку. Теперь мы узнаем имя метода и используем отражение для вызова того же метода из извлеченный фрагмент. Полегче!

в классе, который расширяет 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
}

все действия являются производными от одного и того же ButtonHandlingActivity:

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

}

Он должен определить методы для всех обработчиков xml onClick.

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

и следующее приключение будет программы ProGuard запутывания...

PS

это, конечно, до вас, чтобы создать свое приложение так, что данные живут в модель а не в действиях или фрагментах (которые контроллеры С MVC, Model-View-Controller точки зрения). Элемент посмотреть это то, что вы определяете через xml, плюс пользовательские классы представления (если вы их определяете, большинство людей просто повторно используют то, что уже есть). Эмпирическое правило: если некоторые данные определенно должны пережить поворот экрана, они принадлежат модель.

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

ты в порядке !!!!