gpt4 book ai didi

android - 带有自定义 ArrayAdapter(和 getView 回收)的 ListViewText 中用于 EditText 的 TextWatcher

转载 作者:行者123 更新时间:2023-11-29 17:47:45 28 4
gpt4 key购买 nike

我有一个带有自定义 ArrayAdapter 的 ListView,它使用 OrderedProductItems 列表(我自己的模型类)。在这个 ArrayAdapter 的 getView 中,我使用了 ViewHolder 设计模式:

@Override
public View getView(int position, View convertView, ViewGroup parent){
View view = convertView;
MyHolder h;
if(view == null){
view = inflater.inflate(layoutResourceId, parent, false);
RelativeLayout rl = (RelativeLayout) view.findViewById(R.id.item_layout);
h = new MyHolder(rl);
view.setTag(h);
}
else
h = (MyHolder) view.getTag();

if(h != null){
h.orderedProductItem = getItem(position);

... // Do stuff like:
// - setting Texts of TextViews/EditText
// - updating data of AutoCompleteTextView and Spinner
// - etc.

h.etResultPrice.setTag(h.orderedProductItem);
h.etResultPrice.addTextChangedListener(new MyTextWatcher(h.etResultPrice));
}
}

在我的 ListView 的项目中,我有一个使用自定义 TextWatcher 的 EditText。在这个 TextWatcher 中,我将用户的输入保存到我的 OrderedProductItem 类中:

public class MyTextWatcher implements TextWatcher
{
// Logcat tag
private static final String TAG = "MyTextWatcher";

// The values used for the test output of changed EditText texts
private View view;
private String from;

public MyTextWatcher(View v){
view = v;
}

// Default Android method used by TextWatcher
// (to do something before an EditText's is going to change)
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Get the old text before we make a change to this EditText
from = ((EditText)view).getText().toString();
}

// Default Android method used by TextWatcher
// (to do something when an EditText's text is changing)
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}

// Default Android method used by TextWatcher
// (to do something after an EditText's text is changed)
@Override
public void afterTextChanged(Editable s) {
if(s != null && s.toString() != null && view.getTag() != null){
OrderedProductItem opi = (OrderedProductItem)view.getTag();
if(opi != null){
// Send the changed text of this EditText to the OrderedProductItem's Result-values
if(view.getId() == R.id.et_result_amount){
int amount = 1;
try{
amount = Integer.parseInt(s.toString());
}
catch(NumberFormatException ex){
amount = 1;
}
if(opi.getResultAmount() != amount){
opi.setResultAmount(amount);
Log.i(TAG, "ResultAmount changed from " + from + " to " + s.toString() + " (-> " + String.valueOf(opi.getResultAmount()) + ")");
}
}
else if(view.getId() == R.id.actv_result_name){
if(!V.compare(opi.getResultName(), s.toString(), false, false)){
opi.setResultName(s.toString());
Log.i(TAG, "ResultName changed from " + from + " to " + s.toString() + " (-> " + opi.getResultName() + ")");
}
}
else if(view.getId() == R.id.et_result_price){
double price = C.priceStringToDouble(s.toString());
if(opi.getResultPrice() != price){
opi.setResultPrice(price);
Log.i(TAG, "ResultPrice changed from " + from + " to " + s.toString() + " (-> " + String.valueOf(opi.getResultPrice()) + ")");
}
}
}
else
Log.wtf(TAG, "Tag's OrderedProductItem is null");
}
}
}

现在我的问题是:由于 ArrayAdapter 使用 getView-recycler ( see this post for more information about getView recycling (including picture) ),我的 TextWatcher 覆盖了另一个 OrderedProductItem 的不正确数据。例如,假设我的 OrderedProductItem 的 EditTexts 在创建时是这样填充的(这里没有错):

  1. 预期“1”——实际“1”
  2. 预期“2”——实际“2”
  3. 预期“3”——实际“3”
  4. 预期“4”——实际“4”
  5. 预期“5”——实际“5”
  6. 预期“6”——实际“6”
  7. 预期“7”——实际“7”
  8. 预期“8”——实际“8”
  9. 预期的“9”——实际的“9”
  10. 预期“10”——实际“10”

现在,当我向下滚动时,会发生以下情况(仍然没有错):

  1. 预期“5”——实际“5”
  2. 预期“6”——实际“6”
  3. 预期“7”——实际“7”
  4. 预期“8”——实际“8”
  5. 预期的“9”——实际的“9”
  6. 预期“10”——实际“10”
  7. 预期“11”——实际“11”
  8. 预期“12”——实际“12”
  9. 预期“13”——实际“13”
  10. 预期“14”——实际“14”

当我向上滚动时,问题出现了:

  1. 预期为“1”——实际为“14”
  2. 预期为“2”——实际为“13”
  3. 预期为“3”——实际为“12”
  4. 预期为“4”——实际为“11”
  5. 预期“5”——实际“5”
  6. 预期“6”——实际“6”
  7. 预期“7”——实际“7”
  8. 预期“8”——实际“8”
  9. 预期的“9”——实际的“9”
  10. 预期“10”——实际“10”

我确实尝试在 getView 开始时暂时禁用 TextWatcher(在我获得 EditTexts 之后),然后设置 OrderedProductItem 的值,然后将 MyTextWatcher 重新应用到它们,但它仍然会在之后更改 OrderedProductItem 的值我重新应用了我的 TextWatcher..

有谁知道在使用 TextWatcher 保存 Item 的 EditTexts 的 UserInput 时如何处理 getView 回收?

PS:我知道我可以在 EditTexts 旁边添加一个按钮,这样它只会在单击按钮时保存数据,但我不想要这个。

最佳答案

看来您的问题出在这里:

 etResultPrice.setTag(currentOrderedProductItem);

如果您尝试删除 TextWatcher 但它仍然有问题,它引用了标签,如果您没有使用回收 View 正确重置标签,您将会遇到问题。特别是,看起来您正在尝试重置它,但没有正确执行,因为当回收 View 时,它们应该按顺序进行。这意味着当您向上滚动时,您的行:

 expected "3" -- actual "12"
expected "4" -- actual "11"
expected "5" -- actual "5"
expected "6" -- actual "6"

关于“预期的“4”——实际的“11””——你重置标签的逻辑一定是错误的,因为它应该回收“14”——所以问题不在于回收,而是你的逻辑用于执行回收。您的代码假设这是第 11 项,就像在初始滚动中一样,而不是识别它应该是第 4 项。

可能是这样的:当你创建一个 View 时,你这样做:

 view.setTag(h);

但在你的逻辑中,你也这样做:

h.etResultPrice.setTag(h.orderedProductItem);

这看起来是递归的,如果您的 View 持有者有问题,可能会不同步。

关于android - 带有自定义 ArrayAdapter(和 getView 回收)的 ListViewText 中用于 EditText 的 TextWatcher,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25242410/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com