2016-09-01 5 views
0

編集は、そのメインスレッド

主な問題は、私はeventbusで開かれたフラグメントにした上であまりやって320個のフレームをスキップ。私はその問題を引き起こした遅れを導入しました。とにかく助けてくれてありがとう。

メインポスト

さらに別のフレーム質問をスキップ。だからここに私はフレームを経験しています私のコード

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

    private Context context; 
    private List<Item> productList; 
    private Table<String,Integer,Item> cartTable = HashBasedTable.create(); 
    private OnItemChanged itemChangedListener; 
    private ViewHolder viewHolder; 
    private Picasso picasso; 
    public ProductDisplayAdapter(Context mContext, List<Item> items) 
    { 
     this.context = mContext; 
     this.productList = items; 
     this.picasso = Picasso.with(context); 
     this.picasso.setIndicatorsEnabled(true); 
    } 

    private Item getItem(int position) { 
     return new Item(productList.get(position)); 
    } 

    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 

     View view = LayoutInflater.from(context).inflate(R.layout.list_product,parent,false); 
     this.viewHolder = new ViewHolder(view); 
     viewHolder.cartAdd.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       viewHolder.numberButton.setNumber("1"); 
       viewHolder.viewSwitcher.showNext(); 
       if(itemChangedListener != null) 
       { 
        int position = viewHolder.getAdapterPosition(); 
        Item product = productList.get(position); 
        product.setTotalQuantity(1); 
        notifyItemChanged(viewHolder.getAdapterPosition()); 
        productList.set(position, product); 
        cartTable.put(product.getId(), product.getMetricPosition(), product); 
        itemChangedListener.onItemAdded(cartTable, 1); 
       } 
      } 
     }); 
     viewHolder.numberButton.setOnValueChangeListener(new ElegantNumberButton.OnValueChangeListener() { 
      @Override 
      public void onValueChange(ElegantNumberButton view, int oldValue, int newValue) { 
       if(itemChangedListener != null) 
       { 
        int position = viewHolder.getAdapterPosition(); 
        Item product = productList.get(position); 
        product.setTotalQuantity(newValue); 
        notifyItemChanged(viewHolder.getAdapterPosition()); 
        productList.set(position, product); 
        cartTable.put(product.getId(), product.getMetricPosition(), product); 
        itemChangedListener.onItemAdded(cartTable, newValue-oldValue); 

       } 
      } 
     }); 
     viewHolder.clickView.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       EventBus.getDefault().post(productList.get(viewHolder.getAdapterPosition())); 
      } 
     }); 
     return this.viewHolder; 
    } 

    @Override 
    public void onBindViewHolder(ViewHolder mViewHolder, int position) { 
     Item product = getItem(position); 
     picasso.load(product.getImageUrl()).fit().into(viewHolder.productImage); 
     String price = CurrencyUtils.getCurrencySymbol(product.getCurrency()) + product.getPrice().get(product.getMetricPosition()); 
     viewHolder.productPrice.setText(price); 
     viewHolder.productName.setText(product.getName()); 
     viewHolder.productQuantity.setText(product.getQuantity().get(product.getMetricPosition())); 
     viewHolder.productQuantity.setTypeface(FontUtils.getRegularTypeFace()); 
     viewHolder.productQuantity.setOnClickListener(dialogClickListener); 
     if(product.getTotalQuantity() > 0) 
     { 
      viewHolder.viewSwitcher.setDisplayedChild(1); 
      viewHolder.numberButton.setNumber(String.valueOf(product.getTotalQuantity()),false); 
     } 
     else if(product.getStock() > 0) 
     { 
      viewHolder.viewSwitcher.setDisplayedChild(0); 
      viewHolder.cartAdd.setBackgroundColor(Color.WHITE); 
      viewHolder.cartAdd.setTag(false); 
      viewHolder.cartAdd.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_cart_add)); 
     } 
     else { 
      viewHolder.viewSwitcher.setDisplayedChild(0); 
      viewHolder.cartAdd.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_cart_soldout)); 
     } 

     removeButtonShadow(viewHolder.productQuantity); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public int getItemCount() { 
     return productList.size(); 
    } 

    public static class ViewHolder extends RecyclerView.ViewHolder{ 

     ImageView productImage,cartAdd; 
     TextView productName; 
     TextView productPrice; 
     Button productQuantity; 
     ElegantNumberButton numberButton; 
     ViewSwitcher viewSwitcher; 
     View clickView; 
     public ViewHolder(View itemView) { 
      super(itemView); 
      this.clickView = itemView; 
      productImage = (ImageView) itemView.findViewById(R.id.product_image); 
      productName = (TextView) itemView.findViewById(R.id.product_name); 
      productPrice = (TextView) itemView.findViewById(R.id.product_price); 
      productQuantity = (Button) itemView.findViewById(R.id.product_quantity); 
      cartAdd = (ImageView) itemView.findViewById(R.id.cart_add); 
      numberButton = (ElegantNumberButton) itemView.findViewById(R.id.number_button); 
      viewSwitcher = (ViewSwitcher) itemView.findViewById(R.id.view_switcher); 
     } 

    } 

    private View.OnClickListener dialogClickListener = new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      FragmentTransaction fragmentTransaction = ((Activity) context).getFragmentManager().beginTransaction(); 
      Fragment previousDialog = ((Activity) context).getFragmentManager().findFragmentByTag(StringConstants.DIALOG_TAG); 
      if(previousDialog != null) 
      { 
       fragmentTransaction.remove(previousDialog); 
      } 
      fragmentTransaction.addToBackStack(null); 
      QuantityDialogFragment mFragment = QuantityDialogFragment.newInstance(getItem(viewHolder.getAdapterPosition()),getItem(viewHolder.getAdapterPosition()).getMetricPosition()); 
      mFragment.setQuantityListener(new OnQuantityChosen() { 
       @Override 
       public void onSelectQuantity(int position) { 
        Item item = getItem(viewHolder.getAdapterPosition()); 
        item.setMetricPosition(position); 
        item.setTotalQuantity(0); 
        productList.set(viewHolder.getAdapterPosition(),item); 
        notifyItemChanged(viewHolder.getAdapterPosition()); 
       } 
      }); 
      mFragment.show(fragmentTransaction,StringConstants.DIALOG_TAG); 
     } 
    }; 

    private void removeButtonShadow(Button button) 
    { 
     if(Build.VERSION.SDK_INT >= 21) 
      button.setStateListAnimator(null); 
    } 

    public void setOnItemChangedListener(OnItemChanged onItemChangedListener) 
    { 
     this.itemChangedListener = onItemChangedListener; 
    } 


} 

である私は次の行に遭遇したときに問題が発生するから、どこで見つけ出すことができませんでした

viewHolder.clickView.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       EventBus.getDefault().post(product); 
      } 
     }); 

、特にスキップします。しかし、一度recyclerview Itemをクリックすると、トレースに300以上のフレームスキップを投げているコンパイラで、目に見えて重要なフレームキックが発生しています。誰もそれを絞り込み、いくつかの変更を提案できますか?

編集

は、ここに私のEventbus加入者です。あなたが作っている

@Subscribe(threadMode = ThreadMode.BACKGROUND) 
    public void onProductClicked(Item product) 
    { 
     Fragment fragment = ProductLandingFragment.newInstance(product); 
     FragmentManager fragmentManager = getFragmentManager(); 
     FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
//  fragmentTransaction.hide(fragmentManager.findFragmentByTag(StringConstants.FRAGMENT_CATEGORIES_TAG)); 
     fragmentTransaction.replace(R.id.fragmentholder,fragment,StringConstants.FRAGMENT_PRODUCT_TAG); 
     fragmentTransaction.addToBackStack(null); 
     fragmentTransaction.commit(); 
    } 
+0

ああ、あまりにも大きなメソッドの恐怖! – abbath

+0

Eventbusの加入者は何をしていますか?トラブルはそこになければならないと思います。 – abbath

+0

サブスクライバはフラグメントを変更します。 RecycleViewは、フラグメント(UIフラグメント)に保持されているViewPagerの内部にあります。加入者はただUIを置き換えます。フラグメント –

答えて

0

1つの明らかなミスがonBindViewHolder()コールバックで(一般的に、またはオブジェクト)多くのOnClickListenersにインスタンス化されます。 onBindViewHolder()で、

View.OnClickListener productListener = new View.OnClickListener() { 
    @Override 
    public void onClick(View view) { 
     Product product = adapter.items.get((int) view.getTag)); // get item for position 
     EventBus.getDefault().post(product); 
    } 
} 

その後:

置き、それ外onBindViewHolder()(例えばアダプタのコンストラクタ):

あなたは簡単に、たとえば、ボタンの種類ごとに1人のだけのリスナーをインスタンス化することによってこの問題を解決することができます

... 
viewHolder.clickView.setOnClickListener(productListener); 
viewHolder.setTag(position); 

OnClickListenersを再利用することで、多くのCPU時間とメモリを節約できます。インスタンシエートはそれほど高価ではありませんが、多くのメモリを解放して、Garbage Collectorは、もはや使用されなくなったリソースを解放するよう常に働きます。

@abbathがコメントで述べたことも問題になる可能性があります。

1

onBindにリスナーを割り当てないでください。私はあなたがリサイクルの見解を誤解していると思います。これは、あなたがそれを行うべきかです:

、ビューを初期化するビューを見つけて、リスナーを追加する必要がありますonCreateViewHolder
  • [OnBind]の

を焼成したとき、それらのリスナーが適切なデータを持っているので、ViewHolderデータを更新する必要がありますonBindのコードができるだけ少ないことを確認したい、特にスクロール時にたくさん呼び出されるようにしたい。

たとえば、コード初期化(つまりピカソ)は一切行わず、アダプターコンストラクターで一度だけ行います。

複数のビュータイプを使用すると、動的な変更に対処する必要はありません。

+0

コードを少し最適化しました。 –

関連する問題