【问题标题】:The views are crazy, I use ListView. And all views change视图很疯狂,我使用 ListView。所有的观点都会改变
【发布时间】:2018-01-02 17:23:28
【问题描述】:

我有一个代码,每个视图都有不同的背景 当我向上和向下滚动时,所有颜色都会混淆,所有CheckBoxes 标记都会发生变化,当我擦除一部分时,会擦除其他部分并改变颜色。

如果你需要完整的代码,请告诉我

这是更改背景颜色的代码:

View v = List.getChildAt(index -
            List.getFirstVisiblePosition());

    if(v == null)
        return;
    ConstraintLayout LayoutT = v.findViewById(R.id.LayoutT);
    LayoutT.setBackgroundColor(Color.RED);

这个删除代码:

 CheckBox currentCheckBox = (CheckBox) view.findViewById(mCheckBoxView);
    currentCheckBox.setChecked(mCheckBoxStates[csr.getPosition()]);
    currentCheckBox.setTag(new Long(csr.getLong(csr.getColumnIndex(DatabaseHandler.KEY_ID))));

    currentCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        final int position = fcsr.getPosition();
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            mCheckBoxStates[position] = ((CheckBox) buttonView).isChecked();
            int restore_cursor_position = fcsr.getPosition();
            fcsr.moveToPosition(position);
            fcsr.moveToPosition(restore_cursor_position); //restore the Cursor's position
        }
    }); 
      another class:
 for (long id : mCheckedIdList) {

                mDBHandler.deleteRecord(id);

            }
            db.beginTransaction();
            db.setTransactionSuccessful();
            db.endTransaction();

            mCsr = mDBHandler.getAllRecords();
            mMCA.swapCursor(mCsr);

编辑

我试着按照你最初的建议去做。它工作得很好,但是当我将它调整为我的代码时,只出现一种颜色,它会根据最后一种颜色或应该出现的第一种颜色而变化

 @Override
public View getView(int position, View view, ViewGroup parent) {
    View convertview = super.getView(position, view,parent);

    parent.setBackgroundColor(0xFF555555);
  //  LinearLayout ll = (LinearLayout) 
 convertview.findViewById(R.id.item_layout);

    int[] colours = new int[]{ 
            ContextCompat.getColor(mContext, R.color.Cyan)
  ,    ContextCompat.getColor(mContext, R.color.LowRed)
  };
    if (convertview != null) {
        DatabaseHandler db = new DatabaseHandler(mContext);
        int Count = List.getCount();
        String[] Status = new String[Count];

        for (int i = 0; i < Count; ) {
            Cursor c = db.getCursorStatus(i);
            if (c != null) {
                while (c.moveToNext()) {
                    Status[i] = c.getString(0);

                }
            }

            String mStatus[] = new String[3];
        mStatus[0] = "Monetary_Expenditure";
        mStatus[1] = "Financial income";
        mStatus[2] = "Cancellation";


        boolean first = Status[i] != null && Status[i].equals(mStatus[1]);
        boolean second = Status[i] != null && Status[i].equals(mStatus[0]);

        if (Status[i] != null && Status[i].equals(mStatus[1])) {
            convertview.setBackgroundColor(colours[1]);
        } else if (Status[i] != null && Status[i].equals(mStatus[0])) {
            convertview.setBackgroundColor(colours[0]);
        }
        else {convertview.setBackgroundColor(0xFF555555);}

        i++;
    }
   }
    return convertview;
  }

编辑 2

我改了:

 if (convertview != null) {
    Cursor csr = getCursor(); 
    String status = csr.getString(0);
    int colourindex = 0;
    if (status.equals("Financial income") {
        colourindex = 1;
    }
    if (status.equals("Cancellation") {
        colourindex = 2;
    }
    convertview.setBackgroundColor(colours[colourindex]);       
}

到:

       if (convertview != null) {
        Cursor csrF = getCursor();

        DatabaseHandler db = new DatabaseHandler(mContext);
         i++;
        Cursor csr = db.getCursorStatus(i);
        String status = csr.getString(0);
        int colourindex = 0;
        if (status.equals("Financial income")) {
            colourindex = 1;
        }
        if (status.equals("Cancellation")) {
            colourindex = 2;
        }
        convertview.setBackgroundColor(colours[colourindex]);
 }

因为光标没有转到右行

我得到这个错误:android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1

编辑 3

 Cursor csr = getCursor();
        String status="";
        while (csr.moveToNext()) {
            status = csr.getString(4);
        }
        int colourindex = 3;
        if ("Monetary Expenditure".equals(status)){
        colourindex = 0;
        }
        else if ("Financial income".equals(status)) {
            colourindex = 1;
        }
        else if ("Cancellation".equals(status)) {
            colourindex = 2;
        }
        convertview.setBackgroundColor(colours[colourindex]);
        Log.i("Debug", "colour index is: "+colourindex);

【问题讨论】:

  • 列表视图旨在重复自身。为每一行创建一个全新的视图会占用系统太多的内存。话虽如此,你想完成什么?
  • 我想用相同的设计制作 X 布局(布局数组):5 TextField 1 和 Checkbox 和背景颜色 X。现在我想创建其中一些布局并将每个信息放在不同但每个人的背景颜色会有所不同。抱歉,如果我没有正确解释自己。

标签: android listview


【解决方案1】:

在您的自定义适配器中覆盖 getView() 方法并在该方法中设置颜色。

签名是:-public View getView(int position, View view, ViewGroup parent)

  • position 是正在处理的视图列表中的位置。
  • view 是视图(布局)
  • 父级是ListView
  • 应该返回修改后的视图。

一个改变背景颜色的例子(每 x 行是不同的颜色,其中 x 是颜色的数量):-

@Override
public View getView(int position, View view, ViewGroup parent) {
    View convertview = super.getView(position, view,parent);

    parent.setBackgroundColor(0xFF555555);
    //LinearLayout ll = (LinearLayout) convertview.findViewById(R.id.item_layout);

    int[] colours = new int[]{0xFFFF55FF,0xBBFF55FF,0x77FF55FF};
    if (convertview != null) {
        convertview.setBackgroundColor(colours[position % colours.length]);
        //ll.setBackgroundColor(colours[position % colours.length]);
    }
    return convertview;
}
  • parent.setBackgroundColor(0xFF555555); 设置 ListView 的背景颜色(深灰色)。
  • 注释掉的行是获取布局的替代方法,但不是必需的
  • 在此示例中,颜色相同,但透明度增加,因此可以显示背景(ListView/父级)颜色。

结果(根据您上一个问题的答案中提供的代码的修改):-

您可以交替覆盖bindView 方法,因为它已将视图传递给它,尽管它没有传递位置。您也可以将两者结合使用。


另一个操作 ListView 颜色的例子

这是一个完整的自定义光标适配器,它使用从数据库中提取的用户定义颜色,使用bindView 为每个项目相应地着色。但是,这会改变可绘制对象的背景颜色。它用于信用卡管理(工作仍在进行中),因此 ListView 中的每个项目看起来都像一张信用卡。 :-

public class CardListViewCursorAdapter extends CursorAdapter {

    Context mContext;
    Cursor mCurssor;

    CardListViewCursorAdapter(Context context, Cursor csr) {
        super(context, csr, 0);
        mContext = context;

    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return super.getView(position, convertView, parent);

    }

    @Override
    public View newView(Context context, Cursor csr, ViewGroup viewGroup) {

        return LayoutInflater.from(context).inflate(
                R.layout.standard_cards_listview,
                viewGroup,
                false
        );
    }


    @Override
    public void bindView(View view, Context context, Cursor csr) {

        TextView mCardName = view.findViewById(R.id.scl_cardname);
        TextView mCardNotes = view.findViewById(R.id.scl_cardnotes);
        LinearLayout mCardLayout = view.findViewById(R.id.scl_cardlayout);
        Drawable mDrawable = mCardLayout.getBackground();

        int cardcolour = (int) CardManageActivity.DEFAULT_CARDCOLOUR;

        long extracted_cardcolour = csr.getLong(
                csr.getColumnIndex(
                        DBCardsTableConstants.CARDCOLOUR.getDBColumnName()
                )
        );
        if ((extracted_cardcolour & DBCardsTableConstants.CARDSCOLOUR_FLAG) > 0) {
            cardcolour = (int) extracted_cardcolour;
        }

        setShapeBackGroundColour(mDrawable, cardcolour);

        mCardName.setText(
                csr.getString(
                        csr.getColumnIndex(
                                DBCardsTableConstants.CARDNAME.getDBColumnName())
                )
        );
        mCardNotes.setText(
                csr.getString(
                        csr.getColumnIndex(
                                DBCardsTableConstants.CARDNOTES.getDBColumnName()
                        )
                )
        );
    }

    private void setShapeBackGroundColour(Drawable drawable, int colour) {
        if (drawable instanceof ShapeDrawable) {
            ShapeDrawable sd = (ShapeDrawable) drawable;
            sd.getPaint().setColor(colour);
        }
        if (drawable instanceof GradientDrawable) {
            GradientDrawable gd = (GradientDrawable) drawable;
            gd.setColor(colour);
        }
        if (drawable instanceof ColorDrawable) {
            ColorDrawable cd = (ColorDrawable) drawable;
            cd.setColor(colour);
        }
    }
}

这看起来像:-

回答:-

我按照你的说法编辑了代码我试图按照你的建议去做 第一的。它工作得很好但是当我将它调整为我的代码时 只出现一种颜色,它会根据最后一种颜色或 第一个应该出现的为什么我尝试的是问题?和 非常感谢你所做的一切

我相信您的问题是在getView 内(对列表中的每个项目单独调用(如bindView)视图是列表中该位置的视图)您是循环所有项目/视图,基本上将所有项目更改为最后一项。

即对于 10 个项目的列表,getView 将被调用(至少)10 次。每次调用它都是针对正在处理的单个视图/项目。

我相信你需要改变:-

if (convertview != null) {
        DatabaseHandler db = new DatabaseHandler(mContext);
        int Count = List.getCount();
        String[] Status = new String[Count];

        for (int i = 0; i < Count; ) {
            Cursor c = db.getCursorStatus(i);
            if (c != null) {
                while (c.moveToNext()) {
                    Status[i] = c.getString(0);

                }
            }

            String mStatus[] = new String[3];
        mStatus[0] = "Monetary_Expenditure";
        mStatus[1] = "Financial income";
        mStatus[2] = "Cancellation";


        boolean first = Status[i] != null && Status[i].equals(mStatus[1]);
        boolean second = Status[i] != null && Status[i].equals(mStatus[0]);

        if (Status[i] != null && Status[i].equals(mStatus[1])) {
            convertview.setBackgroundColor(colours[1]);
        } else if (Status[i] != null && Status[i].equals(mStatus[0])) {
            convertview.setBackgroundColor(colours[0]);
        }
        else {convertview.setBackgroundColor(0xFF555555);}

        i++;
    }
   }

到:-

    if (convertview != null) {
        Cursor csr = getCursor(); 
        String status = csr.getString(0);
        int colourindex = 0;
        if (status.equals("Financial income") {
            colourindex = 1;
        }
        if (status.equals("Cancellation") {
            colourindex = 2;
        }
        convertview.setBackgroundColor(colours[colourindex]);       
    }
  • 因此您使用 CursorAdapters getCursor() 方法获取光标,光标将相应定位。
  • 然后您提取列表中正在为其构建视图的项目的状态,即为 列表中的每个项目调用getView()。因此,如果列表中有 10 个项目,getView() 至少会被调用 10 次。您似乎认为它只被调用一次。
  • 颜色索引(0,1 或 2)根据状态(第 0 列)确定。
  • 背景颜色根据列表中特定项目的状态设置。

【讨论】:

  • 我按照您的说法编辑了代码,我尝试按照您最初的建议进行操作。它工作得很好,但是当我将它调整为我的代码时,只出现一种颜色,它会根据最后一种颜色或应该出现的第一种颜色而变化 为什么我尝试的是问题?非常感谢你所做的一切
  • @MenachemYarhi 我已经编辑了答案(虽然我没有测试过,所以可能会有奇怪的打字错误)
  • @MenachemYarhi 您需要添加第三种颜色或修改代码,使 colourindex 只能为 0 或 1,否则 *取消 状态将因索引数组错误而失败。
  • thanx,我编辑帖子因为我收到此错误:android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
  • 你没有像我说的那样改变代码。删除您添加的三行。除非 status 不在列表的光标中。在这种情况下,您需要获取正在处理的行的 status ,即您将提取可以传递给 getCursorStatus() 方法的列(但是这应该是一个返回状态的方法不是一个游标,如果游标需要在尝试从中获取数据之前定位该游标)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
  • 1970-01-01
  • 1970-01-01
  • 2010-11-06
  • 2011-11-08
相关资源
最近更新 更多