2016-09-01 2 views
0

편집는 메인 스레드

메인 문제는 내가 eventbus 연 조각이었다에 너무 많은 일을 320 개 프레임을 건너 뛰었습니다. 나는 그 문제를 일으킨 지연을 소개했다. 어쨌든 도움을 주셔서 감사합니다. 메인 포스트

는 또 다른 프레임의 질문을 건너 뜁니다. 그래서 나는 여기에 다음 줄을 발생 특히 문제가에서 발생하는 경우,

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

나는 이해할 수 없었다 내 코드

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; 
    } 


} 

I 프레임을 경험하고 건너 뜁니다입니다. 하지만 일단 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 Fragment)에 보관 된 ViewPager 안에 있습니다. 구독자가 UI를 바꿉니다. 조각 –

답변

0

하나의 명백한 실수 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() (예 : 어댑터의 생성자) :

당신은 쉽게 예를 들어, 버튼 타입 당 하나의 리스너를 인스턴스화하여이 문제를 해결할 수

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

OnClickListeners을 재사용하면 많은 CPU 시간과 메모리를 절약 할 수 있습니다. 인스턴스화는 그다지 비싸지는 않지만 많은 메모리를 확보하고 더 이상 사용되지 않는 리소스를 해제하기 위해 항상 Garbage Collector을 작동하게 만듭니다.

의견에 @abbath가 언급 한 내용도 문제가 될 수 있습니다.

1

onBind에서 리스너를 할당하지 마십시오. 나는 당신이 recycleview의 요점을 오해한다고 생각합니다. 이것은 당신이 그것을 할 방법입니다 :

보기를 초기화 전망을 찾아 리스너를 추가해야 onCreateViewHolder
  • onBind

을 발사 할 때 그 청취자가 적절한 데이터를 그래서 ViewHolder 데이터를 업데이트하면 onBind에 가능한 한 적은 코드가 있는지 확인하고 싶습니다. 특히 스크롤하는 동안 많이 호출되기 때문입니다.

예를 들어 피카소와 같은 코드 초기화를 어댑터 생성자에서 한 번 수행하지 마십시오.

여러보기 유형을 사용하여 동적 변경을 처리하지 않아도됩니다.

+0

코드를 약간 최적화했습니다. –