2015-06-03 4 views
13

Ich benutze RecyclerView.Adapter, aber ich bin etwas verwirrt in Bezug auf die Arbeit seiner Methode onCreateViewHolder.Android RecyclerView.Adapter onCreateViewHolder() funktioniert

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

    } 
} 

So einhüllen habe ich 10 Stück in meiner Liste so für jedes Element diese Methode aufgerufen wird, und jedes Mal, wenn ein neues ViewHolder wird natürlich erstellt werden, es wird einmal für jede Ansicht, aber jetzt ist meine Frage, wenn Wir benutzten ListView und BaseAdapter mit ihnen wir speichern ViewHolder in Tag und verwenden Sie das. Wir erstellen kein ViewHolder für jeden Artikel.

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

So erstellen wir keine zusätzlichen Viewholders-Objekte. Bitte helfen Sie mir, die Vor- und Nachteile zu verstehen.

Dank

Antwort

16

onCreateViewHolder schafft nur einen neuen Halter Ansicht, wenn es keine vorhandenen Ansicht Halter sind, die die RecyclerView wiederverwenden können. Wenn zum Beispiel RecyclerView 5 Elemente gleichzeitig anzeigen kann, erstellt es 5-6 ViewHolders und verwendet sie dann automatisch erneut, wobei jedes Mal onBindViewHolder aufgerufen wird.

Sein ähnlich das, was Ihr Code in den ListView hat (Überprüfung, ob convertViewnull ist, und wenn nicht, die vorhandenen ViewHolder aus dem Tag Rupfen), mit der Ausnahme, mit RecyclerView, das ist alles automatisch.

Ich nehme an, das ist einer der Profis mit einer RecyclerView - Sie müssen sich nicht so viel Sorgen über die Wiederverwendung ViewHolders, wie Sie mit ListView tun. Die Con ist, RecyclerView ist sehr anpassbar, hat aber sehr wenig eingebaute Funktionalität - im Gegensatz zu ListView, die nicht sehr anpassbar ist, aber hat eine Menge eingebauter Funktionalität.

+0

So bedeutet es eine viewholder für jedes Element erzeugen werden und Verwenden Sie dann diesen Halter jedes Mal für diese Zelle der Liste. Recht? –

+0

Danke Gil, ich habe noch eine Frage in RecyclerView.Adapter, aber dafür werde ich eine separate Frage zum Stapelüberlauf stellen. –

+0

Ich habe ein Dokument durchgelesen, das für die abstrakte Methode onCreateViewHolder erwähnt wird. Der neue ViewHolder wird verwendet, um Elemente des Adapters unter Verwendung von {@link #onBindViewHolder (ViewHolder, int)} anzuzeigen. Da es zur Anzeige verschiedener Elemente im Datensatz verwendet wird, empfiehlt es sich, Verweise auf Unteransichten der Ansicht zu cachen, um unnötige Aufrufe von {@link View # findViewById (int)} zu vermeiden. Wie können wir Referenzen auf Unteransichten im Cache speichern? –

0

Sie können diese verwenden:

-> Konstruktor erstellen:

/** * Erstellt von Deepak Sharma auf 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); 
    } 

} 

-> In Ihrer Aktivität/Fragment:

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

dann ruft Rückruf

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); 
Verwandte Themen