Android的RecyclerView的使用

AndroidRecyclerView的使用

Android推出RecyclerView的时间不算短了,一直没有具体去了解。前段时间公司做代码优化,用到这个。具体了解之后发现其功能确实强大。下面来基本解释RecyclerView控件

RecyclerView干啥用的?

可以理解为效率更高的ListViewGridView,而且功能更强大。最关键的一个地方,貌似是听说在Adapter中复用之前已经产生的item,这个估计得查看内存方可以看得清楚。

使用RecyclerView,我们需要了解一下三个元素

1、RecyclerView.Adapter

2、LayoutManager

3、ItemAnimator

 

1RecyclerView.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);
		}

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

对比listviewadapater我们立马就能看出来。这里它单独弄出来了一个ViewHolder。这个ViewHolder可以是多个layout的组合,这样做更加灵活,使得布局更加多变(可以仔细想一下是为什么)。

ListViewAdapter通常是直接导入数据,下滑。但是RecyclerViewAdapter就不是下滑这么简单,上下滑动和左右滑动都成为可能。这个关键就是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)函数是相当重要的,它基本就能够确定在布局中滚动或者滑动时候,子Itemparent之间的位置。仔细查看这个函数的父类源码我们可以知道,dydx的实际意义就是在滚动中下滑和左右滑动的距离。而这个值的确定会严重影响滑动的流畅程度(我一直在调试这两个值……)

public int scrollHorizontallyBy(int dx, Recycler recycler, State state)这个函数是滑动中的回调函数。见到的人肯定很多,不足为奇。

 

3、ItemAnimator

是滑动进行中的动画,听别人说很炫,但是自己貌似没有亲手去实现,知道有这么个东西而已吧。

 

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。