1. RecyclerView 高度动态调整
solution ( RecyclerView的高度控制都在 LayoutManager 中)
LinearLayoutManager exceptionLayoutManager = new LinearLayoutManager(this){
@Override
public void onMeasure( recycler, state, int widthSpec, int heightSpec) {
View view = (0);
if (view != null) {
measureChild(view, widthSpec, heightSpec);
//int measuredWidth = (widthSpec);
int measuredHeight = ();
int showHeight = measuredHeight * ();
if(() >= 5){
showHeight = measuredHeight * 5;
}
setMeasuredDimension(widthSpec, showHeight);
}
}
};
(false);
(false);
(exceptionLayoutManager);
(new DefaultItemAnimator());
/buobao/blog/651279
1.1
(false)
(false)
@Override
public void onMeasure( recycler, state, int widthSpec,int heightSpec) {
View view = (0);
measureChild(view, widthSpec, heightSpec);
int measuredWidth = (widthSpec);
int measuredHeight = ();
setMeasuredDimension(measuredWidth, measuredHeight);
}
1.2这里获取了view的高度,也就是item布局的高度,所以item的布局需要设定固定的高度,否则获取为0。其次,
这两个设置不能少,否则报错,这里和中的调用顺序有关,源码:
protected void onMeasure(int widthSpec, int heightSpec) {
if (mLayout == null) {
defaultOnMeasure(widthSpec, heightSpec);
return;
}
if () { //这里为true会进入该分支
final int widthMode = (widthSpec);
final int heightMode = (heightSpec);
final boolean skipMeasure = widthMode ==
&& heightMode == ;
(mRecycler, mState, widthSpec, heightSpec); //在调用mLayout的onMeasure方法时(被自定义复写的方法),为0,造成越界异常
if (skipMeasure || mAdapter == null) {
return;
}
if ( == State.STEP_START) {
dispatchLayoutStep1();
}
// set dimensions in 2nd step. Pre-layout should happen with old dimensions for
// consistency
(widthSpec, heightSpec);
= true;
dispatchLayoutStep2();
// now we can get the width and height from the children.
(widthSpec, heightSpec);
// if RecyclerView has non-exact width and height and if there is at least one child
// which also has non-exact width & height, we have to re-measure.
if (()) {
(
(getMeasuredWidth(), ),
(getMeasuredHeight(), ));
= true;
dispatchLayoutStep2();
// now we can get the width and height from the children.
(widthSpec, heightSpec);
}
} else {
if (mHasFixedSize) { //这里不设置为false会造成与上面相同的问题
(mRecycler, mState, widthSpec, heightSpec);
return;
}
// custom onMeasure
if (mAdapterUpdateDuringMeasure) {
eatRequestLayout();
processAdapterUpdatesAndSetAnimationFlags();
if () {
= true;
} else {
// consume remaining updates to provide a consistent state with the layout pass.
();
= false;
}
mAdapterUpdateDuringMeasure = false;
resumeRequestLayout(false);
}
if (mAdapter != null) {
= ();
} else {
= 0;
}
eatRequestLayout();
(mRecycler, mState, widthSpec, heightSpec); //在这里调用时才会有值,这与mLayout中获取当前item布局的方式有关:View view = (0);
resumeRequestLayout(false);
= false; // clear
}
}
2. 关于RecyclerView的宽高调整 /crazyman2010/article/details/54315109
设置ItemView的间隔高宽
重写ItemDecoration的getItemOffsets函数即可:
(new () {
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, state) {
(outRect, view, parent, state);
(4, 4, 4, 4);//设置itemView中内容相对边框左,上,右,下距离
}
});
3. ItemView适应RecyclerView
RecyclerView大小固定的情况下,根据RecyclerView的宽高设置ItemView的宽高,以达到recyclerview刚好显示N行/列数据的目的:
在原理是先计算出RecyclerView的宽高,然后在Adapter的onCreateViewHolder中设置view的高度:
比如一个垂直列表,希望recyclerview刚好显示三行,这样写:
@Override
public onCreateViewHolder(ViewGroup parent, int viewType) {
View view = (()).inflate(布局文件, parent, false);
().height = mRecyclerViewHeight/3;
return new ServiceItemViewHolder(view);
}