如何在片段之间很好地设置监听器?
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);
}
我有一个包含 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);
}