Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android的RecyclerView的使用

Android的RecyclerView的使用

編輯:關於Android編程

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

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

		@Override
		public long getItemId(int position) {
			return 0;
		}

		@Override
		public 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);
			}
		}
		

		@Override
		public 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 byhistorylist;
	private LayoutInflater mInflater;
	
	public Byhistory__Adapater(Context context,ArrayList byhistory_list){
		this.byhistorylist = byhistory_list;
		this.mInflater = LayoutInflater.from(context);
	}
	
	@Override
	public int getCount() {
		return this.byhistorylist.size();
	}

	@Override
	public Object getItem(int arg0) {
		return null;
	}

	@Override
	public long getItemId(int arg0) {
		return 0;
	}

	@Override
	public 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);
	}

	@Override
	public 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 bottom
		int dy = offScreenTop != 0 ? offScreenTop : offScreenBottom;
		if (dy > 0) {
			//偏移量是40,焦點計算的高是360,比整體高少40,原因是焦點的view是item的子View,item的高度是400
			dy += 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;
	}
	
	
	@Override
	public 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

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

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved