只是一个基本问题:如果我有几十个属于ListAdapter的EditText字段,那么各个EditText字段如何知道它们属于哪一行?
目前我正在使用TextWatcher来监听文本输入。我已经尝试扩展TextWatcher,以便我可以将EditText的位置传递给TextWatcher的构造函数。
但是,当弹出软键盘时,与各种EditText字段对应的位置会随机播放。
如何将EditText字段跟踪到正确的位置?
我正在使用GridView来解决问题。每个项目的布局都是一个ImageView,下面有TextView和EditText字段。
每个EditText的文本都保存在一个名为strings的全局String数组中。它最初是空的,并由我的TextWatcher类更新。
public void initList()
{
ArrayAdapter<String> listAdapter = new ArrayAdapter<String>(this, R.layout.shape, strings)
{
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.shape, null);
}
final String theData = getItem(position);
final EditText editText = (EditText) convertView.findViewById(R.id.shape_edittext);
editText.setText(theData);
editText.addTextChangedListener(
new MyTextWatcher(position, editText)
);
ImageView image = (ImageView) convertView.findViewById(R.id.shape_image);
image.setBackgroundResource(images[position]);
TextView text = (TextView) convertView.findViewById(R.id.shape_text);
if (gameType == SHAPES_ABSTRACT)
text.setText("Seq:");
else
text.setVisibility(View.GONE);
return convertView;
}
@Override
public String getItem(int position) { return strings[position]; }
};
grid.setAdapter(listAdapter);
}
private class MyTextWatcher implements TextWatcher {
private int index;
private EditText edittext;
public MyTextWatcher(int index, EditText edittext) {
this.index = index;
this.edittext = edittext;
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
public void afterTextChanged(Editable s) { strings[index] = s.toString(); }
public void setIndex(int newindex) { index = newindex; }
}
当我点击第一个EditText(见图片)时,EditText转移到笑脸下的那个。
答案 0 :(得分:5)
如果这是一个很好的用户界面设计,请不要考虑这个问题:
public class TestList
{
public void blah()
{
ArrayAdapter<DataBucket> listAdapter = new ArrayAdapter<DataBucket>()
{
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
convertView = LayoutInflater.from(getContext()).inflate(R.layout.testlayout, null);
}
final DataBucket dataBucket = getItem(position);
final EditText editText = (EditText) convertView.findViewById(R.id.theText);
editText.setText(dataBucket.getSomeData());
editText.addTextChangedListener(new TextWatcher()
{
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2)
{
}
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
{
}
public void afterTextChanged(Editable editable)
{
dataBucket.setSomeData(editable.toString());
}
});
return convertView;
}
};
}
public static class DataBucket
{
private String someData;
public String getSomeData()
{
return someData;
}
public void setSomeData(String someData)
{
this.someData = someData;
}
}
}
'DataBucket'是一个占位符。您需要使用您创建的任何类来存储在编辑文本中放入和编辑的数据。 TextWatcher将引用引用的数据对象。滚动时,编辑文本框应使用当前数据更新,并应保存文本更改。您可能希望跟踪用户更改了哪些对象,以提高数据/网络更新效率。
*编辑*
使用int位置而不是直接引用对象:
ArrayAdapter<DataBucket> listAdapter = new ArrayAdapter<DataBucket>()
{
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
convertView = LayoutInflater.from(getContext()).inflate(R.layout.testlayout, null);
}
final DataBucket dataBucket = getItem(position);
final EditText editText = (EditText) convertView.findViewById(R.id.theText);
editText.setText(dataBucket.getSomeData());
editText.addTextChangedListener(new TextWatcher()
{
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2)
{
}
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
{
}
public void afterTextChanged(Editable editable)
{
getItem(position).setSomeData(editable.toString());
}
});
return convertView;
}
};
*再次编辑*
我觉得有必要为后代说,我实际上不会这样编码。我猜你想要一个比String数组更结构化的数据,并且你在外面维护String数组,以及一个ArrayAdapter,所以它是一种奇怪的并行情况。但是,这样可以正常工作。
我将数据放在单个String数组中而不是多维数组中。原因是支持GridView的数据模型只是一个简单的列表。这可能违反直觉,但事实就是如此。 GridView应该自行进行布局,如果留给自己的设备,将使用可变数量的单元格填充行,具体取决于您拥有的数据量和屏幕的宽度(AFAIK)。
足够的聊天。代码:
public class TestList extends Activity
{
private String[] guess;
//Other methods in here, onCreate, etc
//Call me from somewhere else. Probably onCreate.
public void initList()
{
ArrayAdapter<String> listAdapter = new ArrayAdapter<String>(this, /*some resourse id*/, guess)
{
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
convertView = LayoutInflater.from(getContext()).inflate(R.layout.testlayout, null);
}
final String theData = getItem(position);
final EditText editText = (EditText) convertView.findViewById(R.id.theText);
editText.setText(theData);
editText.addTextChangedListener(
new MyTextWatcher(position)
);
return convertView;
}
};
gridView.setAdapter(listAdapter);
}
class MyTextWatcher extends TextWatcher {
private int position;
public MyTextWatcher(int position) {
this.position = position;
}
public void afterTextChanged(Editable s) {
guess[position] = s.toString();
}
// other methods are created, but empty
}
}
答案 1 :(得分:3)
要跟踪行号,EditText
中的每个听众都必须保留对列表中某个项的引用,并使用getPosition(item)
获取ListView
中的位置。我的示例使用Button
,但我认为它可以应用于EditText
。
class DoubleAdapter extends ArrayAdapter<Double> {
public DoubleAdapter(Context context, List<Double> list) {
super(context, android.R.layout.simple_list_item_1, list);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_row, null);
}
// keep a reference to an item in a list
final Double d = getItem(position);
TextView lblId = (TextView) convertView.findViewById(R.id.lblId);
lblId.setText(d.toString());
Button button1 = (Button) convertView.findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// the button listener has a reference to an item in the list
// so it can know its position in the ListView
int i = getPosition(d);
Toast.makeText(getContext(), "" + i, Toast.LENGTH_LONG).show();
remove(d);
}
});
return convertView;
}
}
答案 2 :(得分:1)
可能值得考虑是否需要将编辑文本存储在列表单元格中?当用户一次只编辑一个时,似乎有点不必要。
虽然我不知道您的应用是如何设计的,但我建议您稍微重新考虑一下您的用户体验,以便在按下列表项时会出现单个文本编辑,供他们编辑。这样您就可以像往常一样使用列表适配器获取列表项引用,在用户编辑时存储它并在完成后更新它。
答案 3 :(得分:1)
我不确定这是否是一个很好的设计,因为一旦滚动列表视图,EditText内容很有可能出现问题(洗牌内容,缺少文本)。考虑尝试m6tt的想法。
但如果您真的想按照自己的方式行事,可以发布一些代码,特别是TextWatcher吗?
答案 4 :(得分:0)
我试图解决这个问题,因为你可以看到有一个简单的方法 - 我在这里发布答案,因为它可能对某人有用。
列表视图无法获取位置 - &gt;编辑文本有一个文本观察者。
这是对我有用的解决方案:
在获取视图中 -
当我添加文本观察者监听器来编辑文本时,我还添加了以下行
edittext.setTag(R.id.position<any unique string identitiy>, position)
在你的afterTextChanged -
中 int position = edittext.getTag(R.id.position)
提供正确的位置编号,您可以根据位置编号进行修改。