0

我有一個片段,它包含一個RecyclerView,這是填充retrofit 2,在我的Listener中填充適配器並設置在RecyclerView上。RecyclerView +適配器在片段上第一次創建後不可見

,如果應用程序被殺害,當我打開這個片段再次啓動,在第一時間顯示正確,但如果我按後退按鈕或者改變片段,當我試圖進入同一片段RecyclerView與該適配器從不顯示。

我使用這個的gradle上:

compile 'com.android.support:cardview-v7:25.0.1' 
compile 'com.android.support:recyclerview-v7:25.0.1' 
compile 'com.android.support:support-v4:25.0.1' 

這是我的XML:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:background="@android:color/white" 
android:orientation="vertical"> 

<include 
    android:id="@+id/my_toolbar" 
    layout="@layout/standard_toolbar" /> 

<com.sample.ui.CustomSwipeRefreshLayout 
    android:id="@+id/ptr_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:visibility="visible"> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <include 
      android:id="@+id/empty_rewards" 
      layout="@layout/no_near_by_rewards" 
      android:visibility="gone"/> 

     <android.support.v7.widget.RecyclerView 
      android:id="@+id/rewards_list" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:scrollbars="vertical"/> 

    </LinearLayout> 

</com.sample.ui.CustomSwipeRefreshLayoutt> 
</LinearLayout> 

這是我的片段類:

public class RewardsListFragment extends BaseFragment implements GoogleApiClient.ConnectionCallbacks, 
    GoogleApiClient.OnConnectionFailedListener, LocationListener { 

public static volatile boolean refreshOffersListFragment = false; 
public static boolean comingFromDetailFragment = false; 
private static GoogleApiClient locationClient; 

private int LIMIT = 7; 

private View noRewards; 

ArrayList<MerchantListItem> nMerchantList = new ArrayList<>(); 

private RewardsRVArrayAdapter mAdapter; 
private RecyclerView rList; 

// Bool to track whether the app is already resolving an error 
private boolean resolvingError = false; 
private boolean awaitingPermission = false; 
private boolean appSettingsSelected = false; 
private boolean locationSettingsSelected = false; 
private boolean gpsOffScreenDisplayed = false; 
private boolean awaitingHomeCoordinates = true; 

private double homeLatitude = 0.0; 
private double homeLongitude = 0.0; 
private Location currentLocation = null; 
private String permissionStatus; 

MerchantListRequest listRequest; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    return inflater.inflate(R.layout.rewards_list_fragment_2, container, false); 
} 

@Override 
public void onViewCreated(View view, Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 

    rList = (RecyclerView) view.findViewById(rewards_list); 
    noRewards = view.findViewById(R.id.empty_rewards); 

    rList.setHasFixedSize(true); 
    LinearLayoutManager layoutManager = new LinearLayoutManager(getContext()); 
    layoutManager.setOrientation(LinearLayoutManager.VERTICAL); 
    rList.setLayoutManager(layoutManager); 
} 

@Override 
public void onDetach() { 
    super.onDetach(); 
    if(mAdapter != null) 
    { 
     mAdapter = null; 
    } 

    if(rList.getAdapter() != null) 
    { 
     rList.setAdapter(null); 
    } 

    if(listRequest != null) { 
     listRequest.getCall().cancel(); 
    } 
} 

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 

    homeLatitude = ChimeApplication.user.latitude; 
    homeLongitude = ChimeApplication.user.longitude; 

    startIndeterminateProgress(); 
    currentLocation = new Location(""); 
    currentLocation.setLatitude(homeLatitude); 
    currentLocation.setLongitude(homeLongitude); 
    awaitingHomeCoordinates = false; 

    mAdapter = new RewardsRVArrayAdapter(new ArrayList<MerchantListItem>()); 
    rList.setAdapter(mAdapter); 

} 

@Override 
public void onResume() { 
    super.onResume(); 
    getRewards(); 
} 

private void refreshOffers() { 
     startIndeterminateProgress(); 
     final int first_row = 0; 
     final int num_rows = LIMIT; 
     listRequest = new MerchantListRequest(parentActivity, currentLocation.getLatitude(), currentLocation.getLongitude(), first_row, num_rows); 
     listRequest.execute(new MerchantListRequestListener(getContext())); 
} 

@Override 
public void onRefresh() { 
    refreshOffersListFragment = true; 
    refreshOffers(); 
} 

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    inflater.inflate(R.menu.offers_list_menu, menu); 
} 


@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    if (item.getItemId() == R.id.refresh) { 
     refreshOffersListFragment = true; 
     refreshOffers(); 
     return true; 
    } 

    return false; 
} 

@Override 
public void onPause() { 
    super.onPause(); 

    if (locationClient != null && locationClient.isConnected()) { 
     locationClient.disconnect(); 
    } 
} 

private void showList() { 
    noRewards.setVisibility(View.GONE); 
    rList.setVisibility(View.VISIBLE); 
} 

private void hideList() { 
    noRewards.setVisibility(View.VISIBLE); 
    rList.setVisibility(View.GONE); 
} 

private void setMerchantsList(ArrayList<MerchantListItem> results) { 

    if (nMerchantList != null && nMerchantList.size() > 0) { 
     nMerchantList.clear(); 
    } 

    for (MerchantListItem item : results) { 
     nMerchantList.add(item); 
    } 

    if (mAdapter == null) { 
     mAdapter = new RewardsRVArrayAdapter(nMerchantList); 
     rList.setAdapter(null); 
     rList.setAdapter(mAdapter); 
    } else { 
     mAdapter.addAll(nMerchantList); 
     rList.postInvalidate(); 
    } 
} 

private class MerchantListRequestListener extends BaseRetrofitRequestListener<MerchantListResult> { 

    public MerchantListRequestListener(Context context) { 
     super(context); 
    } 

    @Override 
    public void onRequestFailed(int code, String errorMessage) { 
     android.util.Log.e("RECYCLERVIEW", "FAIL request"); 
     stopIndeterminateProgress(); 
     dialogCheck(); 
     if (errorMessage != null && !errorMessage.isEmpty() && isVisible()) { 
      Toast.makeText(context, errorMessage, Toast.LENGTH_LONG).show(); 
      hideList(); 
     } 
    } 

    @Override 
    public void onRequestSuccessful(Response<MerchantListResult> response) { 
     dialogCheck(); 
     stopIndeterminateProgress(); 
     if (response != null && response.body().results != null) { 
      showList(); 

      setMerchantsList(response.body().results); 


     } else { 
      hideList(); 
     } 
    } 

    private void dialogCheck() { 
     if (!Utils.isHighAccuracySet(parentActivity) && ContextCompat.checkSelfPermission(parentActivity, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && 
       ContextCompat.checkSelfPermission(parentActivity, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { 
      displayGPSOffDialog(); 
     } 
    } 
} 

private void getRewards() { 
    if (ContextCompat.checkSelfPermission(parentActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
     if (!(RewardsListFragment.this).shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) { 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
       awaitingPermission = true; 
       (RewardsListFragment.this).requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, 
           Manifest.permission.ACCESS_COARSE_LOCATION}, 
         PermConst.REWARDS_LOCATION_PERMISSION_REQUESTED); 
      } 
     } else { 
      displayPermissionDeniedDialog(); 
      final int first_row = 0; 
      final int num_rows = LIMIT; 

      listRequest = new MerchantListRequest(parentActivity, currentLocation.getLatitude(), currentLocation.getLongitude(), first_row, num_rows); 
      listRequest.execute(new MerchantListRequestListener(parentActivity)); 
      awaitingPermission = false; 
     } 

    } else { 
     if (locationClient != null && !locationClient.isConnected() && Utils.isHighAccuracySet(parentActivity)) { 
      // Turn off no offers and gps disabled screens only if the no offers screen is not currently displayed. 
      locationClient.connect(); 
     } else { 
      if (locationClient == null && Utils.isHighAccuracySet(parentActivity)) { 
       refreshOffersListFragment = true; 
       locationClient = new GoogleApiClient.Builder(parentActivity.getApplicationContext()) 
         .addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build(); 
       locationClient.connect(); 
      } else { 
       final int first_row = 0; 
       final int num_rows = LIMIT; 

       listRequest = new MerchantListRequest(parentActivity, currentLocation.getLatitude(), currentLocation.getLongitude(), first_row, num_rows); 
       listRequest.execute(new MerchantListRequestListener(parentActivity)); 
       if (!Utils.isHighAccuracySet(parentActivity)) { 
        gpsOffScreenDisplayed = true; 
       } 
      } 
     } 
     awaitingPermission = false; 
    } 

    mPullToRefreshLayout.setEnabled(true); 

} 

最後,這是我的適配器:

public class RewardsRVArrayAdapter extends RecyclerView.Adapter<RewardsRVArrayAdapter.ViewHolder> { 

private List<MerchantListItem> results; 
private final int sdkVersion; 
private Bitmap defaultImage; 
private final DecimalFormat dollarFormatter = new DecimalFormat("$##.##"); 

private int lastAnimatedPosition = -1; 

public RewardsRVArrayAdapter(List<MerchantListItem> results) { 
    this.results = results; 
    sdkVersion = Utils.getSDKVersion(); 
    setHasStableIds(false); 
} 

@Override 
public RewardsRVArrayAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    // create a new view 
    defaultImage = BitmapFactory.decodeResource(parent.getContext().getResources(), R.drawable.big_text); 
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rewards_list_item, parent, false); 
    // set the view's size, margins, paddings and layout parameters 
    return new ViewHolder(v); 
} 

@Override 
public void onViewAttachedToWindow(ViewHolder holder) { 
    super.onViewAttachedToWindow(holder); 
} 

@Override 
public void onViewDetachedFromWindow(ViewHolder holder) { 
    super.onViewDetachedFromWindow(holder); 
} 

@Override 
public void onBindViewHolder(ViewHolder holder, int position) { 
    MerchantListItem offerItem = results.get(position); 
    Deal deal = offerItem.deal != null ? offerItem.deal : null; 

    if (offerItem.type.equalsIgnoreCase(Const.MERCHANT_MERCHANT_STRING)) { 
     setMerchant(holder, offerItem, deal); 
    } else if (offerItem.type.equalsIgnoreCase(Const.MERCHANT_REWARD_STRING)) { 

     setCategoryReward(holder, deal); 
    } 

    //Set up the banner 
    if (offerItem.banner != null && offerItem.banner.text != null && !offerItem.banner.text.isEmpty()) { 
     holder.banner.setVisibility(View.VISIBLE); 
     holder.banner.setText(offerItem.banner.text); 

     //Set color of banner based on type 
     if (offerItem.banner.type.equalsIgnoreCase(Banner.TYPE_FEATURED)) { 
      holder.banner.setBackgroundResource(R.drawable.yellow_banner); 
      holder.banner.setTextColorRes(R.color.text); 
     } else if (offerItem.banner.type.equalsIgnoreCase(Banner.TYPE_PERSONALIZED)) { 
      holder.banner.setBackgroundResource(R.drawable.blue_banner); 
      holder.banner.setTextColorRes(android.R.color.white); 
     } else if (offerItem.banner.type.equalsIgnoreCase(Banner.TYPE_LIMITED)) { 
      holder.banner.setBackgroundResource(R.drawable.orange_banner); 
      holder.banner.setTextColorRes(android.R.color.white); 
     } 

     //For some reason padding did not work in XML so I moved it here 
     holder.banner.setPadding(Utils.convertDpToPixel(10, holder.banner.getContext()), Utils.convertDpToPixel(3, holder.banner.getContext()), 
       Utils.convertDpToPixel(10, holder.banner.getContext()), Utils.convertDpToPixel(3, holder.banner.getContext())); 
    } else { 
     holder.banner.setVisibility(View.GONE); 
    } 
} 

@Override 
public int getItemCount() { 
    return results != null ? results.size() : 0; 
} 

public MerchantListItem getItemAtPosition(int position) 
{ 
    return results.get(position); 
} 

public void addAll(ArrayList<MerchantListItem> newResults) 
{ 
    this.results.clear(); 
    for(MerchantListItem item : newResults) 
    { 
     this.results.add(item); 
    } 
    dataSetChanged(); 
} 

@UiThread 
protected void dataSetChanged() { 
    notifyDataSetChanged(); 
} 

private void setMerchant(final ViewHolder viewHolder, final MerchantListItem offerItem, final Deal deal) { 
    loadCardImage(offerItem.image_url, viewHolder); 
    viewHolder.merchant_name_txt.setText(offerItem.name); 

    if (deal != null) { 
     viewHolder.merchant_offer_txt.setText(deal.name); 
     viewHolder.offer_amount.setText(dollarFormatter.format(deal.promotional_value)); 
    } 
} 

private void setCategoryReward(final ViewHolder viewHolder, Deal deal) { 
    if(deal != null) 
    { 
     loadCardImage(deal.category_reward.card_image_url, viewHolder); 
     viewHolder.merchant_name_txt.setText(deal.category_reward.card_title); 
     viewHolder.merchant_offer_txt.setText(deal.name); 
     viewHolder.offer_amount.setText(dollarFormatter.format(deal.promotional_value)); 
    } 
} 

private void loadCardImage(String url, final ViewHolder viewHolder) { 
    if (url != null && !url.isEmpty()) { 
     Picasso.with(viewHolder.main_layout.getContext()).load(url).memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE).fit().networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE, NetworkPolicy.OFFLINE).into(viewHolder.main_layout); 
    } else { 
     setDefaultImage(viewHolder.main_layout); 
    } 

} 

@SuppressWarnings("deprecation") 
@SuppressLint("NewApi") 
private void setBackgroundImage(View view, Drawable drawable) { 
    //FIXME we can remove this because we don't support any below to API 16 (JELLY BEAN) 
    if (sdkVersion < android.os.Build.VERSION_CODES.JELLY_BEAN) { 
     view.setBackgroundDrawable(drawable); 
    } else { 
     view.setBackground(drawable); 
    } 
} 

public static class ViewHolder extends RecyclerView.ViewHolder { 
    // each data item is just a string in this case 
    ButtonTextView banner; 
    ButtonTextView merchant_name_txt; 
    HeaderTextView merchant_offer_txt; 
    ImageView main_layout; 
    ButtonTextView offer_amount; 
    public ViewHolder(View v) { 
     super(v); 
     banner = (ButtonTextView) v.findViewById(R.id.banner); 
     merchant_name_txt = (ButtonTextView) v.findViewById(R.id.merchant_name_txt); 
     merchant_offer_txt = (HeaderTextView) v.findViewById(R.id.merchant_reward_txt); 
     main_layout = (ImageView) v.findViewById(R.id.image_layout); 
     offer_amount = (ButtonTextView) v.findViewById(R.id.reward_amount); 
    } 
} 

}

奇怪的是,這是發生在Android M和N,但現在正在發生的事情在Android L,我以前閱讀與RecyclerView一些問題支持庫但我可以」找到解決方案。

連接一個GIF的檢查有什麼行爲 Gif bug RecyclerView

回答

0

加入onCreateView的代碼RewardsListFragment

mAdapter = new RewardsRVArrayAdapter(new ArrayList<MerchantListItem>()); 
rList.setAdapter(mAdapter); 
+0

不,這仍然沒有工作,出於某種原因,當我出去的片段和回報,RecyclerView有參考最後一個適配器,如果我嘗試把null,這不做任何改變 – DiegoF

+0

然後你試着也嘗試onresume – sasikumar

1

因爲我不能直接檢查,因爲你的項目有很多依賴,我以下建議您記錄方法的每個部分。

我想你的getRewards()方法有一些錯誤。 如果你的刷新方法工作得很好,你可以使用

private boolean firstTime = true; 

@Override 
public void onResume() { 
    super.onResume(); 
    if(firstTime){ 
     getRewards(); 
     firstTime = false;  
    } 
    else{ 
     onRefresh(); 
    } 
} 

代替

+0

我檢查了每個方法,並且getRewards()工作正常,只是檢查locationClient是否爲空或連接。 – DiegoF

+0

我會投你的答案,有一段時間是有幫助的,但這不能解決問題,因爲我要求的許可,並重拍我的getRewards方法,我解決了問題。 – DiegoF

+0

@DiegoF謝謝你,正如我之前提到的這個答案只是一個解決方法,如果你的刷新方法工作正常。我不能用你的代碼複製這個問題,因爲你的項目有許多依賴關係,只是包含有限的代碼 – HendraWD

相關問題