2011-06-26 112 views
1

我想在我的自定義適配器上調用notifyDataSetChanged(),但它似乎沒有工作。Android - notifyDataSetChanged()不適用於自定義適配器?

這裏是我的活動: -

public class ThreadData extends ListActivity 
{ 
private static final Uri SMS_URI = Uri.parse("content://sms"); 
HashMap<Long, BodyType> bodies = new HashMap<Long, BodyType>(); 
private String name, number; 
private ListView listView; 
private Activity activity; 
ThreadDataAdapter adapter; 
Handler handler; 
private Context context; 
private static final String PHONE_NUMBER_SEPARATORS = "()-./"; 
static HashMap<String, ContactInfo.ContactDetail> info = new HashMap<String, ContactInfo.ContactDetail>(); 

public void onCreate(Bundle bundle) 
{ 
    super.onCreate(bundle); 
    setContentView(R.layout.chats); 
    Bundle extras = getIntent().getExtras(); 
    activity = this; 
    context = this; 
    if(extras != null) 
    { 
     number = extras.getString("address"); 
     ContactInfo.ContactDetail nameInfo = getContactsDetailWithNumber(number); 
     if(nameInfo != null) 
     { 
      name = nameInfo.name; 
     } 
     else 
     { 
      name = number; 
     } 
    } 
    TextView person = (TextView) findViewById(R.id.chat_person); 
    person.setText(name); 
    ImageButton callPerson = (ImageButton) findViewById(R.id.call_person); 
    callPerson.setOnClickListener(new OnClickListener() { 
     public void onClick(View view) { 
      popUpDialerAlert(); 
     } 
    }); 

    buildMessageList(); 

    ArrayList<BodyType> items = sortBodies(); 
    adapter = new ThreadDataAdapter(this, items); 
    listView = getListView(); 
    listView.setAdapter(adapter); 
    listView.setStackFromBottom(true); 

    getContentResolver().registerContentObserver(SMS_URI, true, new MyContentObserver(handler)); 

} 

public void buildMessageList() 
{ 
    Cursor cursor = getContentResolver().query(SMS_URI, null, null, null, "date ASC"); 
    startManagingCursor(cursor); 
    while (cursor.moveToNext()) 
    { 
     BodyType bodyInfo = new BodyType(); 
     String address = cursor.getString(cursor.getColumnIndex("address")); 
     bodyInfo.body = cursor.getString(cursor.getColumnIndexOrThrow("body")); 
     Long date = cursor.getLong(cursor.getColumnIndexOrThrow("date")); 
     bodyInfo.date = date; 
     String type = cursor.getString(cursor.getColumnIndexOrThrow("type")); 
     if(type.equals("1")) 
     { 
      bodyInfo.type = "received"; 
     } 
     else if(type.equals("2")) 
     { 
      bodyInfo.type = "sent"; 
     } 
     else if(type.equals("3")) 
     { 
      bodyInfo.type = "draft"; 
     } 

     String number = filterPhoneNumber(address); 
     ContactInfo.ContactDetail nameInfo = getContactsDetailWithNumber(number); 
     String personName = number; 
     if(nameInfo != null) 
     { 
      personName = nameInfo.name; 
     } 
     else 
     { 
      personName = number; 
     } 
     if(personName.equals(name)) 
     { 
      bodies.put(date, bodyInfo); 
     } 
    } 
} 

public void popUpDialerAlert() 
{ 
    AlertDialog.Builder dialerAlert = new AlertDialog.Builder(this); 
    dialerAlert.setTitle("Confirm"); 
    dialerAlert.setMessage("Call" + " " + name + "?"); 
    dialerAlert.setPositiveButton("Yes", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialogInterface, int i) { 
      Uri uri = Uri.parse("tel:" + number); 
      Intent intent = new Intent((Intent.ACTION_CALL)); 
      intent.setData(uri); 
      context.startActivity(intent); 
     } 
    }); 
    dialerAlert.setNegativeButton("No", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialogInterface, int i) { 

     } 
    }); 
    dialerAlert.show(); 
} 

public ArrayList<BodyType> sortBodies() 
{ 
    ArrayList<Long> dates = new ArrayList<Long>(bodies.keySet()); 
    Collections.sort(dates); 
    ArrayList<BodyType> items = new ArrayList<BodyType>(); 
    for(Long date : dates) 
    { 
     for(Long key : bodies.keySet()) 
     { 
      if(date.equals(key)) 
      { 

       items.add(bodies.get(key)); 
      } 
     } 
    } 
    return items; 
} 

public void printBodies(ArrayList<BodyType> items) 
{ 
    for(BodyType bodyType : items) 
    { 
     log(bodyType.date.toString()); 
     log(bodyType.body); 
     log(bodyType.type); 
    } 
} 

static class BodyType 
{ 
    public String type; 
    public String body; 
    public Long date; 

} 


public static ContactInfo.ContactDetail getContactsDetailWithNumber(String number) 
{ 
    if(info.containsKey(number)) 
    { 
     return info.get(number); 
    } 
    return null; 
} 

public static String filterPhoneNumber(String phoneNumber) 
{ 
    if (phoneNumber == null) 
    { 
     return null; 
    } 

    int length = phoneNumber.length(); 
    StringBuilder builder = new StringBuilder(length); 

    for (int i = 0; i < length; i++) 
    { 
     char character = phoneNumber.charAt(i); 

     if (PHONE_NUMBER_SEPARATORS.indexOf(character) == -1) 
     { 
      builder.append(character); 
     } 
    } 
    return builder.toString(); 
} 

public class MyContentObserver extends ContentObserver 
{ 

    public MyContentObserver(Handler handler) 
    { 
     super(handler); 
    } 

    @Override 
    public void onChange(boolean selfChange) 
    { 
     buildMessageList(); 
     adapter.notifyDataSetChanged(); 
     super.onChange(selfChange); 

    } 
} 

public void log(String msg) 
{ 
    Log.e("ThreadData", msg); 
} 
} 

這裏是我的自定義適配器: -

public class ThreadDataAdapter extends BaseAdapter 
{ 
Activity activity; 
ArrayList<ThreadData.BodyType> data; 
LayoutInflater inflater; 

public ThreadDataAdapter(Activity a, ArrayList<ThreadData.BodyType> list) 
{ 
    activity = a; 
    data = list; 
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
} 

public int getCount() { 
    return data.size(); //To change body of implemented methods use File | Settings | File Templates. 
} 

public Object getItem(int i) { 
    return data.get(i); //To change body of implemented methods use File | Settings | File Templates. 
} 

public long getItemId(int i) { 
    return i; //To change body of implemented methods use File | Settings | File Templates. 
} 

public static class ViewHolder 
{ 
    public TextView message; 
} 

public View getView(int i, View view, ViewGroup viewGroup) 
{ 

    View row = view; 
    final ViewHolder holder; 

    ThreadData.BodyType bodyInfo = data.get(i); 
    if(bodyInfo.type.equals("sent")) 
     { 
      Log.e("MMS", bodyInfo.body); 
      row = inflater.inflate(R.layout.sentitem, viewGroup, false); 
      holder = new ViewHolder(); 
      holder.message = (TextView)row.findViewById(R.id.sent); 
      holder.message.setText(bodyInfo.body); 

     } 
     else 
     { 
      row = inflater.inflate(R.layout.chatitems, viewGroup, false); 
      holder = new ViewHolder(); 
      holder.message = (TextView)row.findViewById(R.id.received); 
      holder.message.setText(bodyInfo.body); 
     } 
    return row; 
} 
@Override 
public void notifyDataSetChanged() { 
    super.notifyDataSetChanged(); 
} 
} 

什麼,我試圖做的是,我註冊一個ContentObserver,並呼籲notifyDataSetChanged()在其onChange()中,只要設備的SMS數據庫發生一些變化。但它根本不工作。

任何幫助,將不勝感激。請幫忙!

在此先感謝。

回答

5

您在適配器(數據)中使用的List是您在sortBody中創建的List的參考。它從未更新。因此,您的適配器卡在未由您的OnChange方法更新的項目副本上。

換句話說,OnChange是否被調用,getView將始終返回相同的看法......

您適配器應該使用機構,因爲這MashMap由您OnChange方法更新。

+0

@Sincolas謝謝隊友。 – Varundroid

相關問題