【问题标题】:Remove Fragment 2 from BackStack and pass data to Fragment 1从 BackStack 中移除 Fragment 2 并将数据传递给 Fragment 1
【发布时间】:2019-10-18 09:56:52
【问题描述】:

在我的 MainActivity (Demo) 中,我将 FragmentDemo 1 添加到 backstack。在这个 fragmentDemo 1 中,按下一个按钮会打开一个新的 FragmentDemo 2,其中有一个编辑文本。在按下第二个片段上的按钮时,我想将其从后台堆栈中删除并将数据从 editText 发送回 FragmentDemo 1。

我在 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();
}
}

片段接口

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

片段演示 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();
}
}

片段演示 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);
}

}

预期的结果是从 backstack 中删除片段 2 并打开片段 1,并接收来自片段 2 的数据。

【问题讨论】:

    标签: android android-fragments android-activity listener


    【解决方案1】:

    分片回栈示例。

    参考这个网址https://www.dev2qa.com/android-fragment-back-stack-example/

    【讨论】:

    • 我已经查看了本教程,但这并不是将数据从片段 3 传递到片段 2。
    【解决方案2】:

    现有代码中的问题

    您尝试在 FragmentDemo2 中使用的 Context 属于 Demo 活动(不是 FragmentDemo1),因此您在尝试附加时无法将其类型转换为侦听器

    如果您想使用现有代码实现相同的目标,请按照以下步骤操作

    1) 从 FragmentDemo2 公开 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 进行通信

    希望这些信息对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-19
      • 1970-01-01
      • 1970-01-01
      • 2018-11-20
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      相关资源
      最近更新 更多