要实现的效果我们在前三篇的文章中都已经实现了
但是没有可以一次写出来的完美的代码 我们的代码应该在重构中段前行
1.合并冗余代码
再次大家写代码的过程中总是会出现一些重复需要的代码,但是为了时间的缘故我们只是单纯的复制粘贴就好了 也没有去考虑一个良好的代码结构,这些的出现就是我们要处理的冗余代码
比如我完成这三的的时候冗余的代码就有
/**
* 获取RecyclerView的显示高度
*/
public int getVerticalSpace() {
return getHeight() - getPaddingTop() - getPaddingBottom();
}
/**
* 获取RecyclerView的显示宽度
*/
public int getHorizontalSpace() {
return getWidth() - getPaddingLeft() - getPaddingRight();
}
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(RecyclerView.LayoutParams.WRAP_CONTENT,
RecyclerView.LayoutParams.WRAP_CONTENT);
}
至于如何优化一般有两种方式
1.将重复代码写到工具类中
2.如果重复代码与本身的基类关联比较密切 我们应该新建一个基类 让他们来继承
这里我们采用第二种方式
这只完整的的最基础的基类
public class BaseLayoutManager extends RecyclerView.LayoutManager {
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
/**
* 获取RecyclerView的显示高度
*/
public int getVerticalSpace() {
return getHeight() - getPaddingTop() - getPaddingBottom();
}
/**
* 获取RecyclerView的显示宽度
*/
public int getHorizontalSpace() {
return getWidth() - getPaddingLeft() - getPaddingRight();
}
}
2.使用模板
我们可以使用模板设计模式 来是我们在整个实现过程中保持一个良好的思路
在做这件事情之前我们先要整理出自己的自定义LayoutManager的实现思路是什么 我们只要按照这个思路实现就行了 后面的人如果去看这个基类也能有一个良好的思路 在这三个实现类中我们要整理的主要部分是 onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state)
这个方法的实现里面
所以我们主要就是实现基类中的onLayoutChildren方法
我们设计的模板
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
if (getItemCount() <= 0 || state.isPreLayout()) {
return;
}
//移除所有View
removeAndRecycleAllViews(recycler);
initItemView(recycler);
List<T> itemViewList = createItemViewInfoList();
detachAndScrapAttachedViews(recycler);
drawView(recycler, state, itemViewList);
}
@Override
public void initItemView(RecyclerView.Recycler recycler) {
}
@Override
public List<T> createItemViewInfoList() {
return null;
}
@Override
public void drawView(RecyclerView.Recycler recycler, RecyclerView.State state, List<T> itemViewList) {
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
if (getItemCount() <= 0 || state.isPreLayout()) {
return;
}
//移除所有View
removeAndRecycleAllViews(recycler);
initItemView(recycler);
List<T> itemViewList = createItemViewInfoList();
detachAndScrapAttachedViews(recycler);
drawView(recycler, state, itemViewList);
}
@Override
public void initItemView(RecyclerView.Recycler recycler) {
}
@Override
public List<T> createItemViewInfoList() {
return null;
}
@Override
public void drawView(RecyclerView.Recycler recycler, RecyclerView.State state, List<T> itemViewList) {
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
if (getItemCount() <= 0 || state.isPreLayout()) {
return;
}
//移除所有View
removeAndRecycleAllViews(recycler);
initItemView(recycler);
List<T> itemViewList = createItemViewInfoList();
// 在布局之前,将所有的子 View 先 Detach 掉,放入到 Scrap 缓存中
detachAndScrapAttachedViews(recycler);
drawView(recycler, state, itemViewList);
}
@Override
public void initItemView(RecyclerView.Recycler recycler) {
}
@Override
public List<T> createItemViewInfoList() {
return null;
}
@Override
public void drawView(RecyclerView.Recycler recycler, RecyclerView.State state, List<T> itemViewList) {
}
设计的接口
public interface LayoutManagerInterface<T> {
/***
* 初始化绘制参数
* @param recycler
*/
void initItemView(RecyclerView.Recycler recycler) ;
/***
* 创建绘制界面所需要的bean
* @return
*/
List<T> createItemViewInfoList() ;
/***
* 实际绘制
* @param recycler
* @param state
* @param itemViewList
*/
void drawView(RecyclerView.Recycler recycler, RecyclerView.State state, List<T> itemViewList) ;
}
在这做的时候有两个想法
1.使用泛型是每个实现类都自己的实体类
- 写一个包含所有的属性的bean 每个实现类都使用这实体类
虽然感觉两个都可以,但是最终选择了 1 至于为什么 我也不知道直觉吧
这样我们最基础的模板就大好了 我们就可以去改在具体的实现类了 后面我们发现有什么共有的特征可以在玩基类里面加
我在这里只是说以下一个的改造 感觉写的时候第一个最差也最容易就改第一个吧。
首先我们应该有一个控制类来控制list的信息的配置和list的创建并和View的绘制个里所以有了TanTanControl类
public class TanTanControl {
private int count = 4;
private float scale = 0.05f;
private int translateY = 100;
public TanTanControl(int count, float scale, int translateY) {
this.count = count;
this.scale = scale;
this.translateY = translateY;
}
public int getCount() {
return count;
}
public float getScale() {
return scale;
}
public int getTranslateY() {
return translateY;
}
public List<TanTanBean> createItemViewInfoList(int itemCount) {
int lastPosition;
if (itemCount < count) {
lastPosition = 0;
} else {
lastPosition = itemCount - count;
}
List<TanTanBean> tanTanBeanList = new ArrayList<>();
for (int position = lastPosition; position < itemCount; position++) {
TanTanBean tanTanBean = new TanTanBean();
int level = itemCount - position - 1;
tanTanBean.setLevel(level);
//设置每层的Scale和translationY
if (level > 0) {
//设置每一层X方向的缩小
tanTanBean.setScaleX(1 - scale * level);
if (level < count - 1) {
//Y需要缩小的和位移
tanTanBean.setTranslateY(translateY * level);
tanTanBean.setScaleY(1 - scale * level);
} else {
//不需要缩小和位移只需要和前一层保持一致
tanTanBean.setTranslateY(translateY * (level - 1));
tanTanBean.setScaleY(1 - scale * (level - 1));
}
}
tanTanBeanList.add(tanTanBean);
}
return tanTanBeanList;
}
}
在这里面负责逻辑和默认参数的配置
而新的Layoutmanager只负责View层的绘制
public class TanTanLayoutManager extends BaseLayoutManager<TanTanBean> {
TanTanControl tanTanControl;
public TanTanLayoutManager(TanTanControl tanTanControl) {
this.tanTanControl = tanTanControl;
}
@Override
public void initItemView(RecyclerView.Recycler recycler) {
}
@Override
public List<TanTanBean> createItemViewInfoList() {
return tanTanControl.createItemViewInfoList(getItemCount());
}
@Override
public void drawView(RecyclerView.Recycler recycler, RecyclerView.State state, List<TanTanBean> itemViewList) {
int itemCount = getItemCount();
if (itemCount < 1) {
return;
}
for (int i = 0; i < itemViewList.size(); i++) {
TanTanBean tanTanBean = itemViewList.get(i);
View view = recycler.getViewForPosition(itemCount - tanTanBean.getLevel() - 1);
addView(view);
measureChildWithMargins(view, 0, 0);
int widthSpace = getWidth() - getDecoratedMeasuredWidth(view);
int heightSpace = getHeight() - getDecoratedMeasuredHeight(view);
layoutDecoratedWithMargins(view, widthSpace / 2, heightSpace / 4,
widthSpace / 2 + getDecoratedMeasuredWidth(view),
heightSpace / 4 + getDecoratedMeasuredHeight(view));
if (tanTanBean.getLevel() > 0) {
view.setScaleX(tanTanBean.getScaleX());
view.setTranslationY(tanTanBean.getTranslateY());
view.setScaleY(tanTanBean.getScaleY());
}
}
}
}
他们两件中间联系的纽带实体类
public class TanTanBean {
private int translateY;
private float scaleX;
private float scaleY;
private int level;
}
这样改造基本就完成了 然后就是抽时间吧另外两个也改了
网友评论