Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/183.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 即使没有数据,ListView类的备用背景色_Android_Listview - Fatal编程技术网

Android 即使没有数据,ListView类的备用背景色

Android 即使没有数据,ListView类的备用背景色,android,listview,Android,Listview,我想为我的自定义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; im

我想为我的自定义
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;
    }
    }
适配器内部:

    if (position % 2 == 0) {
        view.setBackgroundColor(Color.RED);
    } else {
        view.setBackgroundColor(Color.WHITE);
    }

但它总是显示一种颜色,红色或白色与我尝试的一切。我没有得到交替颜色的白-红-白-红。

失败的原因是因为for循环从未改变。您总是在检查
getChildCount()%2
getChildCount()
将为每次迭代返回相同的值。您需要根据职位进行检查:

for(int i = 0; i < getChildCount(); i++){
   if(i % 2 == 0){
      mPaintBackground.setcolor(Color.WHITE);
   } else{
      mPaintBackground.setColor(Color.RED);
   }
}
当然,以上只是伪代码,可能需要根据您的项目进行调整


上述解决方案仅适用于现有数据。如果无论是否有数据,您都需要交替颜色,如果我现在理解的话,这就是您在
dispatchDraw
中试图实现的。我会非常诚实地说,我不是100%确定如何做到这一点,我不能测试它,但我想象的步骤如下:

  • 获取ListView的高度
  • 获取ListView的宽度
  • 获取一个子项的高度(如果使用listPreferredItemHeight,则为listPreferredItemHeight。如果使用wrap content,则可能更复杂,因为您无法预测项目的大小,因此很难为空ListView交替颜色)
  • 当ListView中还有空间时,绘制一个矩形
请注意,不能基于子项的数量进行迭代,因为此时可能没有子项

伪代码:

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++;
}
listViewWidth=getMeasuredWidth();
listViewHeight=getMeasuredHeight();
numChildren=getChildCount();
itemHeight=getItemHeight();//请参阅上面的评论,根据您的问题调整此选项。
currentTop=0;//用于跟踪我们正在绘制的矩形的顶部。
currentBottom=itemHeight;//用于跟踪当前正在绘制的底部矩形。
int currentRectangle=0;

而(currentBottom逻辑中有一个小错误。 以下是该部分的更新代码:

for (int i = 0; i < getChildCount(); i++) {
        if (i % 2 == 0) {
            view.setBackgroundColor(getResources.getColor(Color.WHITE));
        } else {
            view.setBackgroundColor(getResources.getColor(Color.RED));
        }
    }
for(int i=0;i
检查应该在计数器控制变量上,getChildCount将始终返回项目的总数,这就是为什么您总是看到相同的颜色。 上面粘贴的代码将解决您的问题。但是,对于适配器类,此代码应该在getView()中,因为在渲染时会对每一行调用getView()函数。
您当前的方法只需调用一次函数,将无法获得所需的结果。

您只需创建一个自定义的
适配器即可为
列表视图创建相同的效果:

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
        ...
    }
}
公共类MyAlternateColorAdapter扩展了ArrayAdapter{
私有上下文;//从构造函数获取上下文
...
@凌驾
公共视图getView(int位置、视图转换视图、视图组父级){
LayoutFlater充气器=(LayoutFlater)context.getSystemService(context.LAYOUT\u充气器\u服务);
视图行视图=充气机。充气(R.layout.rowlayout,父级,false);
如果(位置%2==0){
rowView.setBackgroundColor(Color.RED);//或使用rowView.setBackgroundResource(R.drawable.bg_RED);其中bg_RED是可绘制的,带有选择器以提供触摸反馈
}否则{
rowView.setBackgroundColor(颜色:白色);
}
//设置行的数据
...
}
}

在@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++;
        }
int-listViewHeight=getMeasuredHeight();
int itemHeight=lastChild.getMeasuredHeight();
int currentTop=0;
int currentbooth=lastChild.getBottom();
int currentRectangle=0;

while(currentBottom)感谢您的快速响应。但是如果我使用它,它将只显示白色。@PiyushGupta您在哪一行绘制背景?在您拥有的代码中,它看起来像是您经过并迭代了
getChildCount()
但除了设置绘制背景颜色外,不要做任何事情,该颜色将保留在上次迭代时给定的任何值。也许当您在适配器中调用
getView()
时,您可以基于
位置进行检查:,android.view.view,android.view.ViewGroup)是的,我正在用position检查它。但至少如果数据可能是空的,那么listView将显示为一个带有交替的白-红bg颜色。但是它没有显示!@PiyushGupta您的listView有适配器类吗?您也可以共享适配器代码吗?好的。谢谢您的努力。让我检查一下。我会返回给您!!我已经更新了答案。此代码段应位于getView()中您当前的代码段与listview小部件相关,但您真正想要的是对listview行的自定义。您使用了错误的方法来实现结果。dispatchDraw方法只调用一次。您应该使用getView方法来实现这种行为,这种行为对每个项都会调用。@faizan建议他是正确的解决方案啊。真的吗?那该怎么办?请看完整的注释。@SAIR你检查了我编辑的问题了吗?我也发布了我的适配器代码。!适配器代码只有在有数据时才有效。如果你想在没有数据的情况下为整个ListView替换颜色,则必须在dispatchDraw中完成。我正在尝试编辑现在是我的答案。很高兴你能做到这一点,我更新了我的答案,以反映正确的
Rect()
构造函数。
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
        ...
    }
}
        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++;
        }