note_28:RecyclerView分标题栏和内容栏的实现和Glide加载图片并将图片变成灰度图

RecyclerView分标题栏和内容栏的实现和Glide加载图片并将图片变成灰度图


参考:
RecyclerView有标题栏的分类列表 自定义列数(不同行设置不同个子项item)
Android图片转换类 1. Bitmap去色,转换为黑白的灰度图, 2. Bitmap图片加圆角效果
Glide变换
Class BitmapTransformation


文章目录

  • RecyclerView分标题栏和内容栏的实现和Glide加载图片并将图片变成灰度图
    • 1. RecyclerView分标题栏和内容栏的实现
      • (1) RecyclerView.ViewHolder
      • (2) onAttachedToRecyclerView
      • (3) getItemViewType
      • (4) onCreateViewHolder
      • (5) onBindViewHolder
    • 2. Glide加载图片并将图片变成灰度图


1. RecyclerView分标题栏和内容栏的实现

(1) RecyclerView.ViewHolder

因为要区分标题栏和内容栏,所以这两个item的布局是不一样的,不大可能使用同一个itemView。
然而从源代码里可以看到,一个ViewHolder只能绑定一个itemView,所以需要分成两个ViewHolder。
但是一个RecyclerView.Adapter里面只能跟一个AppAdapter.ViewHolder,所以要把这两个ViewHolder变成内部类写在一个ViewHolder里面。

public class ViewHolder extends RecyclerView.ViewHolder {
	private static final int TYPE_TITLE = 0;

	public TitleViewHolder titleViewHolder;
	public ContentViewHolder contentViewHolder;

	// 一定要写 而且不能改参数列表 也不能删掉super(itemView)
	// 但是因为我们真正用到的构造函数不是这个 所以也就先摆在这里
	public ViewHolder(View itemView) {
		super(itemView);
	}

	// 相当于初始化了另外两个VieHolder的其中一个 因为一次onBindViewHolder只能绑定一个
	public ViewHolder(View view, int type) {
		this(view);
		if (type == TYPE_TITLE) titleViewHolder = new TitleViewHolder(view);
		else contentViewHolder = new ContentViewHolder(view);
	}

	public class TitleViewHolder extends RecyclerView.ViewHolder {
		// 标题的布局 外面一层LinearLayout加里面一个TextView
		@BindView(R.id.title)
		TextView title;

		public TitleViewHolder(View itemView) {
			super(itemView);
			ButterKnife.bind(this, itemView);
		}
	}

	public class ContentViewHolder extends RecyclerView.ViewHolder {
		// 内容的布局 外面一层LinearLayout里面一个ImageView
		@BindView(R.id.image)
		ImageView image;

		public ContentViewHolder(View itemView) {
			super(itemView);
			ButterKnife.bind(this, itemView);
		}
	}
}

(2) onAttachedToRecyclerView

由于这个RecyclerView是使用GridLayoutManager来完成的,所以如果是遇到标题的话,那标题应该是占满了一整行。

RecyclerView的部分源码

/**
  * Called by RecyclerView when it starts observing this Adapter.
  * 

* Keep in mind that same adapter may be observed by multiple RecyclerViews. * * @param recyclerView The RecyclerView instance which started observing this adapter. * @see #onDetachedFromRecyclerView(RecyclerView) */ public void onAttachedToRecyclerView(RecyclerView recyclerView) { }

所以需要重写onAttachedToRecyclerView

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
	GridLayoutManager manager = (GridLayoutManager) recyclerView.getLayoutManager();
	// 设置一个item占的空间
	manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
		@Override
		public int getSpanSize(int i) {
			// 如果不是标题 那就站一格
			// 如果是标题 那就占满正行
			if (!mListItems.get(i).isTitle()) return 1;
			else return NUM_COLUMNS;
		}
	});
}

(3) getItemViewType

因为创建ViewHolder的实例的时候需要判断是标题栏还是内容栏,在onCreateViewHolder的时候会用上。

RecyclerView的部分源码

/**
  * Return the view type of the item at position for the purposes
  * of view recycling.
  *
  * 

The default implementation of this method returns 0, making the assumption of * a single view type for the adapter. Unlike ListView adapters, types need not * be contiguous. Consider using id resources to uniquely identify item view types. * * @param position position to query * @return integer value identifying the type of the view needed to represent the item at * position. Type codes need not be contiguous. */ public int getItemViewType(int position) { return 0; }

重写getItemViewType

@Override 
public int getItemViewType(int position) {
	if (mListItems.get(position).isTitle()) return VIEW_TYPE_TITLE;
	else return VIEW_TYTPE_CONTENT;
}

(4) onCreateViewHolder

前面在getItemViewType的时候已经给ViewHolder分了类型。

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
	LayoutInflater inflater = LayoutInflater.from(parent.getContext());
	View view;
	ViewHolder viewHolder = null;
	switch (viewType) {
		case VIEW_TYPE_TITLE:
			view = inflater.inflate(R.layout.adapter_title, null);
			viewHolder = new ViewHolder(view, VIEW_TYPE_TITLE);
			break;

		case VIEW_TYTPE_CONTENT:
			view = inflater.inflate(R.layout.adapter_content);
			viewHolder = new ViewHolder(view, VIEW_TYTPE_CONTENT);
			break;

		default:
			break;		
	}
	return viewHolder;
}

(5) onBindViewHolder

创建完ViewHoder之后就要绑定每个ViewHolder里面的信息,例如TextView里面要写些什么字,ImageView里面要放张什么图,
要不要给每一个item加个点击事件或者自己写个别的回调。

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
	Item item = mListItems.get(position);
	if (item.isTitle()) {
		holder.titleViewHolder.title.setText(item.getTitle());
	} else {
		holder.contentViewHolder.image.setImageDrawable(item.getIcon());
		holder.contentViewHolder.image.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Toast.makeText(mContext, "you click this imageView", Toast.LENGTH_SHORT).show();
			}
		});
	}
}

2. Glide加载图片并将图片变成灰度图

用回上面onBindViewHolder的代码,不过这个时候的图片不是本地获取的,而是从网上下载的。

// 因为存储的时候是String类型的网址 所以必须转成Uri类型
Uri uri = Uri.parse(item.getUri());

// Glide有提供transform函数对获取的图片进行转换
// 如果直接从holder.contentViewHolder.image中获取图片的话 是null
Glide.with(mContext)
		.load(uri)
		.transform(new Adapter.ColorfulToGrey(mContext))
		.into(holder.contentViewHolder.image);

灰度图的算法,从网上找的

// 官方推荐是继承BitmapTransformation来写
public class ColorfulToGrey extends BitmapTransformation {
	private static final String ID = "com.example.demo.ColorfulToGrey";

	public ColorfulToGrey(Context context) {
		super(context);
	}

	@Override
	protected Bitmap transform(BitmapPool bitmapPool, Bitmap bitmap, int i0, int i1) {
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
		Canvas canvas = new Canvas(result);
		Paint paint = new Paint();
		ColorMatrix ColorMatrix = new ColorMatrix();
		colorMatrix.setSaturation(0);
		ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
		paint.setColorFilter(filter);
		canvas.drawBitmap(bitmap, 0, 0, paint);
		return result;
	}

	@Override
	public String getId() {
		return ID;
	}

	@Override
	public int hashCode() {
		return ID.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == null) return false;
		return obj instanceof Adapter.ColorfulToGrey;
	}

}

你可能感兴趣的:(安卓,note,菜鸟)