如何在片段之间很好地设置监听器?

How to set up listeners nicely between fragments?

我有一个包含 4 个选项卡的应用程序,所有选项卡都是 Fragment 并且有一个适配器,因为我使用的是 RecyclerView。在第一个选项卡上我有项目。我希望第二个选项卡显示在第一个选项卡上检查的项目并收听更改。当我单击第一段上的按钮时,第三个选项卡显示第二个选项卡中的项目(=第一个选项卡选中的项目)。现在我在 onCreate 和 onCreateView 中设置监听器。有时它在工作,有时不工作。我怀疑创建方法不是每次都以相同的顺序执行。另一个问题是有时我的片段必须通知监听器,有时是片段的适配器。我该如何善待它?

第一个选项卡(它的适配器会通知)

public class EventFragment extends Fragment implements BettingEventAdapter.BettingItemClickListener {

    private RecyclerView recyclerView;
    static private BettingEventAdapter adapter;
    private BettingListDatabase database;
    private static Answer bettingData = null;
    private static final String TAG = "EVENT";
    private static BettingEventAdapter.BettingItemClickListener listener;

    public static void setListener(BettingEventAdapter.BettingItemClickListener _listener) {
        listener = _listener;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        database = BettingListDatabase.getInstance(this.getContext());

        loadBettingData();

    }

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

        recyclerView = view.findViewById(R.id.MainRecyclerView);
        adapter = new BettingEventAdapter(this);
        adapter.addBettingItemListener(listener);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getBaseContext()));
        recyclerView.setAdapter(adapter);

        loadItemsInBackground();

        return view;
    }

第二个标签:

public class TicketFragment extends Fragment implements BettingEventAdapter.BettingItemClickListener {

    private RecyclerView recyclerView;
    TextView prizeTextView;
    EditText stakeInput;
    Button bSave;

    private static BettingTicketAdapter.TicketSaveClickListener listener;
    private BettingListDatabase database;
    private BettingTicketAdapter adapter;
    double odds=1;
    int stake=0;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        database = BettingListDatabase.getInstance(this.getContext());
        EventFragment.setListener(this);
            }

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

        recyclerView = view.findViewById(R.id.TicketRecyclerView);
        adapter = new BettingTicketAdapter();
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getBaseContext()));
        recyclerView.setAdapter(adapter);
}

第三个选项卡:

public class TicketListFragment extends Fragment implements BettingTicketAdapter.TicketSaveClickListener {

    private BettingTicketListAdapter parentAdapter;
    private BettingListDatabase database;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        database = BettingListDatabase.getInstance(this.getContext());
        TicketFragment.setListener(this);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        super.onCreateView(inflater, container, savedInstanceState);

        View view = inflater.inflate(R.layout.fragment_ticket_list,
                container, false);
        RecyclerView parentRecyclerView = view.findViewById(R.id.SavedTicketParentRecyclerView);
        parentAdapter = new BettingTicketListAdapter();
       //TODO db-ből feltölteni
        loadItemsInBackground();
        parentRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getBaseContext()));
        parentRecyclerView.setAdapter(parentAdapter);

        return view;
    }

寻呼机activity:

public class PagerActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pager);
    }

    @Override
    protected void onResume() {
        super.onResume();
        ViewPager mainViewPager = findViewById(R.id.mainViewPager);
        TabPagerAdapter tabPagerAdapter = new TabPagerAdapter(getSupportFragmentManager(), this);
        mainViewPager.setAdapter(tabPagerAdapter);
    }
}

https://developer.android.com/training/basics/fragments/communicating

要允许 Fragment 与其 Activity 通信,您可以在 Fragment class 中定义一个接口并在 Activity 中实现它。片段在其 onAttach() 生命周期方法期间捕获接口实现,然后可以调用接口方法以便与 Activity.

进行通信

这是您的片段的示例:

事件片段

public class EventFragment extends Fragment {
    OnEventSelectedListener callback;

    public void setOnEventSelectedListener(OnEventSelectedListener callback) {
        this.callback = callback;
    }

    // This interface can be implemented by the Activity, parent Fragment,
    // or a separate test implementation.
    public interface OnEventSelectedListener {
        public void onEventSelected(int position);
    }

    // ...
}

寻呼机Activity

    public class PagerActivity extends AppCompatActivity implements EventFragment.OnEventSelectedListener{

    // ...

    // In order to receive event callbacks from the fragment, the activity that
    // hosts it must implement the interface defined in the fragment class.
    //For example, the following activity implements the interface from the above example.

    public void onEventSelected(int position) {
        // ...
    }

    @Override
    public void onAttachFragment(Fragment fragment) {
        if (fragment instanceof EventFragment) {
            EventFragment eventFragment = (EventFragment) fragment;
            eventFragment.setOnEventSelectedListener(this);
        }
    }
}

例如,当用户点击列表项时调用片段中的以下方法。该片段使用回调接口将事件传递给父级 activity.

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    // Send the event to the host activity
    callback.onEventSelected(position);
}