Так что я пытался решить эту проблему в течение многих часов, но не могу найти причину этого.
Проблема: Мое приложение отображает данные из моего API в recyclerView, стандартную функцию. Проблема возникает, когда я использую функцию поиска. Когда я что-то ищу, мой поисковый адаптер отображает данные запроса, но снова возвращаясь к основному фрагменту, загрузчик представления показывает содержимое нормально, но когда я нажимаю на него, вместо этого фактически загружаются элементы поиска.
Проверка мое приложение, чтобы узнать, о чем я говорю: https://play.google.com/store/apps/details?id=envision.apps.newsextra
Чтобы воспроизвести, найдите что-нибудь, нажмите на любую статью из результатов поиска, затем go назад и нажмите любую статья из основного канала, вместо этого на самом деле загружаются элементы поиска.
Вот мой основной фрагмент:
public class FeedsFragment extends Fragment implements ArticleListener, LocalMessageCallback {
private PullRefreshLayout pullRefreshLayout;
private RecyclerView recyclerView;
private FeedsAdapter adapter;
private View layout;
private ArrayList<Object> data = new ArrayList<>();
private List<Favorites> favorites = new ArrayList<>();
private List<Articles> articles = new ArrayList<>();
private boolean init = true;
private DataViewModel dataViewModel;
private NativeAdsManager mNativeAdsManager;
private String sort_date = SharedPrefernces.getFeedSortDate();
public static FeedsFragment newInstance() {
return new FeedsFragment();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
layout = inflater.inflate(R.layout.feeds_fragment_layout, container, false);
init_views();
setRecyclerView();
initNativeAds();
dataViewModel = ViewModelProviders.of(this).get(DataViewModel.class);
dataViewModel.getFavorites().observe(this, favorites -> {
if(favorites!=null){
this.favorites = favorites;
}
});
dataViewModel.getArticles().observe(this, articles -> {
this.articles = articles;
if(init) {
if (articles!= null && articles.size() > 0) {
//this.articles = articles;
data = new ArrayList<>();
if(SharedPrefernces.getActiveInterest().equalsIgnoreCase(getString(R.string.all_stories))){
data.add(new Info("Showing stories based on all your interests"));
}else{
data.add(new Info("Showing stories on "+SharedPrefernces.getActiveInterest()));
}
data.addAll(articles);
adapter.setData(data);
}
init = false;
}
});
new Handler().postDelayed(() -> {
//we first check if time set to fetch feeds again has elapsed
pullRefreshLayout.setRefreshing(true);
fetchFeeds();
SharedPrefernces.setReloadArticles(false);
}, 1000);
return layout;
}
//init view layouts
private void init_views(){
pullRefreshLayout = layout.findViewById(R.id.pullRefreshLayout);
int[] colorScheme = getResources().getIntArray(R.array.refresh_color_scheme);
pullRefreshLayout.setColorSchemeColors(colorScheme);
pullRefreshLayout.setOnRefreshListener(this::fetchFeeds);
}
//init recyclerview
private void setRecyclerView() {
recyclerView = (RecyclerView) layout.findViewById(R.id.recyclerView);
GridLayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 1);
recyclerView.setLayoutManager(mLayoutManager);
adapter = new FeedsAdapter(getActivity(),recyclerView,this);
//int index = movies.size() - 1;
adapter.setLoadMoreListener(() -> recyclerView.post(() -> {
if(data.size()>0 && data.get(1) instanceof Articles){
adapter.setLoader();
loadMoreFeeds();
}
}));
recyclerView.setAdapter(adapter);
}
private void initNativeAds(){
mNativeAdsManager = new NativeAdsManager(getActivity(), getResources().getString(R.string.FACEBOOK_FEED_NATIVE_AD), 10);
mNativeAdsManager.loadAds();
mNativeAdsManager.setListener(new NativeAdsManager.Listener() {
@Override
public void onAdsLoaded() {
}
@Override
public void onAdError(AdError adError) {
}
});
}
private void fetchFeeds(){
if(!NetworkUtil.hasConnection(getActivity())) {
setNetworkError();
return;
}
NetworkService service = StringApiClient.createServiceWithToken(NetworkService.class);
try {
JSONObject jsonData = new JSONObject();
if(SharedPrefernces.getActiveInterest().equalsIgnoreCase(getString(R.string.all_stories))) {
jsonData.put("interests", new JSONArray(SharedPrefernces.getUserInterests()));
}else{
ArrayList<String> interest = new ArrayList<>();
interest.add(SharedPrefernces.getActiveInterest());
jsonData.put("interests", new JSONArray(interest));
}
if(SharedPrefernces.getUserUnfollowedFeedSources()!=null && SharedPrefernces.getUserUnfollowedFeedSources().size()>0) {
jsonData.put("sources", new JSONArray(SharedPrefernces.getUserUnfollowedFeedSources()));
}
jsonData.put("location", Misc.getCurrentCountryCode());
String requestBody = jsonData.toString();
Log.e("final requestbody",requestBody);
Call<String> callAsync = service.getArticles(requestBody);
callAsync.enqueue(new Callback<String>() {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
Log.e("response",String.valueOf(response.body()));
pullRefreshLayout.setRefreshing(false);
if(response.body()==null){
setNetworkError();
return;
}
try {
JSONObject res = new JSONObject(response.body());
// Add Your Logic
if(res.getString("status").equalsIgnoreCase("ok")){
//create a new object
data = new ArrayList<>();
if(SharedPrefernces.getActiveInterest().equalsIgnoreCase(getString(R.string.all_stories))){
data.add(new Info("Showing stories based on all your interests"));
}else{
data.add(new Info("Showing Stories on "+SharedPrefernces.getActiveInterest()));
}
sort_date = res.getString("date");
SharedPrefernces.setFeedSortDate(sort_date);
ArrayList<Articles> articles = JsonParser.getArticles(res.getJSONArray("feeds"));
//delete all previously store articles, and add new items to database
dataViewModel.deleteAllArticles();
dataViewModel.insertAllArticles(articles);
//append interests to our object list
data.addAll(articles);
//set data to adapter
adapter.setData(data);
//set last fetched time to sharedpreferences
if(articles.size()>0)SharedPrefernces.setArticleLastRefreshTime(System.currentTimeMillis());
}
}catch (Exception e){
e.printStackTrace();
Log.e("error",e.getMessage());
}
}
@Override
public void onFailure(@NonNull Call<String> call, @NonNull Throwable throwable) {
Log.e("error",String.valueOf(throwable.getMessage()));
setNetworkError();
pullRefreshLayout.setRefreshing(false);
}
});
} catch (JSONException e) {
Log.e("parse error",e.getMessage());
e.printStackTrace();
}
}
private void loadMoreFeeds(){
// ToDo
}
private void setNetworkError(){
dataViewModel.deleteAllArticles();
dataViewModel.insertAllArticles(articles);
pullRefreshLayout.setRefreshing(false);
data = new ArrayList<>();
if(SharedPrefernces.getActiveInterest().equalsIgnoreCase(App.getContext().getString(R.string.all_stories))){
data.add(new Info("Showing stories based on all your interests"));
}else{
data.add(new Info("Showing stories on "+SharedPrefernces.getActiveInterest()));
}
data.add(new Error(""));
adapter.setData(data);
}
@Override
public void OnItemClick(Articles article) {
//List<Integer> contestWinners = data.subList(0, 5);
int position = 0;
for (Articles arts: this.articles) {
if(arts.getId() == article.getId()){
position = this.articles.indexOf(arts);
}
}
Gson gson = new Gson();
String json = gson.toJson(article);
Intent intent = new Intent(getActivity(), FeedViewerActivity.class);
intent.putExtra("position", position);
intent.putExtra("article",json);
intent.putExtra(FeedViewerActivity.VIEW_TYPE, Constants.ARTICLE_VIEW);
intent.putExtra(FeedViewerActivity.VIEW_SIZE, get_feeds_view_size(this.articles,position));
startActivity(intent);
Objects.requireNonNull(getActivity()).overridePendingTransition(R.anim.slide_left_in, R.anim.still);
}
@Override
public void OnPinClick(Articles articles,String action) {
if(articles==null)return;
if(action.equalsIgnoreCase(getResources().getString(R.string.add_pin))){
dataViewModel.insertFavorites(ObjectMapper.mapFavorites(articles));
}else {
dataViewModel.deleteFavorite(ObjectMapper.mapFavorites(articles).getId());
}
}
@Override
public void OnShareClick(Articles articles) {
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("text/plain");
share.putExtra(Intent.EXTRA_SUBJECT, articles.getTitle());
share.putExtra(Intent.EXTRA_TEXT, articles.getLink());
startActivity(Intent.createChooser(share, "Share Article"));
}
@Override
public boolean IsPinned(Articles articles) {
for (Favorites fav: favorites) {
if(fav.getId() == articles.getId()){
return true;
}
}
return false;
}
@Override
public void requestAds(int position) {
NativeAd ad = mNativeAdsManager.nextNativeAd();
if(ad!=null){
adapter.setAd(ad,position);
}
}
@Override
public void loadSingleFeedsActivity(Articles articles) {
Gson gson = new Gson();
String myJson = gson.toJson(articles);
Intent intent = new Intent(getActivity(), FeedSourceActivity.class);
intent.putExtra("article", myJson);
startActivity(intent);
}
@Override
public boolean isSingleFeedsActivity() {
return false;
}
@Override
public void onDestroy() {
LocalMessageManager.getInstance().send(R.id.remove_listener);
LocalMessageManager.getInstance().removeListener(this);
super.onDestroy();
}
@Override
public void onStart() {
super.onStart();
LocalMessageManager.getInstance().addListener(this);
}
@Override
public void handleMessage(@NonNull LocalMessage localMessage) {
if(localMessage.getId() == R.id.reload_feeds){
pullRefreshLayout.setRefreshing(true);
fetchFeeds();
SharedPrefernces.setReloadArticles(false);
}
if(localMessage.getId() == R.id.scroll_feeds_to_top){
recyclerView.smoothScrollToPosition(0);
}
}
}
Адаптер:
public class FeedsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements View.OnClickListener {
private ArrayList<Object> data = new ArrayList<>();
private Context context;
private int lastItemPosition = -1;
private final int VIEW_TYPE_HEADER = 1;
private final int VIEW_TYPE_LIST = 2;
private final int VIEW_TYPE_LOADER = 3;
private final int VIEW_TYPE_NETWORK_ERROR = 4;
private final int VIEW_TYPE_INFO = 5;
private final int VIEW_TYPE_AD = 6;
private boolean isLoading = false;
private LoadMoreListener loadMoreListener;
private int visibleThreshold = 2;//visible items before loading next feeds
private int firstVisibleItem,lastVisibleItem, totalItemCount;
private ArticleListener articleListener;
public FeedsAdapter(Context context, RecyclerView mRecyclerView, ArticleListener articleListener) {
this.context=context;
this.articleListener = articleListener;
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LocalMessageManager.getInstance().send(R.id.recyclerview_scroll);
firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition();
totalItemCount = linearLayoutManager.getItemCount();
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
if ((firstVisibleItem + Constants.ADS.NUMBER_OF_ITEMS_BEFORE_REQUEST_AD) % Constants.ADS.LOAD_ADS_AT_POSITION == 0){
//
int pos = firstVisibleItem + Constants.ADS.NUMBER_OF_ITEMS_BEFORE_REQUEST_AD;
if(pos > lastItemPosition && data.size()>pos && data.get(pos - 1) != null/*dont load ad if we r currently making a request*/) {
if (!(data.get(pos) instanceof NativeAd)) {
articleListener.requestAds(pos);
}
}
}
if (!isLoading && NetworkUtil.hasConnection(context)) {
if (totalItemCount <= (lastVisibleItem + visibleThreshold)) {
if (loadMoreListener != null) {
loadMoreListener.onLoadMore();
}
isLoading = true;
}
}
}
});
}
@Override
public int getItemViewType(int position) {
if(data.get(position) instanceof Error)return VIEW_TYPE_NETWORK_ERROR;
if(data.get(position) instanceof Info)return VIEW_TYPE_INFO;
if(data.get(position) instanceof NativeAd)return VIEW_TYPE_AD;
if(SharedPrefernces.get_feed_images_show()
&& SharedPrefernces.get_feed_type() == 1
&& position==1 && data.get(position) instanceof Articles){
return VIEW_TYPE_HEADER;
}
if(data.get(position) == null)return VIEW_TYPE_LOADER;
return VIEW_TYPE_LIST;
}
public void setData(ArrayList<Object> objectList) {
Log.e("objectList size",String.valueOf(objectList.size()));
this.data.clear();
this.data.addAll(objectList);
Log.e("data size",String.valueOf(data.size()));
this.notifyDataSetChanged();
}
public void setMoreData(ArrayList<Articles> articles) {
//int start = data.size() + 2;
data.addAll(articles);
//this.notifyItemRangeInserted(start, articles.size());
this.notifyDataSetChanged();
}
public void setAd(NativeAd ad, int pos) {
data.add(pos, ad);
this.notifyItemInserted(pos);
}
@Override
public int getItemCount() {
return data != null ? data.size() : 0;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
lastItemPosition = position;
//Log.e("view type",String.valueOf(holder.getItemViewType()));
switch (holder.getItemViewType()) {
case VIEW_TYPE_LIST: case VIEW_TYPE_HEADER:
final ArticleViewHolder viewHolder = (ArticleViewHolder) holder;
viewHolder.bindTo((Articles) data.get(position));
break;
case VIEW_TYPE_LOADER:
final ViewLoader viewLoader = (ViewLoader) holder;
viewLoader.rotateLoading.start();
break;
case VIEW_TYPE_NETWORK_ERROR:
ViewError viewError = (ViewError) holder;
if(SharedPrefernces.getUseNightMode()){
viewError.img.setColorFilter(App.getContext().getResources().getColor(R.color.white));
}else{
viewError.img.setColorFilter(App.getContext().getResources().getColor(R.color.black));
}
break;
case VIEW_TYPE_INFO:
final ViewInfo viewInfo = (ViewInfo) holder;
Info info = (Info)data.get(position);
viewInfo.body.setText(info.getContent());
break;
case VIEW_TYPE_AD:
final AdsViewHolder adsViewHolder = (AdsViewHolder) holder;
NativeAd nativeAd = (NativeAd)data.get(position);
adsViewHolder.bind(nativeAd);
break;
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int i) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(context);
switch (i) {
case VIEW_TYPE_HEADER:
View v = inflater.inflate(R.layout.feeds_header, parent, false);
viewHolder = new ArticleViewHolder(v, articleListener);
break;
case VIEW_TYPE_LIST:
View va;
if(SharedPrefernces.get_feed_images_show() && SharedPrefernces.get_feed_type()==0){
va = inflater.inflate(R.layout.large_image_feeds_list, parent, false);
}else{
va = inflater.inflate(R.layout.feeds_list, parent, false);
}
viewHolder = new ArticleViewHolder(va, articleListener);
break;
case VIEW_TYPE_LOADER:
View ld = inflater.inflate(R.layout.loader, parent, false);
viewHolder = new ViewLoader(ld);
break;
case VIEW_TYPE_NETWORK_ERROR:
View ne = inflater.inflate(R.layout.no_stories, parent, false);
viewHolder = new ViewError(ne);
break;
case VIEW_TYPE_INFO:
View info = inflater.inflate(R.layout.info, parent, false);
viewHolder = new ViewInfo(info);
break;
case VIEW_TYPE_AD:
View ads = inflater.inflate(R.layout.ad_item_large, parent, false);
viewHolder = new AdsViewHolder(ads);
break;
}
return viewHolder;
}
@Override
public void onClick(View view) {
//int pos = (int) view.getTag();
switch (view.getId()){
case R.id.pin:
break;
case R.id.share:
break;
}
}
public class ViewLoader extends RecyclerView.ViewHolder {
private RotateLoading rotateLoading;
ViewLoader(View view) {
super(view);
rotateLoading = (RotateLoading) view.findViewById(R.id.rotateloading);
}
}
public class ViewError extends RecyclerView.ViewHolder {
private ImageView img;
ViewError(View view) {
super(view);
img = view.findViewById(R.id.img);
}
}
public class ViewInfo extends RecyclerView.ViewHolder {
private TextView body;
ViewInfo(View view) {
super(view);
body = view.findViewById(R.id.body);
}
}
public void setLoaded(){
data.remove(data.size()-1);
this.notifyItemRemoved(data.size()-1);
isLoading = false;
}
public void setLoadMoreListener(LoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void setLoader(){
data.add(null);
this.notifyItemInserted(data.size()-1);
}
}
Адаптер поиска:
public class SearchAdapter extends RecyclerView.Adapter< RecyclerView.ViewHolder>{
private List<Object> items = new ArrayList<>();
private final int VIEW_TYPE_MEDIA = 0;
private final int VIEW_TYPE_LOADING = 1;
private final int VIEW_TYPE_AD = 2;
private SearchClickListener searchClickListener;
private LoadMoreListener mOnLoadMoreListener;
private boolean isLoading;
private int visibleThreshold = 2;
public int firstVisibleItem,lastVisibleItem, totalItemCount;
private int lastItemPosition = -1;
public SearchAdapter(RecyclerView mRecyclerView, SearchClickListener searchClickListener) {
this.searchClickListener = searchClickListener;
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition();
totalItemCount = linearLayoutManager.getItemCount();
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
if ((firstVisibleItem + Constants.ADS.NUMBER_OF_ITEMS_BEFORE_REQUEST_AD) % Constants.ADS.LOAD_ADS_AT_POSITION == 0){
//
int pos = firstVisibleItem + Constants.ADS.NUMBER_OF_ITEMS_BEFORE_REQUEST_AD;
if(pos > lastItemPosition && items.size()>pos && items.get(pos - 1) != null/*dont load ad if we r currently making a request*/) {
if (!(items.get(pos) instanceof NativeAd)) {
searchClickListener.requestAds(pos);
}
}
}
if (!isLoading && NetworkUtil.hasConnection(App.getContext())) {
if (totalItemCount <= (lastVisibleItem + visibleThreshold)) {
if (items.size() > 1 && mOnLoadMoreListener != null) {
mOnLoadMoreListener.onLoadMore();
}
isLoading = true;
}
}
}
});
}
public void setMoreAdapter(List<Search> data) {
items.addAll(data);
//items.addAll((items.size()-1),data);
this.notifyDataSetChanged();
}
public void setAdapter(List<Search> data) {
items = new ArrayList<>();
items.addAll(data);
this.notifyDataSetChanged();
}
@Override
public int getItemCount() {
return items != null ? items.size() : 0;
}
@Override
public int getItemViewType(int position) {
if(items.get(position) instanceof NativeAd)return VIEW_TYPE_AD;
if(items.get(position)==null && position == (items.size()-1)){
return VIEW_TYPE_LOADING;
}else{
return VIEW_TYPE_MEDIA;
}
}
public void setLoader() {
items.add(null);
this.notifyItemInserted(items.size() - 1);
}
public void setAd(NativeAd ad, int pos) {
items.add(pos, ad);
this.notifyItemInserted(pos);
}
public void removeLoader() {
items.remove(items.size() - 1);
this.notifyItemRemoved(items.size());
}
public void setOnLoadMoreListener(LoadMoreListener mOnLoadMoreListener) {
this.mOnLoadMoreListener = mOnLoadMoreListener;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
switch (i) {
case VIEW_TYPE_MEDIA:
View v = inflater.inflate(R.layout.search_list, viewGroup, false);
viewHolder = new SearchViewHolder(v,searchClickListener);
viewHolder.itemView.setClickable(true);
break;
case VIEW_TYPE_LOADING:
View vL = inflater.inflate(R.layout.loader, viewGroup, false);
viewHolder = new LoadingViewHolder(vL);
break;
case VIEW_TYPE_AD:
View ads = inflater.inflate(R.layout.ad_item_small, viewGroup, false);
viewHolder = new AdsViewHolder(ads);
break;
}
return viewHolder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int i) {
lastItemPosition = i;
switch (holder.getItemViewType()) {
case VIEW_TYPE_LOADING:
LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;
loadingViewHolder.progressBar.start();
break;
case VIEW_TYPE_MEDIA:
final SearchViewHolder viewHolder = (SearchViewHolder) holder;
final Search ci = (Search)items.get(i);
viewHolder.bindTo(ci);
break;
case VIEW_TYPE_AD:
final AdsViewHolder adsViewHolder = (AdsViewHolder) holder;
NativeAd nativeAd = (NativeAd)items.get(i);
adsViewHolder.bind(nativeAd);
break;
}
}
private static class LoadingViewHolder extends RecyclerView.ViewHolder {
private RotateLoading progressBar;
private LoadingViewHolder(View itemView) {
super(itemView);
progressBar = itemView.findViewById(R.id.rotateloading);
}
}
public void setLoaded() {
isLoading = false;
}
public interface SearchClickListener {
void onClick(Search search);
void requestAds(int position);
}
}
Серьезно, любая помощь будет принята с благодарностью.