我有像这样的ViewPagerAdapter
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
List<MovieCategory> movieCategoryList;
public ViewPagerAdapter(FragmentManager fm, List<MovieCategory> movieCategoryList) {
super(fm);
this.movieCategoryList = movieCategoryList;
}
@Override
public Fragment getItem(int position) {
return MoviePagerFragment.start(movieCategoryList, position, "listing");
}
@Override
public int getCount() {
return movieCategoryList.size();
}
@Override
public CharSequence getPageTitle(int position) {
return movieCategoryList.get(position).getCategoryTitle();
}
}
此ViewPagerAdapter在MoviePagerFragment类中使用此静态方法调用MoviePagerFragment
public static Fragment start(List<MovieCategory> movieCategoryList, int position, String from) {
Fragment moviePagerFragment = new MoviePagerFragment();
Bundle basket = new Bundle();
basket.putString("from",from);
basket.putInt("viewpager-position",position);
basket.putParcelableArrayList("movie_category_list", (ArrayList<? extends Parcelable>) movieCategoryList);
basket.putParcelableArrayList("movie_list", (ArrayList<? extends Parcelable>) movieCategoryList.get(position).getMovies());
moviePagerFragment.setArguments(basket);
return moviePagerFragment;
}
现在我在MoviePagerFragment
中注册/取消注册EventBus@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
然后我有一个方法来订阅像这样发送的事件
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(final MovieBuyEvent event) {
final double moviePrice = Double.parseDouble(event.getMoviesItem().getMoviePrice());
final Dialog dialog = new Dialog(getActivity());
dialog.setContentView(R.layout.channel_buy_dialog);
dialog.setCancelable(true);
ImageView imageView = (ImageView) dialog.findViewById(R.id.imageView);
TextView tvName = (TextView) dialog.findViewById(R.id.tvName);
Button bBuy = (Button) dialog.findViewById(R.id.bBuy);
Button bCancel = (Button) dialog.findViewById(R.id.bCancel);
final TextView tvPrice = (TextView) dialog.findViewById(R.id.tvPrice);
final Spinner spinner = (Spinner) dialog.findViewById(R.id.spinner);
Picasso.with(getActivity()).load(event.getMoviesItem().getMoviePicture()).placeholder(R.mipmap.placeholder).into(imageView);
tvName.setText(event.getMoviesItem().getMovieName());
tvPrice.setText(event.getMoviesItem().getMovieName());
dialog.show();
}
正在通过RecyclerViewAdapter的ViewHolder类中的项目的ItemClick广播MovieBuyEvent
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public ViewHolder(View view) {
super(view);
itemView.setClickable(true);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
position = getAdapterPosition();
MoviesItem moviesItem = moviesItemList.get(position);
try {
MovieBuyEvent movieBuyEvent = new MovieBuyEvent();
movieBuyEvent.setMoviesItem(moviesItem);
EventBus.getDefault().post(movieBuyEvent);
} catch (Exception e) {
e.printStackTrace();
}
}
}
现在的问题是,每次刷一个片段时,EventBus都会多次注册和取消注册
onMessageEvent(最终的MovieBuyEvent事件)
方法也被调用多次使Dialog出现多次。那么我应该在ViewPagerAdapter调用的片段中注册/取消注册EventBus?
答案 0 :(得分:1)
如果您有多个注册过来监听MovieBuyEvent
广播的片段,他们都会回复,这是有道理的。如果您在包含可解决问题的viewpager的活动或片段中注册了您的事件监听器。
答案 1 :(得分:1)
您应该将注册活动从onStart()
移至onCreateView()
。这是因为onStart总是called when the Fragment is visible to the user。
然后尝试取消注册onDestroy()
:
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
答案 2 :(得分:0)
如果您从未在viewpager中使用过setOffscreenPageLimit,则应限制为1。 默认情况下,viewpager正在加载当前打开父片段/活动时看到的三个片段,另外两个片段。在初始化viewpager时尝试将setOffscreenPageLimit设置为1。基本上它会一次加载一个片段而不是每个viewpager滚动三个。当您使用事件总线时,它一次只能获得一个片段而不是所有正在使用的片段。