Взаимодействие активности и фрагментов с помощью метода внутри кнопки xml

Я пытаюсь восстановить свое приложение с помощью Navigation Drawer Activity, но в старой версии с простой активностью у меня есть диалог, который берет данные от пользователя и управляет ими внутри активности.

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

Моя первая проблема: MainActivity содержит 4 фрагмента, один из них имеет много кнопок, которые используют метод onClick в XML. С Activity все работает без проблем, но с Fragments я не могу объявить метод onClick xml!

Вторая проблема заключается в том, что метод onClick вызывает DialogActivity с помощью startActivityForResult и возвращает данные с помощью onActivityResult. Я перемещаю метод onClick внутри MainActivity, который содержит фрагмент, но когда он запускает диалог с startActivityForResult, onActivityResult внутри фрагментов не вызывается.

Я пытаюсь переместить его внутри действия и передать полученные данные фрагменту с интерфейсом, но я получаю сообщение об ошибке функции Drawable style = setButtonColor(color);внутри onActivityResult

Каков наилучший способ выполнить это? Лучше удалить DialogActivity и использовать DialogFragment для возврата данных без startActivityForResult и onActivityResult?

Вот код, который мне нужно адаптировать к новой графике Fragment.

<Button
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:text="@string/new_button"
         android:id="@+id/m12"
         android:onClick="addMateria"
         android:background="@drawable/buttons"
         android:singleLine="true"
         android:textSize="12sp"
         android:layout_column="2" />

Метод onClick

public void addMateria(View v){

        /* Prendo il nome della risorsa cosi nel ricompilare il progetto non perdo *
         * tutti i riferimenti ai bottoni salvati nel database                     */

        clickedButtonViewId = getResources().getResourceEntryName(v.getId());

        //StartActivityForResult perche mi aspetto la materia inserita dall'altra activity
        Intent myIntent = new Intent(MainActivity.this, DialogAddMateria.class);
        startActivityForResult(myIntent, 1);
        //onStop();
    }

И как я забираю данные

//Take back data from ActivityAddMateria
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        if(requestCode == 1) {
            if (resultCode == Activity.RESULT_OK) {

                MySQLiteHelper db = new MySQLiteHelper(getActivity());


                Toast.makeText(getContext(), "DENTRO ACTIVITYRESULT",
                        Toast.LENGTH_LONG).show();

                //Cambio subito il Button
                int resId = getResources().getIdentifier(clickedButtonViewId, "id", getActivity().getPackageName());
                final Button clickedtextView = (Button) getActivity().findViewById(resId);

                String result = data.getStringExtra("result"); //Take the materia from Dialog
                int color = data.getIntExtra("color", 1); //Take the color from Dialog

                //Controllo se il Button è già presente nel db se presente aggiorno se non presente inserisco
                boolean modifica = db.Exists(clickedButtonViewId);

                //Se voglio ripristinare il bottone di default
                if (color == getResources().getColor(R.color.blue_orario)) {

                    //Ripristino la grafica di Default
                    Drawable style = setButtonColor(color);
                    clickedtextView.setBackground(style);
                    clickedtextView.setText("New");

                    //Se la materia è nel database la cancello
                    if (modifica) {

                        db.deleteSingleMateria(clickedButtonViewId);

                    }

                } else {
                    //Quando inserisco un normale bottone colorato
                    if (!modifica) {

                        //Materia da inserire in un nuovo spazio
                        db.addMateriaToDb(new Materia(clickedButtonViewId, result, color));

                    } else {

                        //Materia già presente nel Button quindi aggiorno la materia
                        db.updateMateria(new Materia(clickedButtonViewId, result, color));
                        Toast.makeText(getContext(), "Materia modificata!",
                                Toast.LENGTH_LONG).show();
                    }

                    //Inserisco la materia nel DB dei voti_media
                    db.addMateriaVotiFromOrario(new MaterieVoti(result, 0.0));

                    clickedtextView.setText(result);
                    //clickedtextView.setBackgroundColor(color);
                    //clickedtextView.getBackground().setColorFilter(color, PorterDuff.Mode.MULTIPLY);
                    Drawable style = setButtonColor(color);
                    clickedtextView.setBackground(style);
                }
            }

            if (resultCode == Activity.RESULT_CANCELED) {
                //Nessuna materia inserita
            }

        }
    }//onActivityResult

Я не знаком с фрагментами, и мне сложно делать то, что мне нужно, если кто-нибудь может сказать мне, как это сделать, или предложить изменить связь между onClick и методом, фрагментом и методом, я здесь!


person Dario    schedule 20.09.2016    source источник


Ответы (2)


Этот вопрос задают много раз. Связь между действием и фрагментом может осуществляться разными способами, такими как передача данных в пакете, создание шаблона Singleton, объясненного в соответствии с здесь, а также используя EventBus, см. этот ответ, я объяснил каждый аспект, как вы можете это сделать, и если вы хотите большего понимания, прокомментируйте его.

Официальные документы находятся здесь

person TapanHP    schedule 20.09.2016
comment
Да, но проблема с методом? В посте я объясняю свою ситуацию не только с передачей данных между активностью и фрагментом: D. Основная проблема заключается в том, что я не могу объявить метод внутри фрагмента (addMateria()), и если я объявлю его внутри MainActivity, внутренний фрагмент onAcitivityResult не заберет данные из вызываемого DialogAcitivity. - person Dario; 20.09.2016
comment
Внутри ваших фрагментов вы можете получить контекст активности, все, что вам нужно сделать, это вызвать onActivityResult() в вашем фрагменте, и вам также нужно реализовать его в своей деятельности, а затем передать его во фрагменте, вызвав super.onActivityResult(), и вы можете решить эту проблему - person TapanHP; 20.09.2016
comment
я решил с помощью этого решения .... все объявлено внутри MainActivity ... метод addMateria () ... поэтому startActivityForResult и onAcitivityResult тоже ... и все еще работают ... правильно, как я делаю? Или это работает, но это незаконно :D - person Dario; 20.09.2016
comment
Примите ответ, если он полезен, чтобы другие могли получить решение - person TapanHP; 20.09.2016
comment
это не решение, потому что вы отвечаете только на часть проблемы - person Dario; 20.09.2016
comment
Отредактируйте его в соответствии с вашим решением - person TapanHP; 20.09.2016

Добавил все в MainActivity:

Метод, вызываемый в xml фрагмента, который при нажатии кнопки startActivityForResult для получения данных от пользователя.

После этого я пишу onActivityResult внутри MainActivity, чтобы при возврате данных сохранить их в БД и изменить стиль кнопки внутри фрагмента.

MainActivity, содержащие фрагменты

public void addMateria(View v){

        /* Prendo il nome della risorsa cosi nel ricompilare il progetto non perdo *
         * tutti i riferimenti ai bottoni salvati nel database                     */

        clickedButtonViewId = getResources().getResourceEntryName(v.getId());

        //StartActivityForResult perche mi aspetto la materia inserita dall'altra activity
        Intent myIntent = new Intent(MainActivity.this, DialogAddMateria.class);
        startActivityForResult(myIntent, 1);
        //onStop();
    }

    //Take back data from ActivityAddMateria
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        if(requestCode == 1) {
            if (resultCode == Activity.RESULT_OK) {

                MySQLiteHelper db = new MySQLiteHelper(this);

                //Cambio subito il Button
                int resId = getResources().getIdentifier(clickedButtonViewId, "id", getPackageName());
                final Button clickedtextView = (Button) findViewById(resId);

                String result = data.getStringExtra("result"); //Take the materia from Dialog
                int color = data.getIntExtra("color", 1); //Take the color from Dialog

                //Controllo se il Button è già presente nel db se presente aggiorno se non presente inserisco
                boolean modifica = db.Exists(clickedButtonViewId);

                //Se voglio ripristinare il bottone di default
                if (color == getResources().getColor(R.color.blue_orario)) {

                    //Ripristino la grafica di Default
                    Drawable style = setButtonColor(color);
                    clickedtextView.setBackground(style);
                    clickedtextView.setText("...");

                    //Se la materia è nel database la cancello
                    if (modifica) {

                        db.deleteSingleMateria(clickedButtonViewId);

                    }

                } else {
                    //Quando inserisco un normale bottone colorato
                    if (!modifica) {

                        //Materia da inserire in un nuovo spazio
                        db.addMateriaToDb(new Materia(clickedButtonViewId, result, color));

                    } else {

                        //Materia già presente nel Button quindi aggiorno la materia
                        db.updateMateria(new Materia(clickedButtonViewId, result, color));
                        Toast.makeText(MainActivity.this, "Materia modificata!",
                                Toast.LENGTH_LONG).show();
                    }

                    //Inserisco la materia nel DB dei voti_media
                    db.addMateriaVotiFromOrario(new MaterieVoti(result, 0.0));

                    clickedtextView.setText(result);
                    //clickedtextView.setBackgroundColor(color);
                    //clickedtextView.getBackground().setColorFilter(color, PorterDuff.Mode.MULTIPLY);
                    Drawable style = setButtonColor(color);
                    clickedtextView.setBackground(style);
                }
            }

            if (resultCode == Activity.RESULT_CANCELED) {
                //Nessuna materia inserita
            }

        }
    }//onActivityResult

Фрагмент простой проверки наличия данных в БД и обновления представления

    List<Materia> materia;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.orario_view, container, false);

       MySQLiteHelper db = new MySQLiteHelper(getActivity());

        //Get all materie inside database
        materia = db.getAllMaterie();
        //change all TextView inputed from user
        if(materia.isEmpty()){
            //do nothing
        }else {
            for (Materia mat : materia) {
                //Change all the Button with values stored inside the database
                int resId = getResources().getIdentifier(mat.getID(), "id", getActivity().getPackageName());
                Button changedButton = (Button) view.findViewById(resId);
                changedButton.setText(mat.getMateria());
                changedButton.setTypeface(null, Typeface.BOLD);

                Drawable style = setButtonColor(mat.getColor());
                changedButton.setBackground(style);
            }
        }

        return view;
    }
person Dario    schedule 20.09.2016