0

我有一個viewpager與其每個包含recyclerview的片段。然而,當viewpager片段被創建並且recyclerview滾動滯後時,點擊響應需要一段時間。 我在getItemPosition方法中返回POSITION_NONE,以便在用戶更改文本大小/樣式時重新創建碎片。Android viewpager與recyclerview片段laggs(低性能)

  1. 問題1:Viewpager片段的創建和修光滯後
  2. 問題2:RecyclerView滾動也滯後
  3. 問題3.上述兩個問題是具有低RAM 設備更加嚴重,然而具有高RAM/CPU核心設備,其響應可以接受但不符合標準。

這裏是我的代碼: ViewPagerAdapter:

private class ViewPagerAdapter extends FragmentStatePagerAdapter { 

     public ViewPagerAdapter(FragmentManager fm) { 
      super(fm); 
     } 

     @Override 
     public Fragment getItem(int position) { 

      subTitlesFragment = new SubTitlesFragment(); 
      Bundle bundle = new Bundle(); 
      if (isRtl) { 
       int positionRev; 
       positionRev = position - (subTitlesList.size() - 1); 
       bundle.putInt("view_pager_pos", Math.abs(positionRev)); 
      } else { 
       bundle.putInt("view_pager_pos", position); 
      } 
      bundle.putString("type", type); 
      bundle.putString("query", query); 
      subTitlesFragment.setArguments(bundle); 
      return subTitlesFragment; 
     } 

     @Override 
     public int getItemPosition(Object object) { 
      return POSITION_NONE; 
     } 

     @Override 
     public int getCount() { 
      return subTitlesList.size(); 
     } 

    } 

MyRecyclerViewAdapter:

public RecyclerAdapterDetails(Context context, ArrayList<DataView> data, String query, String fav, String language, 
            Typeface typefaceAR, Typeface typefaceTran, 
            String textFontSize, String textFontSizeTran, 
            boolean diacriticsON) { 

     sharedPref = context.getSharedPreferences("sPreferencesFile", Context.MODE_PRIVATE); 
     inflater = LayoutInflater.from(context); 
     this.dataViews = data; 
     this.context = context; 
     this.query = query; 
     this.fav = fav; 
     this.language = language; 
     this.typefaceAR = typefaceAR; 
     this.typefaceTran = typefaceTran; 
     this.textFontSize = textFontSize; 
     this.textFontSizeTran = textFontSizeTran; 
     this.diacriticsON = diacriticsON; 
     currentNightMode = context.getResources().getConfiguration().uiMode 
       & Configuration.UI_MODE_NIGHT_MASK; 
    } 

    @Override 
    public int getItemViewType(int position) { 
     int viewType = 0; 
     if (position == 0 && fav == null) { 
      viewType = 1; 
     } 
     if (position == dataViews.size()) { 
      viewType = 2; 
     } 
     return viewType; 
    } 

    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view; 

     if (viewType == 0) { 
      view = inflater.inflate(R.layout.single_item_recycler_details, parent, false); 
      return new MyViewHolder(view); 
     } else if (viewType == 1) { 
      view = inflater.inflate(R.layout.single_item_title_details, parent, false); 
      return new TitleViewHolder(view); 
     } else { 
      view = inflater.inflate(R.layout.blank_item, parent, false); 
      return new BlankItemViewHolder(view); 
     } 
    } 

    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 

     if (holder.getItemViewType() == 0) { 
      processMyViewHolder(holder, position); 
     } else if (holder.getItemViewType() == 1) { 
      TitleViewHolder titleViewHolder = (TitleViewHolder) holder; 

      if (language.equals("en")) { 
       titleViewHolder.duaTitle.setText(dataViews.get(1).getSubTitleEN()); 
        titleViewHolder.duaTitle.setText(dataViews.get(1).getTranslation_Sub()); 
      } else { 
       titleViewHolder.duaTitle.setText(dataViews.get(1).getSubTitleAR()); 
titleViewHolder.duaTitle.setText(dataViews.get(1).getSub_title()); 
      } 

      if (language.equals("ar")) { 
        titleViewHolder.duaTitle.setTypeface(typefaceAR); 
      } else { 

        titleViewHolder.duaTitle.setTypeface(typefaceTran); 
      } 

      if (language.equals("ar")) { 
       titleViewHolder.duaTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, Float.parseFloat(textFontSize)); 
      } else { 
       titleViewHolder.duaTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, Float.parseFloat(textFontSizeTran)); 
      } 
      if (query != null) { 
       String title = titleViewHolder.duaTitle.getText().toString().toLowerCase(); 
       int ofe3 = title.indexOf(query.toLowerCase(), 0); 
       Spannable spannable3 = new SpannableString(titleViewHolder.duaTitle.getText()); 

       for (int ofs = 0; ofs < title.length() && ofe3 != -1; ofs = ofe3 + 1) { 
        ofe3 = title.indexOf(query, ofs); 
        if (ofe3 == -1) 
         break; 
        else { 
         if (currentNightMode == Configuration.UI_MODE_NIGHT_NO) { 
          spannable3.setSpan(new BackgroundColorSpan(0xFFFFFF00), ofe3, ofe3 + query.length(), 
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
         } else { 
          spannable3.setSpan(new BackgroundColorSpan(0xffcccccc), ofe3, ofe3 + query.length(), 
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
         } 
         titleViewHolder.duaTitle.setText(spannable3, TextView.BufferType.SPANNABLE); 
        } 
       } 
      } 

     } else { 
      Log.w(TAG, "BlankItemViewHolder called..."); 
      BlankItemViewHolder blankItemViewHolder = (BlankItemViewHolder) holder; 
      if (language.equals("ar")) { 
       try { 
        blankItemViewHolder.footnote.setText(dataViews.get(1).getFootnoteAR()); 
       } catch (Exception e) { 

       } 
      } else { 
       try { 
        blankItemViewHolder.footnote.setText(dataViews.get(1).getFootnoteEN()); 
       } catch (Exception e) { 

       } 
      } 
     } 
    } 

    public void processMyViewHolder(RecyclerView.ViewHolder viewHolder, int position) { 

     MyViewHolder holder = (MyViewHolder) viewHolder; 
     if (currentNightMode == Configuration.UI_MODE_NIGHT_NO) { 
      holder.cardView.setCardBackgroundColor(Color.WHITE); 
     } 
     DataView current = dataViews.get(position); 
      holder.contentsAr.setTypeface(typefaceAR); 

     if (diacriticsON) { 
      holder.contentsAr.setText(current.getContentsAR().trim()); 
     } else { 
      Matcher matcher = pattern.matcher(current.getContentsAR().trim()); 
      matcher.reset(); 
      String contentsDiaRemoved = matcher.replaceAll(""); 
      holder.contentsAr.setText(contentsDiaRemoved); 
     } 

     if (language.equals("ar")) { 
      holder.contentsTran.setVisibility(View.GONE); 
      if (current.getDaleelAR().trim().length() > 0) { 
       holder.divider.setVisibility(View.VISIBLE); 
       holder.daleel.setVisibility(View.VISIBLE); 
       if (diacriticsON) { 
        holder.daleel.setText(current.getDaleelAR().trim()); 
       } else { 
        if (language.equals("ar")) { 
         holder.contentsTran.setVisibility(View.GONE); 
        } else { 
         if (current.getContentsEN() != null && !current.getContentsEN().trim().isEmpty()) { 
          holder.contentsTran.setText(current.getContentsEN().trim()); 
         } else { 
          holder.contentsTran.setVisibility(View.GONE); 
         } 
        } 

        Matcher matcher = pattern.matcher(current.getDaleelAR().trim()); 
        matcher.reset(); 
        String daleelText = matcher.replaceAll(""); 
        holder.daleel.setText(daleelText); 
       } 
      } else { 
       holder.divider.setVisibility(View.GONE); 
       holder.daleel.setVisibility(View.GONE); 
      } 
     } else { 
      if (current.getContentsEN() != null && !current.getContentsEN().trim().isEmpty()) { 
       holder.contentsTran.setText(current.getContentsEN().trim()); 
      } else { 
       holder.contentsTran.setVisibility(View.GONE); 
      } 
      if (current.getDaleelEN() != null && !current.getDaleelEN().trim().isEmpty()) { 
       holder.daleel.setText(current.getDaleelEN().trim()); 
      } else { 
       if (current.getDaleelAR().trim().length() > 0) { 
        holder.divider.setVisibility(View.VISIBLE); 
        holder.daleel.setVisibility(View.VISIBLE); 
        holder.daleel.setText(current.getDaleelAR().trim()); 
       } else { 
        holder.divider.setVisibility(View.GONE); 
        holder.daleel.setVisibility(View.GONE); 
       } 
      } 
     } 

     if (language.equals("ar")) { 
      holder.contentsTran.setVisibility(View.GONE); 
      holder.daleel.setTypeface(typefaceAR); 
     } else { 
       holder.contentsTran.setTypeface(typefaceTran); 
       holder.daleel.setTypeface(typefaceTran); 
     } 

     holder.contentsAr.setTextSize(TypedValue.COMPLEX_UNIT_SP, Float.parseFloat(textFontSize)); 

     if (language.equals("ar")) { 
      float newSize = Float.parseFloat(textFontSize) - 2; 
      holder.daleel.setTextSize(TypedValue.COMPLEX_UNIT_SP, newSize); 
     } else { 
      holder.contentsTran.setTextSize(TypedValue.COMPLEX_UNIT_SP, Float.parseFloat(textFontSizeTran)); 
      holder.daleel.setTextSize(TypedValue.COMPLEX_UNIT_SP, Float.parseFloat(textFontSizeTran)); 
     } 

     if (query != null) { 
      String daleel = holder.daleel.getText().toString().toLowerCase(); 
      int ofe = daleel.indexOf(query.toLowerCase(), 0); 
      Spannable spannable = new SpannableString(holder.daleel.getText()); 

      for (int ofs = 0; ofs < daleel.length() && ofe != -1; ofs = ofe + 1) { 
       ofe = daleel.indexOf(query, ofs); 
       if (ofe == -1) 
        break; 
       else { 
        if (currentNightMode == Configuration.UI_MODE_NIGHT_NO) { 
         spannable.setSpan(new BackgroundColorSpan(0xFFFFFF00), ofe, ofe + query.length(), 
           Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
        } else { 
         spannable.setSpan(new BackgroundColorSpan(0xffcccccc), ofe, ofe + query.length(), 
           Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
        } 
        holder.daleel.setText(spannable, TextView.BufferType.SPANNABLE); 
       } 
      } 

      String contents = holder.contentsAr.getText().toString().toLowerCase(); 
      int ofe2 = contents.indexOf(query.toLowerCase(), 0); 
      Spannable spannable2 = new SpannableString(holder.contentsAr.getText()); 

      for (int ofs = 0; ofs < contents.length() && ofe2 != -1; ofs = ofe2 + 1) { 
       ofe2 = contents.indexOf(query, ofs); 
       if (ofe2 == -1) 
        break; 
       else { 
        if (currentNightMode == Configuration.UI_MODE_NIGHT_NO) { 
         spannable2.setSpan(new BackgroundColorSpan(0xFFFFFF00), ofe2, ofe2 + query.length(), 
           Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
        } else { 
         spannable2.setSpan(new BackgroundColorSpan(0xffcccccc), ofe2, ofe2 + query.length(), 
           Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
        } 
        holder.contentsAr.setText(spannable2, TextView.BufferType.SPANNABLE); 
       } 
      } 
     } 

     if (sharedPref.getBoolean("bookmark" + dataViews.get(position).getHadithNo(), false)) { 
      holder.bookmark.setImageResource(R.drawable.ic_bookmark_grey_600_24dp); 
     } else { 
      holder.bookmark.setImageResource(R.drawable.ic_bookmark_border_grey_600_24dp); 
     } 

    }  

    @Override 
    public int getItemCount() { 
     return dataViews.size() + 1; 
    } 

    public void setClickListener(ClickListener clickListener) { 
     this.clickListener = clickListener; 
    } 

    public interface ClickListener { 
     void itemClicked(int position); 
    } 

    private class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { 

     TextView contentsAr, contentsTran; 
     TextView daleel; 
     ImageView bookmark, share; 
     View divider; 
     CardView cardView; 

     public MyViewHolder(View itemView) { 
      super(itemView); 
      contentsAr = (TextView) itemView.findViewById(R.id.contents_ar); 
      contentsTran = (TextView) itemView.findViewById(R.id.contents_tran); 
      daleel = (TextView) itemView.findViewById(R.id.daleel); 
      bookmark = (ImageView) itemView.findViewById(R.id.bookmark); 
      share = (ImageView) itemView.findViewById(R.id.share); 
      divider = itemView.findViewById(R.id.divider); 
      cardView = (CardView) itemView.findViewById(R.id.card_view1); 
      bookmark.setOnClickListener(this); 
      bookmark.setOnLongClickListener(this); 
      share.setOnClickListener(this); 
     } 

     @Override 
     public void onClick(View v) { 
      if (v.getId() == bookmark.getId()) { 
       if (fav == null) { 
        modifySharedPref(); 
       } 
       if (fav != null) { 
        Toast.makeText(context, R.string.long_press, Toast.LENGTH_SHORT).show(); 
       } 
      } 
      if (v.getId() == share.getId()) { 
       clickListener.itemClicked(getLayoutPosition()); 
      } 
     } 

     @Override 
     public boolean onLongClick(View v) { 
      if (fav != null) { 
       bookmark.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); 
       modifySharedPref(); 
       removeAt(getLayoutPosition()); 
      } 
      return true; 
     } 

     void modifySharedPref() { 
      SharedPreferences.Editor editor = sharedPref.edit(); 
      if (!sharedPref.getBoolean("bookmark" + dataViews.get(getLayoutPosition()).getHadithNo(), false)) { 
       bookmark.setImageResource(R.drawable.ic_bookmark_grey_600_24dp); 
       editor.putBoolean("bookmark" + dataViews.get(getLayoutPosition()).getHadithNo(), true); 
      } else { 
       bookmark.setImageResource(R.drawable.ic_bookmark_border_grey_600_24dp); 
       editor.putBoolean("bookmark" + dataViews.get(getLayoutPosition()).getHadithNo(), false); 
      } 
      editor.apply(); 
     } 
    } 

    private class TitleViewHolder extends RecyclerView.ViewHolder { 
     TextView duaTitle; 

     public TitleViewHolder(View itemView) { 
      super(itemView); 
      duaTitle = (TextView) itemView.findViewById(R.id.dua_title); 
     } 
    } 

    private class BlankItemViewHolder extends RecyclerView.ViewHolder { 
     LinearLayout blankItem; 
     TextView footnote; 

     public BlankItemViewHolder(View itemView) { 
      super(itemView); 
      blankItem = (LinearLayout) itemView.findViewById(R.id.blank_item); 
      footnote = (TextView) itemView.findViewById(R.id.foot_note); 
     } 
    } 

    void removeAt(int position) { 
     dataViews.remove(position); 
     notifyItemRemoved(position); 
     notifyItemRangeChanged(position, dataViews.size()); 
    } 

SubTitlesFragment:

public SubTitlesFragment() { 

    } 

    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
     this.context = context; 
    } 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

     View view = inflater.inflate(R.layout.fragment_pager, container, false); 
     recyclerView = (RecyclerView) view.findViewById(R.id.recycler_sub_titles); 

     return view; 
    } 

    @Override 
    public void onCreate(@Nullable Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Log.i(TAG, "onCreate - SubTitlesFragment"); 
    } 

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

     dataViewArrayList.clear(); 
     dataViewTempList.clear(); 
     config = getActivity().getResources().getConfiguration(); 
     sharedPref = getActivity().getSharedPreferences("sPreferencesFile", Context.MODE_PRIVATE); 
     Bundle extras = getArguments(); 
     if (extras != null) { 
      type = extras.getString("type"); 
      if (type != null) { 
       if (type.equals("activity_search")) { 
        query = extras.getString("query"); 
       } else { 
        query = null; 
       } 
      } else { 
       query = null; 
      } 
      position = extras.getInt("view_pager_pos"); 

      Type listOfObjects = new TypeToken<ArrayList<DataView>>() { 
      }.getType(); 
      Gson gson = new Gson(); 
      String json = sharedPref.getString("gson_dataViews", ""); 

      if (!json.equals("")) { 
       dataViewArrayList = gson.fromJson(json, listOfObjects); 
      } 

      Type listOfObjects2 = new TypeToken<ArrayList<SingleItemTitle>>() { 
      }.getType(); 
      Gson gson2 = new Gson(); 
      String json2 = sharedPref.getString("subTitlesList", ""); 

      if (!json2.equals("")) { 
       subTitlesList = gson2.fromJson(json2, listOfObjects2); 
      } 


      boolean groupEnd = false; 
      boolean fetched = false; 

      for (int i = 0; !groupEnd && i < dataViewArrayList.size(); i++) { 
       if (LocaleHelper.getLanguage(context).equals("ar")) { 
        if (dataViewArrayList.get(i).getSubTitleAR().equals(subTitlesList.get(position).duaSubTitleAR)) { 
         dataViewTempList.add(dataViewArrayList.get(i)); 
         fetched = true; 
        } else if (fetched) { 
         groupEnd = true; 
        } 
       } else { 
        if (dataViewArrayList.get(i).getSubTitleEN().equals(subTitlesList.get(position).duaSubTitleEN)) { 
         dataViewTempList.add(dataViewArrayList.get(i)); 
         fetched = true; 
        } else if (fetched) { 
         groupEnd = true; 
        } 
       } 
      } 

     } 

     if (savedInstanceState != null) { 
      notFirstTime = true; 
     } 
     setAdapterData(); 
    } 

    public void setAdapterData() { 

     dataViewEachItemList.clear(); 
     dataViewEachItemList.add(0, null); 

     for (int i = 0; i < dataViewTempList.size(); i++) { 
      dataViewEachItemList.add(i + 1, dataViewTempList.get(i)); 
     } 

     if (dataViewEachItemList.size() > 1) { 
      if (query != null && !notFirstTime) { 
       sharedPref.edit().putBoolean("diacritics_check", false).apply(); 
      } 
      adapterMain = new RecyclerAdapterDetails(getActivity(), dataViewEachItemList, query, 
        null, Locale.getDefault().getLanguage()); 
      adapterMain.setClickListener(this); 

      recyclerView.setAdapter(adapterMain); 
      recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 
     } 
    } 


    @Override 
    public void itemClicked(int position) { 
     String duaTitle; 
     if (LocaleHelper.getLanguage(context).equals("ar")) { 
      if (dataViewEachItemList.get(1).getSubTitleAR() != null) { 
       duaTitle = dataViewEachItemList.get(1).getSubTitleAR().trim(); 
      } else { 
       duaTitle = dataViewEachItemList.get(1).getMainTitleAR().trim(); 
      } 
     } else { 
      if (dataViewEachItemList.get(1).getSubTitleEN() != null) { 
       duaTitle = dataViewEachItemList.get(1).getSubTitleEN().trim(); 
      } else { 
       duaTitle = dataViewEachItemList.get(1).getMainTitleEN().trim(); 
      } 
     } 

     String duaShare; 
     if (LocaleHelper.getLanguage(context).equals("ar")) { 
      if (sharedPref.getBoolean("diacritics_check", true)) { 
       duaShare = getString(R.string.star_for_bold) + duaTitle + getString(R.string.star_for_bold) + 
         getString(R.string.two_line_breaks) + dataViewEachItemList.get(position).getContentsAR(); 
      } else { 
       duaShare = getString(R.string.star_for_bold) + duaTitle + getString(R.string.star_for_bold) + 
         getString(R.string.two_line_breaks) + dataViewEachItemList.get(position).getContentsAR(); 
      } 
     } else { 
      if (dataViewEachItemList.get(position).getContentsEN() != null && 
        !dataViewEachItemList.get(position).getContentsEN().trim().isEmpty()) { 
       duaShare = getString(R.string.star_for_bold) + duaTitle + getString(R.string.star_for_bold) + 
         getString(R.string.two_line_breaks) + dataViewEachItemList.get(position).getContentsEN(); 
      } else { 
       duaShare = getString(R.string.star_for_bold) + duaTitle + getString(R.string.star_for_bold) + 
         getString(R.string.two_line_breaks) + dataViewEachItemList.get(position).getContentsAR(); 
      } 
     } 
     shareIntent(duaTitle, duaShare); 
    } 

    private void shareIntent(String duaTitle, String s) { 
     Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); 
     sharingIntent.setType("text/plain"); 
     String subject = duaTitle + getString(R.string.one_space) + getString(R.string.from_app); 
     sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject); 
     sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, s); 
     sharingIntent.putExtra(android.content.Intent.EXTRA_TITLE, getResources().getString(R.string.app_name)); 
     startActivity(Intent.createChooser(sharingIntent, "Share via")); 
    } 

我研究什麼: 1. ViewPager PagerAdapter not updating the View 2. Update ViewPager dynamically?

但是我不能在提高性能的成功。請建議提高viewpager和recyclerview性能的方法。 謝謝。

回答

1

在你的大onBindViewHolder和proccessMyViewHolder方法中似乎出現這個問題。您應該避免執行任何繁重的操作,例如從共享首選項中讀取數據,並從該方法中的資產創建字體。將數據加載一次並根據需要使用會更好。

+0

感謝您的建議。我在回收站適配器中刪除了所有對共享首選項的不必要訪問以及從資產創建字體,但仍然沒有性能改進。滯後依然如此。請參閱我的更新代碼RecyclerAdapterDetails.java – Abdullah