Android:自定义LinearLayoutManager不允许recyclerView滚动
我正在使用自定义LinearLayoutManager为我的recyclerView禁用/启用滚动Android:自定义LinearLayoutManager不允许recyclerView滚动,android,scroll,android-recyclerview,linearlayoutmanager,Android,Scroll,Android Recyclerview,Linearlayoutmanager,我正在使用自定义LinearLayoutManager为我的recyclerView禁用/启用滚动 public class CustomLayoutManager extends LinearLayoutManager { private boolean isScrollEnabled = true; public CustomLayoutManager(Context context) { super(context); } public
public class CustomLayoutManager extends LinearLayoutManager {
private boolean isScrollEnabled = true;
public CustomLayoutManager(Context context) {
super(context);
}
public void setScrollEnabled(boolean flag) {
this.isScrollEnabled = flag;
}
@Override
public boolean canScrollVertically() {
return isScrollEnabled && super.canScrollVertically();
}
}
当我使用它来设置我的RecyclerView时,即使我将IsScrolleEnabled设置为true,它也不会滚动
CustomLayoutManager customLayoutManager = new CustomLayoutManager(getActivity());
customLayoutManager.setScrollEnabled(true);
recyclerView.setLayoutManager(customLayoutManager);
有人能帮忙吗?
嗨
这段代码工作得很好,但我不能让circle Recycleview mathparent
public class Layoutmameger extends LayoutManager{
private static int INTERVAL_ANGLE = 50;// The default interval angle between each items
private static float DISTANCE_RATIO = 20f; // Finger swipe distance divide item rotate angle
//Flags of scroll dirction
private static int SCROLL_LEFT = 1;
private static int SCROLL_RIGHT = 2;
private Context context;
// Size of each items
private int mDecoratedChildWidth;
private int mDecoratedChildHeight;
//Property
private int startLeft;
private int startTop;
private int mRadius;
private int intervalAngle;
private float offsetRotate; // The offset angle for each items which will change according to the scroll offset
//the range of remove from parent
private int minRemoveDegree;
private int maxRemoveDegree;
//initial position of content
private int contentOffsetX = -1;
private int contentOffsetY = -1;
private int firstChildRotate = 0;
//Sparse array for recording the attachment and rotate angle of each items
private SparseBooleanArray itemAttached = new SparseBooleanArray();
private SparseArray<Float> itemsRotate = new SparseArray<>();
public Layoutmameger(Context context) {
this.context = context;
intervalAngle = INTERVAL_ANGLE;
offsetRotate = 0;
minRemoveDegree = -90;
maxRemoveDegree = 90;
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
if (getItemCount() == 0) {
detachAndScrapAttachedViews(recycler);
offsetRotate = 0;
return;
}
//calculate the size of child
if (getChildCount() == 0) {
View scrap = recycler.getViewForPosition(0);
addView(scrap);
measureChildWithMargins(scrap, 0, 0);
mDecoratedChildWidth = getDecoratedMeasuredWidth(scrap);
mDecoratedChildHeight = getDecoratedMeasuredHeight(scrap);
startLeft = contentOffsetX == -1?(getHorizontalSpace() - mDecoratedChildWidth)/2: contentOffsetX;
startTop = contentOffsetY ==-1?0: contentOffsetY;
mRadius = mDecoratedChildHeight;
detachAndScrapView(scrap, recycler);
}
//record the state of each items
float rotate = firstChildRotate;
for (int i = 0; i < getItemCount(); i++) {
itemsRotate.put(i,rotate);
itemAttached.put(i,false);
rotate+= intervalAngle;
}
detachAndScrapAttachedViews(recycler);
fixRotateOffset();
layoutItems(recycler,state);
}
private void layoutItems(RecyclerView.Recycler recycler,RecyclerView.State state){
layoutItems(recycler,state,SCROLL_RIGHT);
}
private void layoutItems(RecyclerView.Recycler recycler,
RecyclerView.State state,int oritention){
if(state.isPreLayout()) return;
//remove the views which out of range
for(int i = 0;i<getChildCount();i++){
View view = getChildAt(i);
int position = getPosition(view);
if(itemsRotate.get(position) - offsetRotate>maxRemoveDegree
|| itemsRotate.get(position) - offsetRotate< minRemoveDegree){
itemAttached.put(position,false);
removeAndRecycleView(view,recycler);
}
}
//add the views which do not attached and in the range
for(int i=0;i<getItemCount();i++){
if(itemsRotate.get(i) - offsetRotate<= maxRemoveDegree
&& itemsRotate.get(i) - offsetRotate>= minRemoveDegree){
if(!itemAttached.get(i)){
View scrap = recycler.getViewForPosition(i);
measureChildWithMargins(scrap, 0, 0);
if(oritention == SCROLL_LEFT)
addView(scrap,0);
else
addView(scrap);
float rotate = itemsRotate.get(i) - offsetRotate;
int left = calLeftPosition(rotate);
int top = calTopPosition(rotate);
scrap.setRotation(rotate);
layoutDecorated(scrap, startLeft + left, startTop + top,
startLeft + left + mDecoratedChildWidth, startTop + top + mDecoratedChildHeight);
itemAttached.put(i,true);
}
}
}
}
@Override
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
int willScroll = dx;
float theta = dx/DISTANCE_RATIO; // the angle every item will rotate for each dx
float targetRotate = offsetRotate + theta;
//handle the boundary
if (targetRotate < 0) {
willScroll = (int) (-offsetRotate*DISTANCE_RATIO);
}
else if (targetRotate > getMaxOffsetDegree()) {
willScroll = (int) ((getMaxOffsetDegree() - offsetRotate)*DISTANCE_RATIO);
}
theta = willScroll/DISTANCE_RATIO;
offsetRotate+=theta; //increase the offset rotate so when re-layout it can recycle the right views
//re-calculate the rotate x,y of each items
for(int i=0;i<getChildCount();i++){
View view = getChildAt(i);
float newRotate = view.getRotation() - theta;
int offsetX = calLeftPosition(newRotate);
int offsetY = calTopPosition(newRotate);
layoutDecorated(view, startLeft + offsetX, startTop + offsetY,
startLeft + offsetX + mDecoratedChildWidth, startTop + offsetY + mDecoratedChildHeight);
view.setRotation(newRotate);
}
//different direction child will overlap different way
if (dx < 0)
layoutItems(recycler, state,SCROLL_LEFT);
else
layoutItems(recycler,state,SCROLL_RIGHT);
return willScroll;
}
/**
*
* @param rotate the current rotate of view
* @return the x of view
*/
private int calLeftPosition(float rotate){
return (int) (mRadius * Math.cos(Math.toRadians(90 - rotate)));
}
/**
*
* @param rotate the current rotate of view
* @return the y of view
*/
private int calTopPosition(float rotate){
return (int) (mRadius - mRadius * Math.sin(Math.toRadians(90 - rotate)));
}
private int getHorizontalSpace() {
return getWidth() - getPaddingRight() - getPaddingLeft();
}
private int getVerticalSpace() {
return getHeight() - getPaddingBottom() - getPaddingTop();
}
/**
* fix the offset rotate angle in case item out of boundary
**/
private void fixRotateOffset() {
if(offsetRotate < 0){
offsetRotate = 0;
}
if(offsetRotate > getMaxOffsetDegree()){
offsetRotate = getMaxOffsetDegree();
}
}
/**
*
* @return the max degrees according to current number of views and interval angle
*/
private float getMaxOffsetDegree(){
return (getItemCount()-1)* intervalAngle;
}
private PointF computeScrollVectorForPosition(int targetPosition) {
if (getChildCount() == 0) {
return null;
}
final int firstChildPos = getPosition(getChildAt(0));
final int direction = targetPosition < firstChildPos ? -1 : 1;
return new PointF(direction, 0);
}
@Override
public boolean canScrollHorizontally() {
return true;
}
@Override
public void scrollToPosition(int position) {
if(position < 0 || position > getItemCount()-1) return;
float targetRotate = position * intervalAngle;
if(targetRotate == offsetRotate) return;
offsetRotate = targetRotate;
fixRotateOffset();
requestLayout();
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
LinearSmoothScroller smoothScroller = new LinearSmoothScroller(context) {
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return Layoutmameger.this.computeScrollVectorForPosition(targetPosition);
}
};
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
@Override
public void onAdapterChanged(RecyclerView.Adapter oldAdapter, RecyclerView.Adapter newAdapter) {
removeAllViews();
offsetRotate = 0;
}
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
/**
*
* @return Get the current positon of views
*/
public int getCurrentPosition(){
return Math.round(offsetRotate / intervalAngle);
}
/**
*
* @return Get the dx should be scrolled to the center
*/
public int getOffsetCenterView(){
return (int) ((getCurrentPosition()*intervalAngle-offsetRotate)*DISTANCE_RATIO);
}
/**
*
* @return Get the radius of the circle
*/
public int getRadius() {
return mRadius;
}
/**
*
* @param mRadius the radius of the circle,default will be item's height
*/
public void setRadius(int mRadius) {
this.mRadius = mRadius;
}
/**
*
* @return the interval angle between each items
*/
public int getIntervalAngle() {
return intervalAngle;
}
/**
* Default angle is 30
* @param intervalAngle the interval angle between each items
*/
public void setIntervalAngle(int intervalAngle) {
this.intervalAngle = intervalAngle;
}
/**
* Default is center in parent
* @return the content offset of x
*/
public int getContentOffsetX() {
return contentOffsetX;
}
/**
* Default is center in parent
* @param contentOffsetX the content offset of x
*/
public void setContentOffsetX(int contentOffsetX) {
this.contentOffsetX = contentOffsetX;
}
/**
* Default is top in parent
* @return the content offset of y
*/
public int getContentOffsetY() {
return contentOffsetY;
}
/**
* Default is top in parent
* @param contentOffsetY the content offset of y
*/
public void setContentOffsetY(int contentOffsetY) {
this.contentOffsetY = contentOffsetY;
}
/**
* Default is 0
* @return the rotate of first child
*/
public int getFirstChildRotate() {
return firstChildRotate;
}
/**
* Default is 0
* @param firstChildRotate the rotate of first child
*/
public void setFirstChildRotate(int firstChildRotate) {
this.firstChildRotate = firstChildRotate;
}
/**
* The rotate of child view in range[min,max] will be shown,default will be [-90,90]
* @param min min rotate that will be show
* @param max max rotate that will be show
*/
public void setDegreeRangeWillShow(int min,int max){
if(min > max) return;
minRemoveDegree = min;
maxRemoveDegree = max;
}
公共类Layoutmameger扩展LayoutManager{
private static int INTERVAL_ANGLE=50;//每个项目之间的默认间隔角度
专用静态浮动距离_比率=20f;//手指滑动距离除以项目旋转角度
//卷轴方向旗
私有静态int SCROLL_LEFT=1;
私有静态int SCROLL_RIGHT=2;
私人语境;
//每个项目的大小
私有国际山地公园;
私家车出租儿童;
//财产
私人内特;内特;
私人int STARTOP;
私人住宅;
私人内部视角;
private float offsetRotate;//每个项目的偏移角度将根据滚动偏移而改变
//从父级删除的范围
私人酒店;
私人int maxRemoveDegree;
//内容的初始位置
私有int contentOffsetX=-1;
私有int-contentOffsetY=-1;
private int firstChildRotate=0;
//用于记录每个项目的附着和旋转角度的稀疏数组
private SparseBooleanArray itemAttached=新SparseBooleanArray();
private SparseArray itemsRotate=新SparseArray();
公共布局管理器(上下文){
this.context=上下文;
间隔角=间隔角;
偏置=0;
minRemoveDegree=-90;
maxRemoveDegree=90;
}
@凌驾
public void onLayoutChildren(RecyclerView.RecyclerRecycler,RecyclerView.State){
如果(getItemCount()==0){
拆下和刮下附件(回收器);
偏置=0;
返回;
}
//计算孩子的大小
如果(getChildCount()==0){
查看废料=回收商。getViewForPosition(0);
addView(废料);
测量带边距的ILD(废料,0,0);
mDecoratedChildWidth=getDecoratedMeasuredWidth(废料);
mDecoratedChildHeight=getdecordementedmeasuredhight(报废);
StartEFT=contentOffsetX==-1?(getHorizontalSpace()-mDecoratedChildWidth)/2:contentOffsetX;
startTop=contentOffsetY==-1?0:contentOffsetY;
mRadius=mDecoratedChildHeight;
拆卸和报废视图(报废、回收);
}
//记录每个项目的状态
float rotate=firstChildRotate;
对于(int i=0;igetItemCount()-1)返回;
浮动目标状态=位置*间隔角;
if(targetState==offsetState)返回;
offsetRotate=targetRotate;
固定旋转偏移();
requestLayout();
}
@凌驾
公共位置(RecyclerView RecyclerView,RecyclerView.State状态,int位置){
LinearSmoothScroller smoothScroller=新的LinearSmoothScroller(上下文){
@凌驾
公共点F计算CrollVectorForPosition(int targetPosition){
返回layoutmager.this.computeScrollVectorForPosition(targetPosition);
}
};
smoothScroller.setTargetPosition(位置);
startSmoothScroll(平滑滚动器);
}
@凌驾
已更改适配器上的公共void(RecyclerView.Adapter oldAdapter、RecyclerView.Adapter newAdapter){
移除所有视图();
偏置=0;
}
@凌驾
public RecyclerView.LayoutParams GeneratedDefaultLayoutParams(){
返回新的RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_内容,ViewGroup.LayoutParams.WRAP_内容);
}
/**
*
*@return获取视图的当前位置
*/
public int getCurrentPosition(){
返回数学圆(偏置/间隔角);
}
/**
*
*@return Get应该将dx滚动到中心
*/
public int getOffsetCenterView(){
返回(int)((getCurrentPosition()*间隔角偏移量)*距离比);
}
/**
*
*@return获取圆的半径
*/
公共int getRadius(){
返回mRadius;
}
/**
*
*@param mRadius圆的半径,默认为项目的高度
*/
公共v