我想为自定义ListView
课程设置交替颜色。
代码如下:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ListView;
public class CustomListView extends ListView {
private Paint mPaint = new Paint();
private Paint mPaintBackground = new Paint();
public CustomListView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint.setColor(Color.parseColor("#1A000000"));
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
final int currentHeight = getMeasuredHeight();
final View lastChild = getChildAt(getChildCount() - 1);
if (lastChild == null)
return;
for (int i = 0; i < getChildCount(); i++) {
if (getChildCount() % 2 == 0) {
mPaintBackground.setColor(Color.WHITE);
} else {
mPaintBackground.setColor(Color.RED);
}
}
final int lastChildBottom = lastChild.getBottom();
final int lastChildHeight = lastChild.getMeasuredHeight();
final int nrOfLines = (currentHeight - lastChildBottom) / lastChildHeight;
Rect r = new Rect(0, lastChildBottom, getMeasuredWidth(), getMeasuredHeight());
canvas.drawRect(r, mPaintBackground);
canvas.drawLine(0, lastChildBottom, getMeasuredWidth(), lastChildBottom, mPaint);
for (int i = 0; i < nrOfLines; i++) {
canvas.drawLine(0, lastChildBottom + (i + 1) * lastChildHeight, getMeasuredWidth(), lastChildBottom + (i + 1) * lastChildHeight, mPaint);
}
return;
}
}
要获得ListView
的交替背景颜色,我使用了以下代码:
for (int i = 0; i < getChildCount(); i++) {
if (getChildCount() % 2 == 0) {
mPaintBackground.setColor(Color.WHITE);
} else {
mPaintBackground.setColor(Color.RED);
}
}
适配器内部:
if (position % 2 == 0) {
view.setBackgroundColor(Color.RED);
} else {
view.setBackgroundColor(Color.WHITE);
}
但它总是显示一种颜色,红色或白色,我尝试的一切。我没有交替颜色白红 - 白 - 红。
答案 0 :(得分:12)
这是失败的原因是因为你的for循环永远不会改变。你总是在检查getChildCount() % 2
。 getChildCount()
将为每次迭代返回相同的内容。您需要根据职位进行检查:
for(int i = 0; i < getChildCount(); i++){
if(i % 2 == 0){
mPaintBackground.setcolor(Color.WHITE);
} else{
mPaintBackground.setColor(Color.RED);
}
}
如果有帮助,请将您的计数器变量从i
重命名为position
,以便将来更具可读性,或者记下它以帮助自己。
我还想补充一点,鉴于你现在的代码,你的for循环不会改变任何东西。它只是遍历子项数并设置mPaintBackground
。最后,它将保留从上一次迭代中获得的任何值。
我认为处理绘制背景颜色的最佳方法是在Listview的适配器中,在这种情况下,您可以覆盖getView()并根据position
参数进行检查:
int backgroundResource;
if(position % 2 == 0){
backgroundResource = getResources.getColor(android.R.color.WHITE);
} else{
backgorundResource = getResources.getColor(android.R.color.RED);
}
view.setBackground(backgroundResource);
当然,以上只是伪代码,可能需要根据您的项目进行调整。
上述解决方案仅适用于现有数据。如果您需要交替颜色,无论是否有数据,如果我现在理解的是您在dispatchDraw
中尝试实现的目标。我会非常诚实地告诉我,我不是100%确定如何做到这一点,我无法测试它,但我想这些步骤是这样的:
请注意,您无法根据孩子的数量进行迭代,因为此时您可能没有。
伪代码:
listViewWidth = getMeasuredWidth();
listViewHeight = getMeasuredHeight();
numChildren = getChildCount();
itemHeight = getItemHeight(); // See comments above, adjust this for your problem.
currentTop = 0; // Used to keep track of the top of the rectangle we are drawing.
currentBottom = itemHeight; // Used to keep track of the bottom rectangle we are currently drawing.
int currentRectangle = 0;
while(currentBottom <= listViewHeight){
if(currentRectangle % 2 == 0){
mPaintBackground.setColor(Color.WHITE);
} else{
mPaintBackground.setColor(Color.RED);
}
Rect r = new Rect(0, currentBottom, getMeasuredWidth(), getMeasuredHeight());
canvas.drawRect(r, mPaintBackground);
// Move to next
currentTop += itemHeight;
currentBottom += itemHeight;
currentRectangle++;
}
答案 1 :(得分:11)
最后,在@ McAdam331的巨大帮助下,我得到了答案。使用他的代码后我得到了一些奇怪的东西,但在那之后我用这个修复了代码
int listViewHeight = getMeasuredHeight();
int itemHeight = lastChild.getMeasuredHeight();
int currentTop = 0;
int currentBottom = lastChild.getBottom();
int currentRectangle = 0;
while (currentBottom <= listViewHeight) {
if (currentRectangle % 2 == 0) {
mPaintBackground.setColor(Color.WHITE);
} else {
mPaintBackground.setColor(Color.parseColor("#f7f7f7"));
}
Rect r = new Rect(0, currentBottom, getMeasuredWidth(), getMeasuredHeight());
canvas.drawRect(r, mPaintBackground);
// Move to next
currentTop += itemHeight;
currentBottom += itemHeight;
currentRectangle++;
}
答案 2 :(得分:3)
逻辑上有一个小错误。 这是该部分的更新代码:
for (int i = 0; i < getChildCount(); i++) {
if (i % 2 == 0) {
view.setBackgroundColor(getResources.getColor(Color.WHITE));
} else {
view.setBackgroundColor(getResources.getColor(Color.RED));
}
}
检查应该在计数器控制变量上,getChildCount将始终返回总是看到相同颜色的项目总数。 上面粘贴的代码将解决您的问题。但是这个代码应该在你的适配器类的getView()中,因为在每一行上都会调用getView()函数进行渲染。 您当前的方法只会调用该函数一次,您将无法获得所需的结果。
答案 3 :(得分:1)
您只需创建自定义Listview
即可为Adapter
创建相同的效果:
public class MyAlternateColorAdapter extends ArrayAdapter<SomeObject> {
private Context context; //Get the Context from the constructor
...
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
if (position % 2 == 0) {
rowView.setBackgroundColor(Color.RED); // Or use rowView.setBackgroundResource(R.drawable.bg_red); where bg_red is a drawable with a selector to provide touch feedback
} else {
rowView.setBackgroundColor(Color.WHITE);
}
// Set the data of the row
...
}
}