片段与活动之间的相互作用 [英] Interaction betweens Fragments and Activity

查看:85
本文介绍了片段与活动之间的相互作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

面对片段之间以及片段与我的活动之间的交互时,我遇到了一些困难,尤其是在ClickListener方面.

I'm having some difficulty facing the interactions between Fragments and between Fragments and my Activity, especially ClickListener-wise.

我正在开发一个由2个片段组成的计算器应用程序:

I'm developing a Calculator app composed of 2 fragments:

  • 一个片段包含所有Buttons(数字和运算符)
  • 另一个包含2个TextViews(操作和结果)
  • one Fragment contains all the Buttons (numbers and operators)
  • the other contains the 2 TextViews (operation and result)

这里的目标是使这两个片段彼此通信.我应该将字符和字符串发送到TextView,直到我单击等于"按钮(在其上放置了ClickListener),但是我似乎既不使用其他按钮也不发送信息(它一直警告我,尽管有接口,但TextView为null.

The goal here is to make these two Fragments communicate between each other. I'm supposed to send characters and strings to a TextView until I click the on the "equals" button (on which I've put a ClickListener) but I can't seem to neither use the other buttons or send the information (it keeps warning me that the TextView is null, despite the interfaces).

这是包含所有按钮和操作符的片段:

This is the Fragment containing all the buttons and operators :

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>

这是包含两个TextViews的片段:

And this is the Fragment containing both 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>

中间的活动本身就是这个:

The activity itself that's in the middle is this one :

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>

你们有什么主意吗?

谢谢,

票价.

在埃德加的明智建议之后,我向片段添加了方法.如果我理解正确的话,接口将使我们能够获取信息,这些信息将在片段的方法中使用.但是,即使我已将ClickListeners添加到我的按钮中,也仅听"了buttonEqualsFragment. 即使调试,除非单击buttonEqualsFragment,其他按钮也不会考虑在内.

EDIT : I've added methods to my Fragments after the wise advice from Edgar. If I understood correctly, the interfaces allow us to fetch the informations, that will be used in the methods of the fragments. However even though I've added ClickListeners to my buttons, only the buttonEqualsFragmentis "listened" to. Even if I debug unless I click on the buttonEqualsFragment the other buttons aren't taken in account.

我在Activity中创建了一个方法来调用Fragment的已实现接口. (onButtonClick)

I created a method in the Activity to do that called the Fragment's implemented interface. (onButtonClick)

推荐答案

问题是您试图在活动中而不是在片段中显示信息.尝试以下建议.

The problem is you are trying to display the info in the activity and not in the fragment. Try the following suggestions.

在您的UpperCalculatorFragment类中,将其放在顶部:

In yourUpperCalculatorFragment class place this at the top:

private Textview operations, results;

然后在onCreateView()中添加以下内容,以确保textviews不为空:

then in onCreateView() add the following to ensure the textviews are not null:

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

接下来,您必须在此片段(UpperCalculatorFragment)中定义一个公共方法,该方法将处理来自Activity的信息.我只显示结果,您还需要其他操作

Next you have to define a public method still in this fragment (UpperCalculatorFragment) that will handle information from the Activity. I only show result you need another for operation as well

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

要显示结果/操作,您必须像这样从CalculatorSecondActivity调用该方法;

To display the result/operation you have to call that method from the CalculatorSecondActivity like so;

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

}  

请参阅此 Android开发人员文档

这篇关于片段与活动之间的相互作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆