Interacción betweens Fragmentos y Actividad

tarifas:

Estoy teniendo algunas dificultades para hacer frente a los interacciones entre fragmentos y entre los fragmentos y mi actividad, especialmente ClickListener-wise.

Estoy desarrollando una aplicación de calculadora compuesto de 2 fragmentos:

  • Un fragmento contiene todos los Buttons(números y operadores)
  • la otra contiene el 2 TextViews(operación y resultado)

El objetivo aquí es hacer que estos dos fragmentos se comunican entre sí. Se supone que tengo que enviar caracteres y cadenas a un TextView hasta que haga clic en el botón de la (en la que me he puesto un ClickListener) "es igual a", pero me parece que no puede ni usar los otros botones o enviar la información (IT me mantiene advirtiendo que el TextView es nula, a pesar de las interfaces).

Este es el fragmento que contiene todos los botones y los operadores:

package fr.android.calculator.Fragments;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import fr.android.calculator.R;

/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link LowerCalculatorFragment.OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link LowerCalculatorFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class LowerCalculatorFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";


    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private OnFragmentInteractionListener mListener;

    public LowerCalculatorFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment LowerCalculatorFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static LowerCalculatorFragment newInstance(String param1, String param2) {
        LowerCalculatorFragment fragment = new LowerCalculatorFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_lower_calculator, container, false);
        Button button = new Button(getContext());
        LinearLayout buttonContainer = view.findViewById(R.id.resultButtonFragment);
        button.setText("=");
        button.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
        button.setId(R.id.buttonEqualsFragment);
        buttonContainer.addView(button);
        button.setOnClickListener(v -> onButtonPressed(v));

        return view;
    }

    public void onViewCreated(View view, @Nullable Bundle savedInstanceState){
        super.onViewCreated(view,savedInstanceState);
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(View view) {
        if (mListener != null) {
            mListener.lowerFragmentInteraction(view);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }



    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void lowerFragmentInteraction(View view);
    }
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
                                                   xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
                                                   android:layout_width="match_parent"
                                                   android:layout_height="match_parent"
                                                   tools:context=".Activities.CalculatorSecondActivity"
                                                   android:id="@+id/frameLayout">
    <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="match_parent" android:id="@+id/numberOperators" android:baselineAligned="false">
        <LinearLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent" android:id="@+id/numbers" android:layout_weight="1">
            <LinearLayout
                    android:orientation="horizontal"
                    android:layout_width="match_parent"
                    android:layout_weight="1"
                    android:layout_height="match_parent" android:id="@+id/SevenToPlus">
                <Button
                        android:text="7"
                        android:layout_width="0dp"
                        android:layout_height="match_parent" android:id="@+id/button18" android:layout_weight="1"
                        android:onClick="onButtonClick"/>
                <Button
                        android:text="8"
                        android:layout_width="0dp"
                        android:onClick="onButtonClick"
                        android:layout_height="match_parent" android:id="@+id/button19" android:layout_weight="1"
                        />
                <Button
                        android:text="9"
                        android:layout_width="0dp"
                        android:onClick="onButtonClick"
                        android:layout_height="match_parent" android:id="@+id/button20" android:layout_weight="1"
                        />
                <Button
                        android:text="+"
                        android:layout_width="0dp"
                        android:onClick="onButtonClick"
                        android:layout_height="match_parent" android:id="@+id/button21" android:layout_weight="1"
                        />
            </LinearLayout>
            <LinearLayout
                    android:orientation="horizontal"
                    android:layout_width="match_parent"
                    android:layout_weight="1"
                    android:layout_height="match_parent" android:id="@+id/FourToMinus">
                <Button
                        android:text="4"
                        android:layout_width="0dp"
                        android:onClick="onButtonClick"
                        android:layout_height="match_parent" android:id="@+id/button22" android:layout_weight="1"
                        />
                <Button
                        android:text="5"
                        android:layout_width="0dp"
                        android:onClick="onButtonClick"
                        android:layout_height="match_parent" android:id="@+id/button23" android:layout_weight="1"
                        />
                <Button
                        android:text="6"
                        android:layout_width="0dp"
                        android:layout_height="match_parent" android:id="@+id/button24" android:layout_weight="1"
                        />
                <Button
                        android:text="-"
                        android:layout_width="0dp"
                        android:onClick="onButtonClick"
                        android:layout_height="match_parent" android:id="@+id/button25" android:layout_weight="1"
                        />
            </LinearLayout>
            <LinearLayout
                    android:orientation="horizontal"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" android:layout_weight="1" android:id="@+id/OneToAsterix">
                <Button
                        android:text="1"
                        android:layout_width="0dp"
                        android:onClick="onButtonClick"
                        android:layout_height="match_parent" android:id="@+id/button26" android:layout_weight="1"
                        />
                <Button
                        android:text="2"
                        android:layout_width="0dp"
                        android:onClick="onButtonClick"
                        android:layout_height="match_parent" android:id="@+id/button27" android:layout_weight="1"
                        />
                <Button
                        android:text="3"
                        android:layout_width="0dp"
                        android:onClick="onButtonClick"
                        android:layout_height="match_parent" android:id="@+id/button28" android:layout_weight="1"
                        />
                <Button
                        android:text="*"
                        android:layout_width="0dp"
                        android:onClick="onButtonClick"
                        android:layout_height="match_parent" android:id="@+id/button29" android:layout_weight="1"
                        />
            </LinearLayout>
            <LinearLayout
                    android:orientation="horizontal"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" android:layout_weight="1">
                <Button
                        android:text="0"
                        android:layout_width="0dp"
                        android:onClick="onButtonClick"
                        android:layout_height="match_parent" android:id="@+id/button32" android:layout_weight="1"
                        />
                <Button
                        android:text="/"
                        android:layout_width="0dp"
                        android:onClick="onButtonClick"
                        android:layout_height="match_parent" android:id="@+id/button33" android:layout_weight="1"
                        />
            </LinearLayout>
        </LinearLayout>
        <LinearLayout
                android:layout_margin="10dp"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/resultButtonFragment" android:layout_weight="4" android:orientation="vertical"
                >
        </LinearLayout>
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Y este es el fragmento que contiene ambos TextViews:

package fr.android.calculator.Fragments;

import android.content.Context;
import android.os.Bundle;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import fr.android.calculator.R;

/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link UpperCalculatorFragment.OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link UpperCalculatorFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class UpperCalculatorFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;
    private TextView resultDisplay;
    private TextView operations;

    private OnFragmentInteractionListener mListener;

    public UpperCalculatorFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment UpperCalculatorFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static UpperCalculatorFragment newInstance(String param1, String param2) {
        UpperCalculatorFragment fragment = new UpperCalculatorFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_upper_calculator, container, false);
        operations = view.findViewById(R.id.operationsFragment);
        resultDisplay = view.findViewById(R.id.resultDisplayFragment);

        return view;
    }

    public void setOperationsText(String operationsText){
        operations.setText(operationsText);
    }

    public void setResultDisplayText(String resultDisplayText){
        resultDisplay.setText(resultDisplayText);
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(String operations) {
        if (mListener != null) {
            mListener.operationsFragmentInteraction(operations);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void operationsFragmentInteraction(String operations);
        void resultDisplayFragmentInteraction(String resultDisplay);
    }
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:tools="http://schemas.android.com/tools"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             tools:context=".Fragments.UpperCalculatorFragment"
             >
    <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        <TextView
                android:background="@drawable/textview_border"
                android:layout_marginRight="20dp"
                android:layout_width="match_parent"
                android:layout_height="match_parent" android:id="@+id/operationsFragment" android:layout_weight="2"/>
        <TextView
                android:background="@drawable/textview_border"
                android:layout_width="match_parent"
                android:layout_height="match_parent" android:id="@+id/resultDisplayFragment" android:layout_weight="3"/>
    </LinearLayout>
</FrameLayout>

La actividad en sí misma que está en el medio es la siguiente:

package fr.android.calculator.Activities;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import fr.android.calculator.Fragments.LowerCalculatorFragment;
import fr.android.calculator.Fragments.UpperCalculatorFragment;
import fr.android.calculator.R;
import org.mozilla.javascript.Context;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class CalculatorSecondActivity extends AppCompatActivity implements LowerCalculatorFragment.OnFragmentInteractionListener, UpperCalculatorFragment.OnFragmentInteractionListener {
    private LowerCalculatorFragment lowerCalculatorFragment;
    private UpperCalculatorFragment upperCalculatorFragment;
    private Context rhino = Context.enter(); // runtime environment 
    private TextView operations;
    private Button value;
    private String result;
    private TextView resultDisplay;
    private Handler handler;
    private DataInputStream dataInputStream;
    private DataOutputStream dataOutputStream;
    private String resp;
    private Socket socket;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_calculator_second);
        lowerCalculatorFragment = LowerCalculatorFragment.newInstance("fragment", "you");
        upperCalculatorFragment = UpperCalculatorFragment.newInstance("new fragment", "you 2");

        getSupportFragmentManager().beginTransaction().add(R.id.lowerCalculator, lowerCalculatorFragment);
        getSupportFragmentManager().beginTransaction().add(R.id.upperCalculator, upperCalculatorFragment);

        getSupportFragmentManager().beginTransaction().commit();

    }

    @Override
    public void operationsFragmentInteraction(String message) {
        upperCalculatorFragment = (UpperCalculatorFragment) getSupportFragmentManager().findFragmentById(R.id.upperCalculator);
        upperCalculatorFragment.setOperationsText(message);

    }

    @Override
    public void resultDisplayFragmentInteraction(String message) {
        upperCalculatorFragment = (UpperCalculatorFragment) getSupportFragmentManager().findFragmentById(R.id.upperCalculator);
        upperCalculatorFragment.setResultDisplayText(message);
    }


    @Override
    public void lowerFragmentInteraction(View view) {

        value = view.findViewById(view.getId());
        System.out.println("Value : " + value.getText());
        if (value != view.findViewById(R.id.buttonEqualsFragment)) {
            System.out.println("Value : " + value.getText());
            operationsFragmentInteraction((String) value.getText());
        } else {
            // Avec Async 
            new AsyncTaskRunner().execute((String) operations.getText());

            /* Avec Handler*/
            //calculate((String) operations.getText());

        }
    }

    public void onButtonClick(View view){
        lowerCalculatorFragment.onButtonPressed(view);
    }

    public void calculate(String operations) {
        Runnable runnable = () -> {
            try {
                socket = new Socket("10.0.2.2", 9876);
                dataInputStream = new DataInputStream(socket.getInputStream());
                dataOutputStream = new DataOutputStream(socket.getOutputStream());
                dataOutputStream.writeUTF(operations);
                result = dataInputStream.readUTF();
                dataOutputStream.close();
                dataInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            handler.post(() -> resultDisplay.setText(result));
        };

        new Thread(runnable).start();
    }

    private class AsyncTaskRunner extends AsyncTask<String, String, String> {


        @Override
        protected String doInBackground(String... params) {
            try {
                socket = new Socket("10.0.2.2", 9876);
                dataInputStream = new DataInputStream(socket.getInputStream());
                dataOutputStream = new DataOutputStream(socket.getOutputStream());
                dataOutputStream.writeUTF(params[0]);
                result = dataInputStream.readUTF();

                dataOutputStream.close();
                dataInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            publishProgress(params[0]); // Calls onProgressUpdate()
            resp = "Slept for " + 5 + " seconds";
            return resp;
        }

        protected void onProgressUpdate(String... text) {
            resultDisplayFragmentInteraction(result);
        }

    }
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:showIn="@layout/activity_calculator_second"
        tools:context=".Activities.CalculatorSecondActivity">


    <LinearLayout android:orientation="vertical"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" android:weightSum="5">
        <fragment android:layout_width="match_parent" android:layout_height="119dp"
                  android:name="fr.android.calculator.Fragments.UpperCalculatorFragment"
                  android:id="@+id/upperCalculator"
                  tools:layout="@layout/fragment_upper_calculator"
                  android:layout_weight="1"/>
        <fragment android:name="fr.android.calculator.Fragments.LowerCalculatorFragment"
                  android:layout_width="409dp" android:layout_height="413dp"
                  android:id="@+id/lowerCalculator" tools:layout="@layout/fragment_lower_calculator"
                  android:layout_weight="4"/>
    </LinearLayout>


</androidx.constraintlayout.widget.ConstraintLayout>

¿Tienen alguna idea de por qué?

Gracias por adelantado,

Tarifas.

EDIT: He añadido métodos para mis fragmentos después de que el sabio consejo de Edgar. Si he entendido bien, las interfaces permiten a buscar las informaciones, que serán utilizados en los métodos de los fragmentos. Sin embargo a pesar de que he añadido a mis ClickListeners botones, sólo el buttonEqualsFragmentes "escuchado" a. Incluso si elimino errores a menos que haga clic en los buttonEqualsFragmentotros botones no son tomados en cuenta.

He creado un método en la actividad para hacer que la interfaz implementada llama del fragmento. ( onButtonClick)

Edgar:

El problema es que están tratando de mostrar la información en la actividad y no en el fragmento. Pruebe las siguientes sugerencias.

En su UpperCalculatorFragmentclase coloque este en la parte superior:

private Textview operations, results;

después en onCreateView()añadir lo siguiente para asegurar los textviews no son nulos:

operations = view.findViewById(R.id.operationsFragment);
results = view.findViewById(R.id.resultDisplayFragment);

A continuación, tiene que definir un método público todavía en este fragmento (UpperCalculatorFragment) que se encargará de la información de la actividad. Sólo mostrar el resultado de lo que necesita para otra operación, así

public void displayResult(String result){
    results.setText(result);//this displays the result on textview
}

Para mostrar el resultado / operación que tiene que llamar a ese método de la CalculatorSecondActivitycomo tal;

public void displayResultInFragment(String message) {
    UpperCalculatorFragment upperFrag = 
    (UpperCalculatorFragment) getSupportFragmentManager()
      .findFragmentById(R.id.upperCalculator);
    //show the result here after all calculation
    upperFrag.displayResult(message);

}  

Consulte en este desarrolladores de Android docs

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=320857&siteId=1
Recomendado
Clasificación