java—如何在片段中找到主机活动的按钮id,并将数据发送到片段中的主机活动

sgtfey8w  于 2021-06-27  发布在  Java
关注(0)|答案(1)|浏览(301)

编辑:我按照建议更改了代码,但我的应用程序仍然崩溃。我把错误贴在问题的最下面
我已经试了两天了,只需点击一个不在片段中的按钮(它在宿主活动中),就可以将一个edittext数据从片段发送到主活动,尽管我觉得答案可能很简单,但这样做有困难!
这里有一些答案建议使用一个接口,但我在片段中找不到任何不使用按钮的示例。当我试图在片段外找到一个按钮,然后发送数据时,我得到一个运行时错误。
我的代码
java中,应该接收字符串的代码部分位于submitformentries的底部

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.google.android.material.tabs.TabLayout;

public class FormActivity extends AppCompatActivity{

    private static final String TAG = "PROCESS";
    TabLayout tabLayout;
    ViewPager viewPager;
    oneFragment fragA =  new oneFragment();

    //or set to 0 and change it dynamically in the onPageSelected method
    private int numFrags = 2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_formactivity);
        viewPager = findViewById(R.id.viewPager);
        tabLayout = findViewById(R.id.tabLayout);

        getTabs();

        //Add onPageChangeListener to get the position of the current tab and change the button text based on the position
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                Button back = findViewById(R.id.backButton);
                Button next = findViewById(R.id.nextButton);
                Button mainReturn = findViewById(R.id.mainReturn);
                Button submit = findViewById(R.id.submitButton);
                PagerAdapter adapter = viewPager.getAdapter();
                //numFrags = viewPager.getAdapter().getCoBunt() -1; - dynamically get new frags

                if (position == 0) {
                    back.setVisibility(View.GONE);
                    next.setVisibility(View.VISIBLE);
                    mainReturn.setVisibility(View.VISIBLE);

                }
                else if (adapter != null && position == numFrags) {
                    back.setVisibility(View.VISIBLE);
                    next.setVisibility(View.GONE);
                    submit.setVisibility(View.VISIBLE);

                    }
                else {
                    back.setVisibility(View.VISIBLE);
                    next.setVisibility(View.VISIBLE);
                    mainReturn.setVisibility(View.GONE);
                    submit.setVisibility(View.GONE);
                }
            }
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }
            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });

    }

    //Add fragments to viewPager using the object ViewPagerAdapter
    public void getTabs(){
       final ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());

        new Handler().post(new Runnable() {
            @Override
            public void run() {
                viewPagerAdapter.addFragment(oneFragment.getInstance(),null);
                viewPagerAdapter.addFragment(twoFragment.getInstance(),null);
                viewPagerAdapter.addFragment(threeFragment.getInstance(),null);

                viewPager.setAdapter(viewPagerAdapter);
                tabLayout.setupWithViewPager(viewPager);
            }
        });
    }

    //METHODS FOR THE BUTTON LISTENERS
    public void goBack(View view) {
        viewPager.setCurrentItem(viewPager.getCurrentItem()-1);

    }
    public void goNext(View view) {
        viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
    }

    public void submitFormEntries(View view) {
        Intent intent = getIntent();
        String message = intent.getStringExtra("Answer One");
        Log.d(TAG, message);
    }

    public void returnToMainMenu(View view) {
        Log.d(TAG, "returnToMainMenu: ");
    }
}

我的片段代码onefragment.java:

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class oneFragment extends Fragment{

    private EditText answer_One;

    public static oneFragment getInstance() {
        oneFragment oneFragment = new oneFragment();
        return oneFragment;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.page_one, container, false);
        final Button submit = (Button) getActivity().findViewById(R.id.submitButton);
        answer_One = (EditText) view.findViewById(R.id.answerOne);

        if(answer_One != null){
            submit.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) {
                    Intent intent = new Intent(requireActivity().getBaseContext(),
                            FormActivity.class);
                    intent.putExtra("Answer One", answer_One.toString());
                    getActivity().startActivity(intent);
                }
            });

        }
        return view;
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
    }

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

}

viewpageradaper.java文件

import java.util.ArrayList;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;

public class ViewPagerAdapter extends FragmentStatePagerAdapter {

    private List<Fragment> fragmentList = new ArrayList<>();
    private List<String> stringList = new ArrayList<>();

    public ViewPagerAdapter(@NonNull FragmentManager fm) {
        super(fm);
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        return fragmentList.get(position);
    }

    @Override
    public int getCount() {
        return fragmentList.size();
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return stringList.get(position);
    }

    public void addFragment(Fragment fragment, String title){
        fragmentList.add(fragment);
        stringList.add(title);
    }
}

我的错误消息,编辑以反映答案

2021-01-07 19:08:07.767 8786-8786/net.larntech.tablayout E/AndroidRuntime: FATAL EXCEPTION: main
    Process: net.larntech.tablayout, PID: 8786
    java.lang.IllegalStateException: Fragment oneFragment{9ca3c26} (7a20c5f2-8918-4de4-98a6-bed63353b415)} not attached to an activity.
        at androidx.fragment.app.Fragment.requireActivity(Fragment.java:833)
        at net.larntech.tablayout.oneFragment$1.onClick(oneFragment.java:37)
        at android.view.View.performClick(View.java:6294)
        at android.view.View$PerformClick.run(View.java:24770)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

编辑:以下是XML
主要活动:activity\ u formactivity.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    tools:context=".FormActivity">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true">

        <Button
            android:id="@+id/backButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/back"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:onClick="goBack"
            android:visibility="gone"/>

        <Button
            android:id="@+id/mainReturn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/mainReturn"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:onClick="returnToMainMenu"
            android:visibility="visible"/>

        <Button
            android:id="@+id/nextButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/next"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:onClick="goNext"/>

        <Button
            android:id="@+id/submitButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/submit"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:onClick="submitFormEntries"
            android:visibility="gone"/>

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tabLayout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:tabBackground="@drawable/tab_selector"
            app:tabIndicatorHeight="0dp" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</RelativeLayout>

片段xml文件页\ u one.xml

<?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">

    <TextView
        android:id="@+id/titleOne"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="@string/title_one"
        android:textColor="@color/colorPrimaryDark"
        android:textSize="32sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/questionOne"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:text="@string/questionOne"
        android:textColor="@color/colorPrimaryDark"
        android:textSize="18sp"
        app:layout_constraintBottom_toTopOf="@+id/descriptionOne"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@+id/descriptionOne"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:text="@string/descriptionOne"
        android:textSize="18sp"
        app:layout_constraintBottom_toTopOf="@+id/answerOne"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <EditText
        android:id="@+id/answerOne"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="@string/answerHintOne"
        android:inputType="textMultiLine"
        android:maxLines="4"
        android:minLines="4"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />
</androidx.constraintlayout.widget.ConstraintLayout>

顺便说一句,我需要用相当多的片段来完成这个任务,所以像bundle和sharedpref这样的解决方案并不理想。如果答案是建立一个接口,我该怎么做呢?

g0czyy6m

g0czyy6m1#

在你的碎片里,你不能打电话 getView()onCreateView 因为片段视图还没有创建;事实上 onCreateView() 创建片段视图并返回它。
所以要解决这个问题,需要使用膨胀视图本身。

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.page_one, container, false);
    // answer_One = (EditText) getView().findViewById(R.id.answerOne); // returns NPE
    answer_One = (EditText) view.findViewById(R.id.answerOne); // << Use this
...

更新
您需要访问中的活动按钮 onResume 碎片的形状如下

@Override
public void onResume() {
    super.onResume();

    final Button submit = (Button) (FormActivity getActivity()).findViewById(R.id.submitButton); 

    submit.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            Intent intent = new Intent(requireActivity().getBaseContext(),
                    FormActivity.class);
            intent.putExtra("Answer One", answer_One.toString());
            getActivity().startActivity(intent);
        }
    });     
}

从中删除按钮及其侦听器 onCreateView() 方法

相关问题