嗨,我是Android新手,并试图熟悉ListView
。所以我决定为用户编写一个简单的程序来输入引号并按顺序显示它们。我实施StringAdapter
并在每次用户确认时调用notifyDataSetChanged
。
奇怪的是,ListView
有时会更新最旧的引号,有时会更新较新的引号。我不知道这个问题。
请忽略view data
按钮。在这种状态下,我输入了四个引号:
(以相反的顺序,按时间顺序表示,它为4,3,2,1)
public class storage extends AppCompatActivity {
// the adapter
private StringAdapter sa;
// the edit text view
public EditText etString,etSignature;
// the list view
public ListView lv;
// the array list to capture the quotes and signature
private ArrayList<String[]> dataString = new ArrayList<String[]>();
// add the string and notify
public void addString(String[] s){
this.dataString.add(0,s);
((BaseAdapter)this.lv.getAdapter()).notifyDataSetChanged();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_storage);
// Link the view elements
this.etString = (EditText) findViewById(R.id.etInput);
this.etSignature = (EditText) findViewById(R.id.etSignature);
this.lv = (ListView) findViewById(R.id.stringList);
Button btn_confirm = (Button) findViewById(R.id.btnConfirm),
btn_viewData = (Button) findViewById(R.id.btnViewData);
// load the adapter
this.sa = new StringAdapter(this,this.dataString);
lv.setAdapter(sa);
btn_confirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
storage s = (storage) v.getContext();
// get the String
String sString = s.etString.getText().toString(),
sSignature = s.etSignature.getText().toString();
System.out.println("Quotes: " + sString + "\nSignature:" + sSignature);
// verify it is not empty
if (!sString.isEmpty()&&!sSignature.isEmpty()) {
// add new string and notify
s.addString(new String[]{s.etString.getText().toString(),
s.etSignature.getText().toString()});
((StringAdapter) s.lv.getAdapter()).print_stringData();
// prompt the result
Toast.makeText(s.getBaseContext(),
"Enter Quotes from"+etSignature.getText().toString(),Toast.LENGTH_SHORT).show();
} else {
// prompt the result
Toast.makeText(s.getBaseContext(),
"Please Enter Quotes and Signatures!",Toast.LENGTH_SHORT).show();
}
}
});
}
}
public class StringAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<String[]> dataStrings = new ArrayList<String[]>();
public StringAdapter(Context c,ArrayList<String[]> dataStrings){this.mContext=c;this.dataStrings=dataStrings;}
public int getCount(){return this.dataStrings.size();}
public Object getItem(int position){ return this.dataStrings.get(position);}
public long getItemId(int postion){ return (long) postion;}
public void print_stringData(){
System.out.println("String Adapter Output:");
for(String [] s: this.dataStrings){
System.out.println("Quotes: "+s[0]+"\nSignature:"+s[1]);
}
}
public View getView(int position, View convertView, ViewGroup parent){
LinearLayout ll;
if(convertView == null){
// set the linear layout
ll = new LinearLayout(this.mContext);
ll.setOrientation(LinearLayout.VERTICAL);
ll.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
// get the data and set the text inside
String[] data = this.dataStrings.get(position);
TextView //tvNo = new TextView(this.mContext),
tvString = new TextView(this.mContext),
tvSignature = new TextView(this.mContext);
ll.addView(tvString);
ll.addView(tvSignature);
tvString.setText(data[0]);
tvString.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
tvSignature.setText(data[1]);
tvSignature.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
tvSignature.setGravity(Gravity.RIGHT);
}
else{
ll = (LinearLayout) convertView;
}
return ll;
}
}
有些人可能会注意到我总是将String[]
添加到第一个元素。实际上我试图添加到最后一个。奇怪的行为仍然存在。
Android SDK版本:API 23棒棒糖
仿真器版本:Nexus S API 23
答案 0 :(得分:1)
是的,当然,你得到了这个错误。为什么?由于ListView
始终会在convertView
getView
函数中重复使用Adapter
。
看看你的if,else
:
else{
ll = (LinearLayout) convertView;
}
return ll;
在此块中,您告诉adapter
重用convertView
,但您不会重新设置数据。结果,它将显示前一行的数据。
如何解决?只需在else
块中设置数据,就像在if
块中一样。
P / s:你应该学习如何在ViewHolder
中使用ListView
来避免在滚动时出现滞后现象。