每次刷新(使用chrisbanes库)时,我的ListView都会将所有“新”数据附加到旧数据的末尾,而不是替换它。我已经检查了我的Json解析器,它返回了我的ArrayList,它肯定是 NOT ,我不小心在列表本身加倍。
我尝试了各种各样的“notifyDataSetChanged()”和“.invalidate()”,我似乎无法说服我的ListView完全重新填充自己。它在方向转换上正常工作,我意识到这是一个线索,但我似乎无法弄清楚在这种情况下有什么不同。
下面的代码,感谢任何提示!
public class VoicemailsPME extends Activity{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.voicemails_pme);
listView = (PullToRefreshListView) findViewById(R.id.pulllist);
final String username = getIntent().getExtras().getString("username");
final String password = getIntent().getExtras().getString("password");
mailboxId = getIntent().getExtras().getString("mailboxId");
m_voicemails = new ArrayList<Voicemail>();
mHandlerFirst.post(new Runnable() {
@Override
public void run() {
CheckConnectionTask CCT = new CheckConnectionTask(VoicemailsPME.this);
CCT.execute(username, password);
firstTime = false;
}
});
listView.setOnRefreshListener(new OnRefreshListener<ListView>() {
@Override
public void onRefresh(PullToRefreshBase<ListView> lv) {
lv.invalidate();
mHandler.post(new Runnable() {
@Override
public void run() {
CheckConnectionTask CCT = new CheckConnectionTask(VoicemailsPME.this);
CCT.execute(username, password);
}
});
}
});
this.m_adapter = new OrderAdapter(this, R.layout.voicemails_pme_row, m_voicemails);
listView.setAdapter(m_adapter);
}
private Runnable returnRes = new Runnable() {
@Override
public void run() {
if(m_voicemails != null && m_voicemails.size() > 0){
for(int i=0;i<m_voicemails.size();i++)
m_adapter.add(m_voicemails.get(i));
}
}
};
private void getVoicemails(){
try{
//Log.d("Data right before Json Parse", data);
Json jsonParser = new Json(data);
m_voicemails = jsonParser.getVoicemailsPME();
} catch (Exception e) {
Log.e("BACKGROUND_PROC", e.getMessage());
}
runOnUiThread(returnRes);
}
private class OrderAdapter extends ArrayAdapter<Voicemail> {
private ArrayList<Voicemail> items;
public OrderAdapter(Context context, int textViewResourceId, ArrayList<Voicemail> items) {
super(context, textViewResourceId, items);
this.items = items;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Voicemail vm = items.get(position);
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.voicemails_pme_row, null);
}
if (vm != null) {
TextView tt = (TextView) v.findViewById(R.id.toptext);
TextView bt = (TextView) v.findViewById(R.id.bottomtext);
TextView nm = (TextView) v.findViewById(R.id.length);
if (tt != null)
{
tt.setText(vm.getPhoneNumber());
if(vm.getNewStatus())
tt.setTypeface(null, Typeface.BOLD);
}
if(bt != null)
{
bt.setText(vm.getDate());
}
if(nm != null)
{
nm.setText(vm.getLength());
}
}
return v;
}
}
class CheckConnectionTask extends AsyncTask<String, Void, String> {
private VoicemailsPME activity;
private ProgressDialog dialog;
private Context context;
public CheckConnectionTask(VoicemailsPME activity)
{
this.activity = activity;
context = activity;
dialog = new ProgressDialog(context);
}
String username, password, str;
@Override
protected void onPreExecute() {
if(firstTime)
{
this.dialog.setMessage("Loading...");
this.dialog.show();
}
}
@Override
protected String doInBackground(String...arg0)
{
username = arg0[0];
password = arg0[1];
DefaultHttpClient httpclient = new DefaultHttpClient();
Credentials creds = new UsernamePasswordCredentials(username, password);
httpclient.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), creds);
try{
HttpPost post = new HttpPost("https://www.my.patlive.com/api/v1.0/Mailbox/" + mailboxId + "/messages?format=json");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3);
nameValuePairs.add(new BasicNameValuePair("username", username));
nameValuePairs.add(new BasicNameValuePair("password", password));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(post);
str = inputStreamToString(response.getEntity().getContent()).toString();
if(str.contains("\"ErrorCode\":0"))
{
//data = str;
return str;
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();}
return str;
}
@Override
protected void onPostExecute(String newData)
{
if(dialog.isShowing())
{
dialog.dismiss();
}
data = newData;
getVoicemails();
m_adapter.notifyDataSetChanged();
listView.onRefreshComplete();
}
}
}
答案 0 :(得分:1)
我认为你的getVoicemail()
方法是罪魁祸首。
由于适配器的工作方式,它使用您最初提供的后备阵列(m_voicemails
),当您刷新它时,您创建一个新列表,但原始的列表不会被清除,然后您只需添加除此之外。
public void run() {
//Try adding m_adapter.clear() here
if(m_voicemails != null && m_voicemails.size() > 0){
for(int i=0;i<m_voicemails.size();i++)
m_adapter.add(m_voicemails.get(i));
}
}
我发现将数据列表与适配器分开,然后将数据提供给适配器(使用set而不是add)更清楚。