我试图解决以下问题:
我尝试使用下面的代码,问题是它不起作用,我没有发现任何工作示例没有提到在方向改变时重新绘制。
public class AutofitRecyclerView extends RecyclerView {
private MyGridLayoutManager manager;
private int columnWidth = -1;
public AutofitRecyclerView(Context context) {
super(context);
init(context, null);
}
public AutofitRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public AutofitRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
int[] attrsArray = {
android.R.attr.columnWidth
};
TypedArray array = context.obtainStyledAttributes(attrs, attrsArray);
columnWidth = array.getDimensionPixelSize(0, -1);
array.recycle();
}
manager = new MyGridLayoutManager(getContext(), 1);
setLayoutManager(manager);
}
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
super.onMeasure(widthSpec, heightSpec);
if (columnWidth > 0) {
int mw = getMeasuredWidth();
int spanCount = Math.max(1, mw / columnWidth);
manager.setSpanCount(spanCount);
}
int numOfFullRows = manager.getItemCount() / manager.getSpanCount();
if(manager.getItemCount() % manager.getSpanCount() > 0)
{
numOfFullRows++;
}
if(getChildCount() > 0) {
int h = 0;
try {
h = manager.getChildAt(0).getMeasuredHeight();
} catch (Exception e) {
e.printStackTrace();
}
if(h != 0) {
getLayoutParams().height = numOfFullRows * h;
}
}
}
}
感谢@nantoka和@arather的代码,它给了我一个很好的开始。不幸的是,它不能很好地使用不同的spanCount,所以我在这里更新(静态编程语言):
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.Recycler
import com.baziliqo.app.bar.utils.takeIfInstance
class WrappableGridLayoutManager(context: Context?, val preferedSpanCount: Int, @RecyclerView.Orientation orientation: Int = RecyclerView.VERTICAL) :
GridLayoutManager(context, preferedSpanCount, orientation, false) {
private val mMeasuredDimension = IntArray(2)
var measuredWidth = 0
var measuredHeight = 0
override fun onMeasure(recycler: Recycler, state: RecyclerView.State, widthSpec: Int, heightSpec: Int) {
val suitableSpanCount = preferedSpanCount.coerceAtMost(itemCount)
if (spanCount != suitableSpanCount) {
spanCount = suitableSpanCount
return
}
val widthMode = View.MeasureSpec.getMode(widthSpec)
val heightMode = View.MeasureSpec.getMode(heightSpec)
val widthSize = View.MeasureSpec.getSize(widthSpec)
val heightSize = View.MeasureSpec.getSize(heightSpec)
measuredWidth = 0
measuredHeight = 0
for (i in 0 until itemCount) {
measureScrapChild(
recycler, i,
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension
)
if (orientation == HORIZONTAL) {
if (i % spanCount == 0) {
measuredWidth += mMeasuredDimension[0]
}
if (i < spanCount) {
measuredHeight += mMeasuredDimension[1]
}
} else {
if (i % spanCount == 0) {
measuredHeight += mMeasuredDimension[1]
}
if (i < spanCount) {
measuredWidth += mMeasuredDimension[0]
}
}
}
when (widthMode) {
View.MeasureSpec.EXACTLY -> measuredWidth = widthSize
View.MeasureSpec.AT_MOST, View.MeasureSpec.UNSPECIFIED -> {
}
}
when (heightMode) {
View.MeasureSpec.EXACTLY -> measuredHeight = heightSize
View.MeasureSpec.AT_MOST, View.MeasureSpec.UNSPECIFIED -> {
}
}
setMeasuredDimension(measuredWidth, measuredHeight)
}
private fun measureScrapChild(recycler: Recycler, position: Int, widthSpec: Int, heightSpec: Int, measuredDimension: IntArray) {
try {
var view = recycler.getViewForPosition(position) ?: return
val p = view.layoutParams as RecyclerView.LayoutParams
val childWidthSpec = ViewGroup.getChildMeasureSpec(
widthSpec,
paddingLeft + paddingRight, p.width
)
val childHeightSpec = ViewGroup.getChildMeasureSpec(
heightSpec,
paddingTop + paddingBottom, p.height
)
view.measure(childWidthSpec, childHeightSpec)
measuredDimension[0] = view.measuredWidth + p.leftMargin + p.rightMargin
measuredDimension[1] = view.measuredHeight + p.bottomMargin + p.topMargin
recycler.recycleView(view)
} catch (e: Exception) {
}
}
}
您需要添加一个自定义GridlayoutManager。看看这个https://gist.github.com/ArthurSav/5f80e19d9ba6d562fbd5
根据connector发布的代码,我提出了以下解决方案,该解决方案支持不同的行/列大小(尽管我承认没有进行过测试),将项目装饰的大小考虑在内,并正确处理不同的度量模式。
以下是代码:
import android.content.Context;
import android.graphics.Rect;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
public class WrappableGridLayoutManager extends GridLayoutManager {
public WrappableGridLayoutManager(Context context, int spanCount) {
super(context, spanCount);
}
private int[] measuredSize = new int[2];
@Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {
final int widthMode = View.MeasureSpec.getMode(widthSpec);
final int heightMode = View.MeasureSpec.getMode(heightSpec);
final int widthSize = View.MeasureSpec.getSize(widthSpec);
final int heightSize = View.MeasureSpec.getSize(heightSpec);
int spanWidth = 0;
int spanHeight = 0;
int viewWidth = 0;
int viewHeight = 0;
int spanCount = getSpanCount();
for (int i = 0; i < getItemCount(); i++) {
measureScrapChild(recycler, i, View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), measuredSize);
if (i % spanCount == 0) {
spanWidth = measuredSize[0];
spanHeight = measuredSize[1];
} else {
if (getOrientation() == VERTICAL) {
spanWidth += measuredSize[0];
spanHeight = Math.max(spanHeight, measuredSize[1]);
} else {
spanWidth = Math.max(spanWidth, measuredSize[0]);
spanHeight += measuredSize[1];
}
}
if (i % spanCount == spanCount - 1 || i == getItemCount() - 1) {
if (getOrientation() == VERTICAL) {
viewWidth = Math.max(viewWidth, spanWidth);
viewHeight += spanHeight;
} else {
viewWidth += spanWidth;
viewHeight = Math.max(viewHeight, spanHeight);
}
}
}
int finalWidth;
int finalHeight;
switch (widthMode) {
case View.MeasureSpec.EXACTLY:
finalWidth = widthSize;
break;
case View.MeasureSpec.AT_MOST:
finalWidth = Math.min(widthSize, viewWidth);
break;
case View.MeasureSpec.UNSPECIFIED:
finalWidth = viewWidth;
break;
default:
finalWidth = widthSize;
break;
}
switch (heightMode) {
case View.MeasureSpec.EXACTLY:
finalHeight = heightSize;
break;
case View.MeasureSpec.AT_MOST:
finalHeight = Math.min(heightSize, viewHeight);
break;
case View.MeasureSpec.UNSPECIFIED:
finalHeight = viewHeight;
break;
default:
finalHeight = heightSize;
break;
}
setMeasuredDimension(finalWidth, finalHeight);
}
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) {
View view = null;
try {
view = recycler.getViewForPosition(position);
} catch (Exception ex) {
// try - catch is needed since support library version 24
}
if (view != null) {
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, getPaddingLeft() + getPaddingRight(), p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec, getPaddingTop() + getPaddingBottom(), p.height);
view.measure(childWidthSpec, childHeightSpec);
measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
Rect decoratorRect = new Rect();
calculateItemDecorationsForChild(view, decoratorRect);
measuredDimension[0] += decoratorRect.left;
measuredDimension[0] += decoratorRect.right;
measuredDimension[1] += decoratorRect.top;
measuredDimension[1] += decoratorRect.bottom;
recycler.recycleView(view);
}
}
}
我刚刚将一个应用程序重构为一个框架库和一个应用程序,但现在当我尝试在模拟器中启动该应用程序时,我得到了以下错误堆栈跟踪: 通常这意味着清单文件在某些方面是错误的,但我已经仔细检查了我能想到的一切。 这是我的活动课: null
我想在cassandra 1.2 CQL 3.0上实现一个实时的内容排名系统 示例:根据用户投票提供新闻的前10条评论 用户可以评论新闻 用户可以对每条评论投票+1或-1 “真实例子youtube评论” 我的解决方案是: 在计数器表(content_counter)上存储投票计数器 创建排名表 null 选择core FROM content_counter where content_id='x
问题内容: 在使用Scrapy为我的问题构建完整的解决方案之前,我先发布了我想做的一个简单版本: 此代码表示上述URL不存在。该URL与XHR请求相关,当您从此页面上的主表的“总体”选项卡切换到“主页”选项卡时,将提交该XHR请求: 如果您在Google Developer Tools的控制台中激活XHR日志记录,则可以以字典的形式(期望的格式)看到XHR请求和从服务器发送的响应。 谁能告诉我为什
问题内容: 我一直试图在我的package.json文件上运行npm安装,但是遇到了很多麻烦。我一直依赖于它,一直说“错误:尝试解锁XXX,但尚未锁定”。这是其中之一: 如果我尝试将其作为sudo运行,它似乎会更进一步并开始安装一些软件包,但弹出一些新错误: 我最近更新了我的节点和npm安装。所以也许与它有关。另外,我的大部分开发工作都在办公室里,今天我正在使用VPN,所以也许与此有关。 有任何想
问题内容: 使用python模块xlwt,两次写入同一单元会引发错误: 与代码段 看起来代码“引发”了一个异常,该异常终止了整个过程。删除“筹款”一词是否足以覆盖单元格?我感谢xlwt的警告,但我认为pythonic方法是假设“我们知道我们在做什么”。在触摸模块时,我不想破坏其他任何功能。 问题答案: 问题在于,默认情况下,工作表数据的覆盖处于禁用状态。您必须明确允许它,如下所示:
我有一个雄辩的模型,它