2015-06-03 7 views
13

मैं रीसाइक्लर व्यू.एडाप्टर का उपयोग कर रहा हूं लेकिन मैं अपनी विधि onCreateViewHolder के काम के संबंध में थोड़ा उलझन में हूं।Android RecyclerView.Adapter onCreateViewHolder()

@Override 
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { 
    if(viewType==TYPE_ITEM) { 

     View mView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.inflate_common_item, viewGroup, false); 
     ViewHolder vh = new ViewHolder(mView); 
     return vh; 

    } else { 
     View mView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.inflate_uncommon_item, viewGroup, false); 
     ViewHolderFooter vh = new ViewHolderFooter(mView); 
     return vh; 

    } 
} 

तो बैठाना मैं अपने सूची में 10 आइटम नहीं हैं तो प्रत्येक आइटम के लिए इस विधि बुलाया जाएगा और हर बार एक नई ViewHolder यह करेंगे प्रत्येक दृश्य के लिए एक बार, लेकिन अब मेरे सवाल का जब है निश्चित रूप से बनाया जाएगा हम ListView और BaseAdapter का उपयोग कर रहे थे, हम टैग में ViewHolder स्टोर करते हैं और इसका उपयोग करते हैं। हम प्रत्येक आइटम के लिए ViewHolder नहीं बनाते हैं।

@Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
      MyViewHolder mViewHolder; 

      if(convertView == null) { 
        convertView = inflater.inflate(R.layout.layout_list_item, null); 
        mViewHolder = new MyViewHolder(); 
        convertView.setTag(mViewHolder); 
      } else { 
        mViewHolder = (MyViewHolder) convertView.getTag(); 
      } 

      mViewHolder.tvTitle = detail(convertView, R.id.tvTitle, myList.get(position).getTitle()); 
      mViewHolder.tvDesc = detail(convertView, R.id.tvDesc, myList.get(position).getDescription()); 
      mViewHolder.ivIcon = detail(convertView, R.id.ivIcon, myList.get(position).getImgResId()); 

      return convertView; 
    } 

तो क्या हम अतिरिक्त दर्शकधारक वस्तु नहीं बना रहे हैं। कृपया मुझे पेशेवरों और विपक्ष को समझने में मदद करें।

धन्यवाद

उत्तर

16

onCreateViewHolder केवल जब वहाँ कोई मौजूदा दृश्य धारकों जो RecyclerView पुनः उपयोग कर सकते हैं कोई नया दृश्य धारक पैदा करता है। इसलिए, उदाहरण के लिए, यदि आपका RecyclerView एक समय में 5 आइटम प्रदर्शित कर सकता है, तो यह 5-6 ViewHolders बनाएगा, और फिर onBindViewHolder पर कॉल करते समय स्वचालित रूप से उनका पुन: उपयोग करेगा।

क्या ListView में अपने कोड है करने के लिए अपने समान

(पता चल सके कि convertViewnull है, और यदि नहीं, टैग से मौजूदा ViewHolder हथियाने), को छोड़कर, RecyclerView साथ, यह सब स्वचालित रूप से किया है।

मुझे लगता है कि यह एक RecyclerView उपयोग करने के साथ पेशेवरों में से एक है - आप ViewHolders पुन: उपयोग के रूप में आप ListView के साथ क्या के बारे में इतनी चिंता की जरूरत नहीं है। कॉन है, RecyclerView बहुत अनुकूलन योग्य है, लेकिन कार्यक्षमता में बहुत कम बनाया गया है - ListView के विपरीत जो बहुत अनुकूल नहीं है, लेकिन कार्यक्षमता में बहुत अधिक बनाया गया है।

+0

तो इसका मतलब है कि यह प्रत्येक आइटम के लिए एक viewholder उत्पन्न करेंगे और फिर सूची के उस सेल के लिए हर बार उस धारक का उपयोग करें। सही? –

+0

धन्यवाद गिल, मेरे पास RecyclerView.Adapter में एक और सवाल है लेकिन इसके लिए मैं स्टैक ओवरफ़्लो पर एक अलग प्रश्न डालूंगा। –

+0

मैं कुछ दस्तावेज से गुज़र चुका हूं जो कि कर्टव्यूहोल्डर पर अमूर्त विधि के लिए उल्लिखित हैं। नया व्यूहोल्डर {@link #onBindViewHolder (ViewHolder, int)} का उपयोग करके एडाप्टर के आइटम प्रदर्शित करने के लिए उपयोग किया जाएगा। चूंकि इसे डेटा सेट में अलग-अलग आइटम प्रदर्शित करने के लिए फिर से उपयोग किया जाएगा, इसलिए अनावश्यक {@ लिंक देखें # findViewById (int)} कॉल से बचने के लिए दृश्य के उप दृश्यों के संदर्भ कैश करना एक अच्छा विचार है। तो हम सब दृश्यों के संदर्भ कैश कैसे कर सकते हैं? –

0

आप इस का उपयोग कर सकते हैं:

-> एक निर्माता बनाएँ:

/** * 31/10/17 पर दीपक शर्मा द्वारा बनाया गया। */

public class StoreListAdapter<T> extends RecyclerView.Adapter<StoreListAdapter.ViewHolder> implements Filterable { 

    private Collection<T> mItems; 
    private Context context; 
    private int mLayout; 
    IClickable iClickable; 
    private boolean isAnimationAllowed; 
    private StoreSearchFilter<T> mSearchFilter; 

    public StoreListAdapter(Context context) 
    { 
     this.context = context; 
    } 
    public void setData(Collection<T> items, boolean isAnimationAllowed) 
    { 
     mItems = items; 
     this.isAnimationAllowed = isAnimationAllowed; 
    } 

    public void setCallback(int layout, IClickable iClickable) 
    { 
     this.mLayout = layout; 
     this.iClickable = iClickable; 
    } 

    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 
     View view = LayoutInflater.from(viewGroup.getContext()).inflate(mLayout, viewGroup, false); 
     iClickable.init(view); 

     StoreListAdapter.ViewHolder viewHolder = new StoreListAdapter.ViewHolder(view);  
     view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); 
     int width = view.getMeasuredWidth(); 
     int height = view.getMeasuredHeight(); 
//  viewHolder.itemView.getLayoutParams().width = width; 
     viewHolder.itemView.getLayoutParams().height = height+24; 

     return viewHolder; 
    } 

    @Override 
    public void onBindViewHolder(StoreListAdapter.ViewHolder viewHolder, int i) { 
     iClickable.execute(viewHolder, mItems.toArray()[i],viewHolder.getAdapterPosition()); 
     if (isAnimationAllowed) 
      setAnimation(viewHolder.itemView, i); 
    } 

    @Override 
    public int getItemCount() { 
     return mItems.size()>0?mItems.size():0; 
    } 

    @Override 
    public Filter getFilter() { 
     if (mSearchFilter == null) 
      mSearchFilter = new StoreSearchFilter<T>((ArrayList<StoreModel>) mItems, new IFilteredList<T>() { 
       @Override 
       public void onListFiltered(ArrayList<T> list) { 
        setData(list, false); 
        notifyDataSetChanged(); 
       } 
      }); 
     return mSearchFilter; 
    } 

    public class ViewHolder extends RecyclerView.ViewHolder { 

     private final TextView mTextView; 
     //private CheckBox mCheckBox; 

     ViewHolder(View v) { 
      super(v); 
      mTextView = (TextView)v.findViewById(R.id.list_item); 

      // Handle item click and set the selection 
      /*v.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        // Redraw the old selection and the new 
        notifyItemChanged(selectedItem); 
        selectedItem = getLayoutPosition(); 
        notifyItemChanged(selectedItem); 
       } 
      });*/ 
     } 

    } 

    public interface IClickable<T> { 
     public void init(View view); 
     public void execute(StoreListAdapter.ViewHolder holder, T object, int position); 
    } 

    /** 
    * Here is the key method to apply the animation 
    */ 
    private void setAnimation(View viewToAnimate, int position) 
    { 
      Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left); 
      viewToAnimate.startAnimation(animation); 
    } 

} 

-> आप में गतिविधि/टुकड़ा:

ArrayList<StoreModel> mStoreList = new ArrayList<>(); 
mStoreListAdapter = new StoreListAdapter(getActivity()); 
     boolean isAnimate = false; 
     mStoreListAdapter.setData(mStoreList, isAnimate); 

तो फोन कॉलबैक

mStoreListAdapter.setCallback(R.layout.store_item, new StoreListAdapter.IClickable() { 
      @Override 
      public void init(View view) { 
       // Toast.makeText(getActivity(), "Initialized", Toast.LENGTH_SHORT).show(); 
      } 

      @Override 
      public void execute(StoreListAdapter.ViewHolder viewHolder, Object object, int position) { 
       final StoreModel model = (StoreModel) object; 

       View view = viewHolder.itemView; 
       StoreListAdapter.ViewHolder holder = viewHolder; 

       final CoordinatorLayout fabGameview = (CoordinatorLayout) view; 
       final CardView cardView = (CardView) fabGameview.findViewById(R.id.store_item_cardview); 

       TextView txtStoreName = (TextView) cardView.findViewById(R.id.txtStoreName); 
       TextView txtStoreAddress = (TextView) cardView.findViewById(R.id.txtStoreAddress); 
       TextView txtStoreCity = (TextView) cardView.findViewById(R.id.txtStoreCity); 
       TextView txtPrizes = (TextView) cardView.findViewById(R.id.txtPrizes); 
       txtStoreName.setText(model.getStoreName()); 
       txtStoreAddress.setText(model.getStoreAddress()); 
       txtStoreCity.setText(model.getStoreCity()); 
       txtPrizes.setText(String.valueOf(model.getPrizesAvailable())); 

       LinearLayout linearDetails = (LinearLayout) cardView.findViewById(R.id.linearDetails); 
       LinearLayout linearPrize = (LinearLayout) cardView.findViewById(R.id.linearPrize); 

       if (clickedMarkerModel != null && clickedMarkerModel == model) { 
        holder.itemView.setSelected(true); 
//     holder.itemView.setPressed(true); 
//     linearDetails.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark)); 
//     linearPrize.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark)); 
//     mRecyclerStore.stopScroll(); 
       } else { 
        holder.itemView.setSelected(false); 
//     holder.itemView.setPressed(false); 
//     linearDetails.setBackground(ContextCompat.getDrawable(getActivity(), R.drawable.store_selector)); 
//     linearPrize.setBackground(ContextCompat.getDrawable(getActivity(), R.drawable.store_selector)); 
       } 

       // TODO Here scroll recycler view upto selected item 
       /*mRecyclerStore.smoothScrollToPosition(mStoreListAdapter.getItemCount() - 1);*/ 

       cardView.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         boolean isAddedToBackStack = true; 
         StoreDetailsAndProductListFragment storeDetailsAndProductListFragment = new StoreDetailsAndProductListFragment(); 
         Bundle bundle = new Bundle(); 
         bundle.putParcelable(ExtrasUtil.STORE, model); 
         storeDetailsAndProductListFragment.setArguments(bundle); 
         showOtherFragment(storeDetailsAndProductListFragment, getActivity().getFragmentManager(), isAddedToBackStack); 
        } 
       }); 
      } 
     }); 
     mRecyclerStore.setAdapter(mStoreListAdapter);