编辑:已解决!
我在我的适配器中使用了static
监听器!
我使用的片段显示了两个不同活动中的对象列表:MainActivity
和SearchActivity
(这些活动使用相同的布局activity_base.xml
)。
此片段具有OnClikedListener
接口,用于管理在RecycleView上单击的项目。监听器设置在片段中的onAttach
。
问题是:我在MainActivity
,我做了一项研究,SearchView
和SearchActivity
被抛出。
当我通过MainActivity
上的后退按钮返回并单击某个项目时,会抛出SearchActivity
的监听器。
如果我通过向上按钮返回,它似乎没问题,因为MainActivity
被重新创建。
这怎么可能?
很多代码,抱歉:
MainActivity.java
public class MainActivity extends BaseActivity implements MediaListFragment.OnClickedListener {
private static final String NEWS_FRAGMENT_TAG = "news_fragment_tag";
@Inject
MSSEndpoints mssEndpoints;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
if (savedInstanceState == null && findViewById(R.id.container) != null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container,
new MediaListFragmentBuilder(mssEndpoints.newsUrl()).build(),
NEWS_FRAGMENT_TAG)
.commit();
}
getToolbar().setTitle(R.string.news);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getSearchView().setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
MenuItem searchMenuItem = getSearchMenuItem();
if (searchMenuItem != null) {
searchMenuItem.collapseActionView();
}
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return true;
}
});
return true;
}
private void loadMedia(Media media) {
Intent intent = new Intent(MainActivity.this, DetailsActivity.class);
intent.putExtra(DetailsActivity.MEDIA, media);
/*
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
MainActivity.this, transitionView, DetailActivity.EXTRA_IMAGE);
ActivityCompat.startActivity(activity, new Intent(activity, DetailActivity.class),
options.toBundle());
*/
startActivity(intent);
}
@Override
public void onItemClicked(Media media) {
loadMedia(media);
}
}
SearchActivity.java
public class SearchActivity extends BaseActivity implements MediaListFragment.OnClickedListener {
private static final String TAG = SearchActivity.class.getSimpleName();
private static final String MEDIALIST_FRAGMENT_TAG = "medialist_fragment";
private static final String STATE_SEARCH = "state_search";
@Inject
MSSEndpoints mssEndpoints;
private String search;
private boolean reload = false;
MediaListFragment resFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
if (savedInstanceState != null) {
search = savedInstanceState.getString(STATE_SEARCH);
} else if (findViewById(R.id.container) != null) {
handleIntent(getIntent());
getSupportFragmentManager().beginTransaction()
.add(R.id.container,
new MediaListFragmentBuilder(mssEndpoints.simpleSearchUrl(search))
.build(),
MEDIALIST_FRAGMENT_TAG)
.commit();
}
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setDisplayHomeAsUpEnabled(true);
}
}
@Override
public void onResume() {
super.onResume();
resFragment = (MediaListFragment) getSupportFragmentManager()
.findFragmentByTag(MEDIALIST_FRAGMENT_TAG);
if (reload && search != null) {
getSearchView().setQuery(search, false);
// TODO sometimes search is thrown twice
resFragment.loadPage(mssEndpoints.simpleSearchUrl(search));
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getSearchView().setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
getSearchView().clearFocus();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return true;
}
});
// TODO up as home
getSearchMenuItem().expandActionView();
getSearchView().setQuery(search, false);
getSearchView().clearFocus();
return true;
}
@Override
protected void onNewIntent(Intent intent) {
handleIntent(intent);
reload = true;
}
@Override
protected void onSaveInstanceState(Bundle saveInstanceState) {
super.onSaveInstanceState(saveInstanceState);
if (search != null) {
saveInstanceState.putString(STATE_SEARCH, search);
}
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
search = intent.getStringExtra(SearchManager.QUERY);
}
}
@Override
public void onItemClicked(Media media) {
Log.d(TAG, "WTF ???????");
}
}
MedialistFragment.java
@FragmentWithArgs
public class MediaListFragment extends BaseFragment implements MediasAdapter.OnItemClickListener {
private static final String TAG = MediaListFragment.class.getSimpleName();
private static final String STATE_MEDIALIST = "state_medialist";
private static final String STATE_PAGE_LOADED = "page_loaded";
@Arg
String page;
@Inject
MSSService mssService;
@Bind(R.id.media_list_recycler_view)
RecyclerView recyclerView;
private OnClickedListener listener;
private boolean isLoading;
private boolean pageLoaded;
private MediasAdapter newsAdapter;
private MediaList mediaList;
private Observable<MediaList> getMediasObservable;
private Observer<MediaList> getMediasObserver = new Observer<MediaList>() {
@Override
public void onCompleted() {
getMediasObservable = null;
isLoading = false;
}
@Override
public void onError(Throwable e) {
getMediasObservable = null;
isLoading = false;
}
@Override
public void onNext(MediaList nextList) {
mediaList.setNextPageUrl(nextList.getNextPageUrl());
if (newsAdapter != null) {
newsAdapter.addMedias(nextList.getMedias());
mediaList.setMedias(newsAdapter.getMedias());
}
pageLoaded = true;
}
};
public interface OnClickedListener {
void onItemClicked(Media media);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
mediaList = savedInstanceState.getParcelable(STATE_MEDIALIST);
pageLoaded = savedInstanceState.getBoolean(STATE_PAGE_LOADED);
}
initAdapters();
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_media_list, container, false);
ButterKnife.bind(this, rootView);
recyclerView.setAdapter(newsAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
return rootView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (OnClickedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnClickedListener");
}
}
@Override
public void onDetach() {
super.onDetach();
// To show the problem
//listener = null;
}
@Override
public void onResume() {
super.onResume();
Log.d(getContext().toString(), "LISTENER IS : " + this.listener);
if (!pageLoaded) {
loadPage(page);
}
}
@Override
public void onSaveInstanceState(Bundle saveInstanceState) {
super.onSaveInstanceState(saveInstanceState);
if (mediaList != null) {
saveInstanceState.putParcelable(STATE_MEDIALIST, mediaList);
saveInstanceState.putBoolean(STATE_PAGE_LOADED, pageLoaded);
}
}
@Subscribe
public void onMediasLatestPositionEvent(MediasLatestPostionEvent event) {
if (canPullNextMedias(event.getPosition()))
pullNextMedias();
}
public void setListener(OnClickedListener listener) {
this.listener = listener;
}
public void loadPage(String page) {
isLoading = true;
resetAdapters();
getMediasObservable = mssService
.getMediaListFromUrl(page)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
addSubscription(getMediasObservable.subscribe(getMediasObserver));
}
private boolean canPullNextMedias(int position) {
return !isLoading && mediaList != null &&
!mediaList.getNextPageUrl().equals(DefaultFactory.MediaList.EMPTY_FIELD_NEXT_PAGE_URL) &&
position > (newsAdapter.getItemCount() - 10);
}
private void pullNextMedias() {
isLoading = true;
getMediasObservable = mssService
.getMediaListFromUrl(mediaList.getNextPageUrl())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
addSubscription(getMediasObservable.subscribe(getMediasObserver));
}
private void initAdapters() {
if (mediaList == null) {
mediaList = InitialFactory.MediaList.constructInitialInstance();
}
newsAdapter = new MediasAdapter(getActivity(), mediaList.getMedias());
newsAdapter.setOnItemClickListener(this);
}
@Override
public void onItemClick(View itemView, int position) {
listener.onItemClicked(mediaList.getMedias().get(position));
}
private void resetAdapters() {
mediaList = InitialFactory.MediaList.constructInitialInstance();
if (newsAdapter != null) {
newsAdapter.clearMedias();
}
}
}
MediaAdapter.java
public class MediasAdapter extends RecyclerView.Adapter<MediasAdapter.ViewHolder> {
private static final String TAG = MediasAdapter.class.getSimpleName();
@Inject
Bus bus;
private Context context;
private List<Media> medias;
private static OnItemClickListener listener;
public interface OnItemClickListener {
void onItemClick(View itemView, int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
@Bind(R.id.title)
public TextView title;
@Bind(R.id.author)
public TextView author;
@Bind(R.id.icon)
public ImageView icon;
public ViewHolder(final View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.onItemClick(itemView, getLayoutPosition());
}
}
});
}
}
public MediasAdapter(Context context, List<Media> medias) {
this.context = context;
this.medias = medias;
MediasebApp app = MediasebApp.get(context);
app.inject(this);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.view_list_item, parent, false));
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final Media media = medias.get(position);
bus.post(new MediasLatestPostionEvent(position));
holder.title.setText(media.getTitle());
holder.author.setText(media.getAuthor());
Picasso.with(context).load(media.getImageUrl())
.into(holder.icon);
}
@Override
public int getItemCount() {
return medias.size();
}
public List<Media> getMedias() {
return medias;
}
public void addMedias(List<Media> medias) {
int currentSize = this.medias.size();
int amountInserted = medias.size();
this.medias.addAll(medias);
notifyItemRangeInserted(currentSize, amountInserted);
}
public void clearMedias() {
int size = medias.size();
medias.clear();
notifyItemRangeRemoved(0, size);
}
}
我尝试在活动中重置onResume
上的监听器,在onCreate
中设置监听器,使用两种不同的布局,不要搞乱xml ID ......
注意:如果我使用另一个片段进入另一个活动,一切都很好。
感谢您阅读此内容。