Android的RecyclerView的使用

來源:互聯網
上載者:User

標籤:android開發   recyclerview   

Android的RecyclerView的使用

Android推出RecyclerView的時間不算短了,一直沒有具體去瞭解。前段時間公司做代碼最佳化,用到這個。具體瞭解之後發現其功能確實強大。下面來基本解釋RecyclerView控制項

RecyclerView幹啥用的?

可以理解為效率更高的ListView和GridView,而且功能更強大。最關鍵的一個地方,貌似是聽說在Adapter中複用之前已經產生的item,這個估計得查看記憶體方可以看得清楚。

使用RecyclerView,我們需要瞭解一下三個元素

1、RecyclerView.Adapter

2、LayoutManager

3、ItemAnimator

 

1、RecyclerView.Adapter

作為這麼一個看起來蠻叼的控制項,自然用到了各種很厲害的設計模式(這個,我不清楚)。面向介面編程是肯定的,那麼我們來看看它的Adapter

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {public class ViewHolder extends RecyclerView.ViewHolder {public VideoListItem txt1;public VideoListItem txt2;public VideoListItem txt3;public VideoListItem txt4;public ViewHolder(View itemView) {super(itemView);}public VideoListItem getTxt1() {return txt1;}public void setTxt1(VideoListItem txt1) {this.txt1 = txt1;}public VideoListItem getTxt2() {return txt2;}public void setTxt2(VideoListItem txt2) {this.txt2 = txt2;}public VideoListItem getTxt3() {return txt3;}public void setTxt3(VideoListItem txt3) {this.txt3 = txt3;}public VideoListItem getTxt4() {return txt4;}public void setTxt4(VideoListItem txt4) {this.txt4 = txt4;}}private LayoutInflater inflater;public MyAdapter() {inflater = LayoutInflater.from(VideoListActivity.this);}@Overridepublic int getItemCount() {int size = mVideoList.size();if (size == 0) {return 0;}int count = mVideoList.size() / COLUMN;if (size % COLUMN == 0) {return count + 1;} else {return count + 2;}}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic void onBindViewHolder(ViewHolder viewHolder, int position) {System.out.println("wangzx**" +"onCreateViewHolder");int firstIndex = position * COLUMN;int size = mVideoList.size();bindItem(firstIndex + 0, size, position, viewHolder.txt1);bindItem(firstIndex + 1, size, position, viewHolder.txt2);bindItem(firstIndex + 2, size, position, viewHolder.txt3);bindItem(firstIndex + 3, size, position, viewHolder.txt4);}private void bindItem(int index, int size, int position,VideoListItem item) {VideoInfo historyData0 = null;if (size > index) {item.setVisibility(View.VISIBLE);historyData0 = mVideoList.get(index);item.setCurrentLine(position);item.setIndex(index);item.setView_id(historyData0.getVideo_id());item.getmTextView().setText(historyData0.getVideo_name());item.getmRoundedImageView().setCornerRadiusDimen(R.dimen.video_list_corner_radius);item.getmRoundedImageView().setImageResource(R.drawable.history_default);imageLoader.displayImage(historyData0.getVideo_img_url(),item.getmRoundedImageView());}else{item.setVisibility(View.INVISIBLE);}}@Overridepublic MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {System.out.println("wangzx**" +"onCreateViewHolder");View convertView = inflater.inflate(R.layout.video_list_itemlist, parent,false);ViewHolder viewHolder = new ViewHolder(convertView);viewHolder.txt1 = (VideoListItem) convertView.findViewById(R.id.item1);viewHolder.txt2 = (VideoListItem) convertView.findViewById(R.id.item2);viewHolder.txt3 = (VideoListItem) convertView.findViewById(R.id.item3);viewHolder.txt4 = (VideoListItem) convertView.findViewById(R.id.item4);View itemBackground_focus1 = viewHolder.txt1.findViewById(R.id.background_focus);View itemBackground_focus2 = viewHolder.txt2.findViewById(R.id.background_focus);View itemBackground_focus3 = viewHolder.txt3.findViewById(R.id.background_focus);View itemBackground_focus4 = viewHolder.txt4.findViewById(R.id.background_focus);itemBackground_focus1.setOnFocusChangeListener(mVideoListItemOnFocus);itemBackground_focus2.setOnFocusChangeListener(mVideoListItemOnFocus);itemBackground_focus3.setOnFocusChangeListener(mVideoListItemOnFocus);itemBackground_focus4.setOnFocusChangeListener(mVideoListItemOnFocus); //焦點的變換暫時不考慮在內(焦點的擷取同步更新videoCount資料)itemBackground_focus1.setOnClickListener(mOnClick);itemBackground_focus2.setOnClickListener(mOnClick);itemBackground_focus3.setOnClickListener(mOnClick);itemBackground_focus4.setOnClickListener(mOnClick);itemBackground_focus1.setOnKeyListener(mWheelKeyListener);itemBackground_focus2.setOnKeyListener(mWheelKeyListener2);itemBackground_focus3.setOnKeyListener(mWheelKeyListener2);itemBackground_focus4.setOnKeyListener(mWheelKeyListener2);return viewHolder;}}

圖RecyclerView

public class Byhistory__Adapater extends BaseAdapter {private ArrayList<Byhistory_Item> byhistorylist;private LayoutInflater mInflater;public Byhistory__Adapater(Context context,ArrayList<Byhistory_Item> byhistory_list){this.byhistorylist = byhistory_list;this.mInflater = LayoutInflater.from(context);}@Overridepublic int getCount() {return this.byhistorylist.size();}@Overridepublic Object getItem(int arg0) {return null;}@Overridepublic long getItemId(int arg0) {return 0;}@Overridepublic View getView(int position, View convertView, ViewGroup arg2) {Byhistory_Item holder;if(convertView == null){convertView = mInflater.inflate(R.layout.byhistory_item, null);holder = new Byhistory_Item();holder.setLayout_Image((ImageView) convertView.findViewById(R.id.history_item_image));holder.setLayout_ID((TextView) convertView.findViewById(R.id.history_item_name));//holder.setLayout_price((TextView) convertView.findViewById(R.id.history_item_price));holder.setLayout_count((TextView) convertView.findViewById(R.id.history_item_count));holder.setLayout_business((ImageView) convertView.findViewById(R.id.history_item_more));convertView.setTag(holder);}else{holder = (Byhistory_Item) convertView.getTag();}Byhistory_Item dd = byhistorylist.get(position);//holder.getLayout_Image().setBackgroundResource(Integer.valueOf(dd.getItem_Tile_Image()));holder.getLayout_ID().setText(dd.getItem_Title_ID());//holder.getLayout_price().setText(dd.getItem_price());holder.getLayout_count().setText(dd.getItem_count());//holder.getLayout_business().setBackgroundResource(Integer.valueOf(dd.getItem_business()));return convertView;}}

圖ListView

對比listview的adapater我們立馬就能看出來。這裡它單獨弄出來了一個ViewHolder。這個ViewHolder可以是多個layout的組合,這樣做更加靈活,使得布局更加多變(可以仔細想一下是為什麼)。

ListView的Adapter通常是直接匯入資料,下滑。但是RecyclerView的Adapter就不是下滑這麼簡單,上下滑動和左右滑動都成為可能。這個關鍵就是LayoutManager的功勞了。配合ViewHolder的多樣性,功能真是很強大。

 

2、LayoutManager

  知道android貌似確實是有不止一種LayoutManager,但是其他的沒有接觸過,暫就不發表評論,以後可能會補充

LinearLayoutManager

public class MyLinearLayoutManager extends LinearLayoutManager {public MyLinearLayoutManager(Context context) {super(context);}public MyLinearLayoutManager(Context context, int orientation,boolean reverseLayout) {super(context, orientation, reverseLayout);}@Overridepublic boolean requestChildRectangleOnScreen(RecyclerView parent,View child, Rect rect, boolean immediate) {final int parentLeft = getPaddingLeft();final int parentTop = getPaddingTop();final int parentRight = getWidth() - getPaddingRight();final int parentBottom = getHeight() - getPaddingBottom();final int childLeft = child.getLeft() + rect.left;final int childTop = child.getTop() + rect.top;final int childRight = childLeft + rect.right;final int childBottom = childTop + rect.bottom;final int offScreenLeft = Math.min(0, childLeft - parentLeft);final int offScreenTop = Math.min(0, childTop - parentTop);final int offScreenRight = Math.max(0, childRight - parentRight);final int offScreenBottom = Math.max(0, childBottom - parentBottom);// Favor the "start" layout direction over the end when bringing one// side or the other// of a large rect into view.final int dx;if (ViewCompat.getLayoutDirection(parent) == ViewCompat.LAYOUT_DIRECTION_RTL) {dx = offScreenRight != 0 ? offScreenRight : offScreenLeft;} else {dx = offScreenLeft != 0 ? offScreenLeft : offScreenRight;}// Favor bringing the top into view over the bottomint dy = offScreenTop != 0 ? offScreenTop : offScreenBottom;if (dy > 0) {//位移量是40,焦點計算的高是360,比整體高少40,原因是焦點的view是item的子View,item的高度是400dy += 40;//dy += 400;}if (dy < 0) {//dy -= 400;}if (dx != 0 || dy != 0) {if (immediate) {parent.scrollBy(dx, dy);} else {parent.smoothScrollBy(dx, dy);}return true;}return false;}@Overridepublic int scrollHorizontallyBy(int dx, Recycler recycler, State state) {return dx;}}
public boolean requestChildRectangleOnScreen(RecyclerView parent,

View child, Rect rect, boolean immediate)函數是相當重要的,它基本就能夠確定在布局中滾動或者滑動時候,子Item和parent之間的位置。仔細查看這個函數的父類源碼我們可以知道,dy,dx的實際意義就是在滾動中下滑和左右滑動的距離。而這個值的確定會嚴重影響滑動的流暢程度(我一直在調試這兩個值……)

public int scrollHorizontallyBy(int dx, Recycler recycler, State state)這個函數是滑動中的回呼函數。見到的人肯定很多,不足為奇。

 

3、ItemAnimator

是滑動進行中的動畫,聽別人說很炫,但是自己貌似沒有親手去實現,知道有這麼個東西而已吧。

 

 

Android的RecyclerView的使用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.