2015-06-03 19 views
13

Tôi đang sử dụng RecyclerView.Adapter nhưng tôi hơi bối rối về việc làm việc của phương pháp của nó onCreateViewHolder.Android RecyclerView.Adapter onCreateViewHolder() làm việc

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

    } 
} 

Vì vậy, trong trường hợp tôi có 10 mục trong danh sách của tôi vì vậy đối với từng mặt phương pháp này sẽ được gọi và mỗi khi một mới ViewHolder sẽ được tạo ra tất nhiên nó sẽ một lần cho mỗi điểm nhưng bây giờ câu hỏi của tôi là khi chúng tôi đã sử dụng ListViewBaseAdapter với chúng, chúng tôi lưu trữ ViewHolder trong thẻ và sử dụng thẻ đó. Chúng tôi không tạo ra ViewHolder cho mỗi mục.

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

Vì vậy, chúng tôi không tạo thêm đối tượng người xem. Xin hãy giúp tôi hiểu những ưu và khuyết điểm.

Cảm ơn

Trả lời

16

onCreateViewHolder chỉ tạo ra một người giữ quan điểm mới khi không có người xem hiện tại mà RecyclerView thể tái sử dụng. Vì vậy, ví dụ: nếu RecyclerView của bạn có thể hiển thị 5 mục cùng một lúc, nó sẽ tạo 5-6 ViewHolders và sau đó tự động sử dụng lại chúng, mỗi lần gọi onBindViewHolder.

tương tự của nó với những gì mã của bạn trong ListView không (kiểm tra nếu convertViewnull, và nếu không, lấy các ViewHolder hiện từ thẻ), ngoại trừ với RecyclerView, đây là tất cả thực hiện tự động.

Tôi cho rằng đây là một trong những ưu điểm khi sử dụng RecyclerView - bạn không cần phải lo lắng nhiều về việc sử dụng lại ViewHolders như bạn làm với ListView. Con là, RecyclerView là rất tùy biến, nhưng có rất ít được xây dựng trong chức năng - không giống như ListView mà không phải là rất tùy biến, nhưng có rất nhiều chức năng được xây dựng trong.

+0

Vì vậy, nó có nghĩa là nó sẽ tạo ra một viewholder cho từng hạng mục và sau đó sử dụng chủ sở hữu đó mỗi lần cho ô đó của danh sách. đúng? –

+0

Cảm ơn Gil, tôi có thêm một câu hỏi trong RecyclerView.Adapter nhưng tôi sẽ đặt một câu hỏi riêng biệt trên ngăn xếp ngăn xếp. –

+0

Tôi đã đi qua một số tài liệu được đề cập cho phương pháp trừu tượng onCreateViewHolder. ViewHolder mới sẽ được sử dụng để hiển thị các mục của bộ điều hợp sử dụng {@link #onBindViewHolder (ViewHolder, int)}. Vì nó sẽ được sử dụng lại để hiển thị các mục khác nhau trong tập dữ liệu, nên lưu ý tham chiếu đến chế độ xem phụ của Chế độ xem để tránh các cuộc gọi {@link View # findViewById (int)} không cần thiết. Vậy làm thế nào chúng ta có thể lưu trữ các tham chiếu đến các khung nhìn phụ? –

0

Bạn có thể sử dụng này:

-> Tạo một constructor:

/** * Tạo bởi Deepak Sharma vào 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); 
    } 

} 

-> Trong bạn Hoạt động/Fragment:

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

sau đó gọi callback

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); 
Các vấn đề liên quan