android - ListView with ViewHolder,TextViews改变内容

标签 android listview android-listview

我有一个带有自定义 CursorAdapterListView。在那里我有这个:

if (Main.distance_unit.equals(Main.miValue)) {
                //[...] some code here which converts units

                holder.mi.setText(mileageResult + " " + Main.distance_unit);
            } else if (Main.distance_unit.equals(Main.km)) {
                holder.mi.append(" " + Main.distance_unit);
            }

现在的问题是,当我第一次打开 ListView fragment 时,一切都很好,但是当再次向下和向上滚动时,单位消失了。我认为这是由 ViewHolder 引起的吗?我该如何解决这个问题?

Before scrolling

After scrolling

完整代码,其中可能有几行愚蠢的代码。欢迎您提出更好的方法来完成这些事情:

public MyCursorAdapter(Context context, Cursor c, String[] from, int[] to) {
        //noinspection deprecation
        super(context, R.layout.activity_db_row, c, from, to);

        mCursor = c;
        ctx = context;
        mInflater = LayoutInflater.from(ctx);
    }

    @Override
    public View getView(int position, View v, ViewGroup parent) {
        super.getView(position, v, parent);
        mCursor.moveToPosition(position);
        ViewHolder holder = new ViewHolder();

        if (v == null) {
            mInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = mInflater.inflate(R.layout.activity_db_row, parent, false);
            //noinspection deprecation
            v.setBackgroundDrawable(null);

            DecimalFormatSymbols dfs = new DecimalFormatSymbols();
            dfs.setDecimalSeparator('.');
            decimalFormat.setDecimalFormatSymbols(dfs);
            decimalFormatGal.setDecimalFormatSymbols(dfs);

            holder.price = (RobotoTextView) v.findViewById(R.id.lv_tprice_unit);
            holder.price.setText(Main.money_unit);

            holder.lprice = (RobotoTextView) v.findViewById(R.id.lv_lprice_unit);
            holder.lprice.setText(Main.money_unit + "/" + Main.amount_unit);

            holder.amount_unit = (RobotoTextView) v.findViewById(R.id.lv_amount_unit);
            if (Main.amount_unit.equals(Main.galValueImp)) {
                holder.amount_unit.setText(Main.galValue);
            } else holder.amount_unit.setText(Main.amount_unit);

            bindView(v, ctx, mCursor);

            holder.am = (RobotoTextView) v.findViewById(R.id.lv_amount);
            String amount = holder.am.getText().toString();
            holder.am.setText(String.valueOf(decimalFormatGal.format(Double.parseDouble(amount))));

            holder.mi = (RobotoTextView) v.findViewById(R.id.lv_mileage);
            String mileage = holder.mi.getText().toString();

            holder.tp = (RobotoTextView) v.findViewById(R.id.lv_tprice);
            String tprice = holder.tp.getText().toString();
            holder.tp.setText(String.valueOf(decimalFormat.format(Double.parseDouble(tprice))));

            holder.lp = (RobotoTextView) v.findViewById(R.id.lv_lprice);

            holder.d = (RobotoTextView) v.findViewById(R.id.lv_date);

            holder.fuel = (RobotoTextView) v.findViewById(R.id.lv_fueltype);
            String fueltype = holder.fuel.getText().toString();

            if(fueltype.equals("null") || fueltype.length() == 0) {
                holder.fuel.setText("");

                //ToDo: Remove at some point
            }

            String amountResult;
            if (Main.amount_unit.equals(Main.galValue)) {
                BigDecimal amountTmp, toGal, resultTmp;
                double amountDouble = Double.parseDouble(amount);
                amountTmp = BigDecimal.valueOf(amountDouble);
                toGal = BigDecimal.valueOf(DbAdapter.toGal);

                resultTmp = amountTmp.multiply(toGal).setScale(2,
                        RoundingMode.HALF_UP);
                amountResult = resultTmp.toString();

                holder.am.setText(String.valueOf(decimalFormat.format(Double.parseDouble(amountResult))));

            }

            if (Main.amount_unit.equals(Main.galValueImp)) {
                BigDecimal amountTmp, toImpGal, resultTmp;
                double amountDouble = Double.parseDouble(amount);
                amountTmp = BigDecimal.valueOf(amountDouble);
                toImpGal = BigDecimal.valueOf(DbAdapter.toImpGal);

                resultTmp = amountTmp.multiply(toImpGal).setScale(2,
                        RoundingMode.HALF_UP);
                amountResult = resultTmp.toString();

                holder.am.setText(String.valueOf(decimalFormat.format(Double.parseDouble(amountResult))));

            }

            if (Main.distance_unit.equals(Main.miValue)) {
                BigDecimal mileageTmp, toMi, resultTmp;

                double mileageDouble = Double.parseDouble(mileage);
                mileageTmp = BigDecimal.valueOf(mileageDouble);
                toMi = BigDecimal.valueOf(DbAdapter.toMi);

                resultTmp = mileageTmp.multiply(toMi).setScale(2,
                        RoundingMode.HALF_UP);
                String mileageResult = resultTmp.toString();

                holder.mi.setText(mileageResult + " " + Main.distance_unit);
            } else if (Main.distance_unit.equals(Main.km)) {
                holder.mi.append(" " + Main.distance_unit);
            }



            v.setTag(holder);
        } else holder = (ViewHolder) v.getTag();
        return v;

    }

    public static class ViewHolder {
        RobotoTextView price;
        RobotoTextView lprice;
        RobotoTextView amount_unit;
        RobotoTextView am;
        RobotoTextView mi;
        RobotoTextView tp;
        RobotoTextView lp;
        RobotoTextView d;
        RobotoTextView fuel;
    }

最佳答案

在此处查看示例模式:

@Override
public View getView(int position, View v, ViewGroup parent) {
    mCursor.moveToPosition(position);

    if (v == null) {
        /* inflate your view if "v" is null */
        mInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = mInflater.inflate(R.layout.activity_db_row, parent, false);            

        /* hold the reference of your view through ViewHolder */
        ViewHolder holder = new ViewHolder();
        holder.price = (RobotoTextView) v.findViewById(R.id.lv_tprice_unit);

        ......

       /* set view tag */
       v.setTag(holder);
    }

   /* This is where you should update your view state values */
   ViewHolder holder = (ViewHolder) v.getTag();

   DecimalFormatSymbols dfs = new DecimalFormatSymbols();
   dfs.setDecimalSeparator('.');
   decimalFormat.setDecimalFormatSymbols(dfs);

   holder.price.setText(Main.money_unit); 

   ..... update view's 
  return v;

您的示例代码 fragment 发生了什么。在 ListView 的第一次迭代中。你的代码 snipper 工作正常 因为 View 基本上还没有被回收。关于你的问题。这是 View 得到回收。 导致 from if (v == null) 不会被执行,因为 View 可能已经被回收。这就是为什么你的观点 状态属性未更新。

关于android - ListView with ViewHolder,TextViews改变内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20843796/

相关文章:

java - Android 简单适配器在 ListView 中显示

Android:在 RelativeLayout 中调整大小

java - Android 在同一布局 xml 上有一个表格和按钮

android - 由 : java. lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord 引起

android - 将文件名的 ArrayList 转换为 Android 资源

android - "Unable to open log device '/dev/log/main ': No such file or directory"

android - 获取构建错误 : `duplicate entry: javax/annotation/CheckForNull.class`

asp.net-mvc - 如何将第一个项目设置为在 ListView kendoui中选择

android - 按下按钮更改 ListView 背景颜色

android ListView 或 ScrollView : for a form with dynamic number of fields