从BackStack中删除片段2并将数据传递到片段1

时间:2019-06-02 17:19:52

标签: android android-fragments android-activity listener

在我的MainActivity(Demo)里面,我将FragmentDemo 1添加到了backstack。在fragmentDemo 1的内部,按一个按钮将打开一个新的FragmentDemo 2,在其中有一个编辑文本。在按下第二个片段上的按钮时,我想将其从Backstack中删除,并将数据从editText发送回FragmentDemo1。

我在Fragment 2上使用侦听器并实现方法,但是在运行代码时,我收到以下消息。 java.lang.ClassCastException: com.example.teacherapp.activities.Demo@5630fb7must implement Listener

演示(主要活动)

public class Demo extends AppCompatActivity implements FragmentInterface {
private TextView textView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_demo);
    if (savedInstanceState == null) {
        addFragment(new FragmentDemo1());
    }

}

@Override
public void onMyFragment(Fragment fragment) {
    addFragment(fragment);
}

private void addFragment(Fragment fragment){
    getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.demo_container,fragment)
            .addToBackStack(null)
            .commit();
}
}

FragmentInterface

public interface FragmentInterface {
void onMyFragment(Fragment fragment);
}

FragmentDemo 1

public class FragmentDemo1 extends Fragment implements FragmentInterface, FragmentDemo2.Fragment2CallBack {
Button btnFrag1;
TextView tvFrag1;

public FragmentDemo1() {
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_fragment_demo1, container, false);
    return view;
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    btnFrag1 = view.findViewById(R.id.fragment1_button);
    tvFrag1 = view.findViewById(R.id.fragment1_tv);
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    FragmentManager fm = getFragmentManager();
    btnFrag1.setText("Frag 1: " + String.valueOf(fm.getBackStackEntryCount()));

    btnFrag1.setOnClickListener(v -> {
        replaceFragment(new FragmentDemo2());
    });
}

@Override
public void onMyFragment(Fragment fragment) {
    replaceFragment(fragment);
}

private void replaceFragment(Fragment fragment) {
    getFragmentManager().
            beginTransaction().
            replace(R.id.demo_container, fragment).
            addToBackStack(null).
            commit();
}

@Override
public void onDataSent(String myData) {
    Toast.makeText(getContext(), "RECEIVED. "+myData, Toast.LENGTH_LONG).show();
}
}

FragmentDemo 2

public class FragmentDemo2 extends Fragment {
private Button btnFrag2;
private EditText etFrag2;
private Fragment2CallBack listener;


public FragmentDemo2(){}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                         @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_fragment_demo2,container,false);
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    btnFrag2=view.findViewById(R.id.fragment2_button);
    etFrag2=view.findViewById(R.id.fragment2_et);
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    FragmentManager fm=getFragmentManager();
    btnFrag2.setOnClickListener(v->{
        String info=etFrag2.getText().toString();
        listener.onDataSent(info);
        fm.popBackStack();
    });
}


@Override
public void onAttach(@NonNull Context context) {
    super.onAttach(context);
    try{
        listener=(Fragment2CallBack) context;
    }catch (ClassCastException e){
        throw new ClassCastException(context.toString()+"must implement Listener");

    }
}

public interface Fragment2CallBack{
    void onDataSent(String s);
}

}

预期结果是将片段2从堆栈中移除,并打开片段1,并从片段2中接收数据。

2 个答案:

答案 0 :(得分:0)

片段返回堆栈示例。

引用此网址https://www.dev2qa.com/android-fragment-back-stack-example/

答案 1 :(得分:0)

现有代码中的问题

您试图在FragmentDemo2中使用的上下文是演示活动(不是FragmentDemo1),因此在尝试附加时无法将其强制类型转换为侦听器

如果要使用现有代码实现相同的目标,请执行以下步骤

1)从FragmentDemo2中公开API,该API可以设置Fragment2Callback类型的侦听器

public void setListener(Fragment2Callback li) {listener = li;} 

2)在FragmentDemo1中,当您创建FragmentDemo2实例时,还需要将自身设置为FragmentDemo2的侦听器

FragmentDemo2 frg = new FragemtDemo2()
frg.setListener(this);
replaceFragment(frg);

3)然后替换FragmentDemo1中的Fragment()

4)从FragmentDemo2内部的onAttach()删除侦听器的转换

因此,现在您在FragmentDemo2中拥有FragmentDemo1作为侦听器,可以用来与FragmentDemo1进行通信

希望此信息对您有帮助