2014-07-09 66 views
8

Activity調用Fragment,我顯示一個ListView與兩個Buttons。當我點擊menu_item(即顯示在線)時,我正在更新數據,因此ListView。現在我需要反映更新的數據。我點擊「在線顯示」後,如何刷新Fragment。到目前爲止,我已經使用了下面的代碼:刷新當前片段(ListView數據)保留在同一活動中

Intent intent = getIntent(); 
Intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); 
finish(); 
startActivity(intent); 

但是,這將重新啓動整個Activity。我只需刷新當前的Fragment

enter image description here enter image description here

編輯:代碼添加

活動類

public class ContactListActivity extends ActionBarActivity { 

    ListView listView; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     final ActionBar actionBar = getActionBar(); 
     MenuButtonUtil.enableMenuButton(this); 

     FragmentManager fragmentManager = getFragmentManager(); 

     FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 

     MyContactsFragment contactListFragment = new MyContactsFragment(); 
     fragmentTransaction.replace(android.R.id.content, contactListFragment); 
     fragmentTransaction.commit(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     int id = item.getItemId(); 
     if (id == R.id.show_online) { 
      ContentValues values = new ContentValues(); 
      String where = "((" + ContactsContentProvider.PHONE_ID + " NOTNULL) AND ((" + 
         ContactsContentProvider.PHONE_ID+ " = 17486)OR (" + 
         ContactsContentProvider.PHONE_ID+ " = 17494)))"; 

      values.put(ContactsContentProvider.STATUS, true); 
      this.getContentResolver().update(ContactsContentProvider.CONTENT_URI, values, where, null); 

      listView = (ListView) this.findViewById(android.R.id.list); 
      ((BaseAdapter) listView.getAdapter()).notifyDataSetChanged(); 

      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

} 

片段

public class MyContactsFragment extends ListFragment{ 

Button allContactsBtn; 
Button neeoContactsBtn; 
ListView listView; 
CustomAdapterForAllContacts adapterForAllContacts; 
CustomAdapterForNeeoContacts adapterForNeeoContacts; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    // TODO Auto-generated method stub 
    super.onCreate(savedInstanceState); 
    final ActionBar actionBar = getActivity().getActionBar(); 
    MenuButtonUtil.enableMenuButton(getActivity()); 
    adapterForNeeoContacts = new CustomAdapterForNeeoContacts(); 
    adapterForAllContacts = new CustomAdapterForAllContacts(); 
} 


@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { 

    View view = inflater.inflate(R.layout.contactsfragment, container,false); 

    allContactsBtn = (Button) view.findViewById(R.id.allContactsButton); 
    neeoContactsBtn = (Button) view.findViewById(R.id.neeoContactsButton); 
    listView = (ListView) view.findViewById(android.R.id.list); 


    // ==================== Neeo Contacts ============================ 
    neeoContactsBtn.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      listView.setAdapter(adapterForNeeoContacts); 

     } 
    }); 

    // ====================== All Contacts ============================= 

    allContactsBtn.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      listView.setAdapter(adapterForAllContacts); 
     } 
    }); 

    return view; 
} 

適配器

private class CustomAdapterForAllContacts extends BaseAdapter { 

public CustomAdapterForAllContacts(){ 

} 
    List<Contact> contactsList = getAllContacts(); 
    @Override 
    public int getCount() { 
     // TODO Auto-generated method stub 
     return contactsList.size(); 
    } 

    @Override 
    public Contact getItem(int arg0) { 
     // TODO Auto-generated method stub 
     return contactsList.get(arg0); 
    } 

    @Override 
    public long getItemId(int arg0) { 
     // TODO Auto-generated method stub 
     return arg0; 
    } 

    @Override 
    public View getView(int position, View view, ViewGroup viewGroup) { 

     if(view==null) 
     { 
      LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      view = inflater.inflate(R.layout.list_item, viewGroup,false); 
     } 

     TextView contName = (TextView)view.findViewById(R.id.nameText); 
     TextView contNumber = (TextView)view.findViewById(R.id.numberText); 
     ImageView image = (ImageView)view.findViewById(R.id.contact_image); 

     Contact contact = contactsList.get(position); 

     String status = contact.getStatus(); 

     if(contact.getStatus().equals("1")){ 
      image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_online); 
     }else{ 
      image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_offline); 
     } 

     contName.setText(contact.getName()); 
     contNumber.setText(contact.getPhoneNumber()); 
     return view; 
    } 

    public Contact getContactPosition(int position) 
    { 
     return contactsList.get(position); 
    } 
    public List<Contact> getAllContacts(){ 

     List<Contact> contactList = new ArrayList<Contact>(); 

     String URL = "content://com.example.provider.Contacts/contacts"; 
     Uri baseUri1 = Uri.parse(URL); 
     String[] select = {ContactsContentProvider.PHONE_ID, ContactsContentProvider.STATUS}; 

     String where = "((" + ContactsContentProvider.NEEO_USER + " NOTNULL) AND (" + 
                ContactsContentProvider.NEEO_USER+ " = 1)AND (" + 
                ContactsContentProvider.STATUS+ " = 1))"; 

     Cursor cursor = getActivity().getContentResolver().query(baseUri1, select, where, null, "pid"); 

     for(cursor.moveToFirst(); cursor.moveToNext(); cursor.isAfterLast()) { 
      Log.w("Filtered IDS",""+ cursor.getString(cursor.getColumnIndex(ContactsContentProvider.PHONE_ID))+ 
        ""+ cursor.getString(cursor.getColumnIndex(ContactsContentProvider.STATUS))); 
     } 


     Uri baseUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; 

     String[] projection = new String[] { 
       ContactsContract.CommonDataKinds.Phone._ID, 
       ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, 
       ContactsContract.CommonDataKinds.Phone.NUMBER}; 

     String selection = "((" + 
       ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " NOTNULL) AND (" + 
       ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " != ' '))"; 

     String[] selectionArgs = null; 
     String sortOrder = ContactsContract.CommonDataKinds.Phone._ID + " COLLATE LOCALIZED ASC"; 

     Cursor mCursor= getActivity().getContentResolver().query(baseUri, projection, selection, selectionArgs, sortOrder); 

     // Joinging Both Cursors 
       CursorJoiner joiner = new CursorJoiner(cursor, new String[] {ContactsContentProvider.PHONE_ID} , mCursor, new String[] {ContactsContract.CommonDataKinds.Phone._ID}); 
       for (CursorJoiner.Result joinerResult : joiner) { 
        Contact cont = new Contact(); 
        Log.e("Result", joinerResult.toString()); 
        switch (joinerResult) { 
        case LEFT: 
         // handle case where a row in cursorA is unique 
         break; 
        case RIGHT: 
         // handle case where a row in cursorB is unique 
         cont.setID(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID))); 
         cont.setName(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))); 
         cont.setPhoneNumber(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); 
         cont.setStatus("0"); 
         contactList.add(cont); 
         break; 
        case BOTH: 
         // handle case where a row with the same key is in both cursors 
         cont.setID(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID))); 
         cont.setName(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))); 
         cont.setPhoneNumber(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); 
         cont.setStatus(cursor.getString(cursor.getColumnIndex(ContactsContentProvider.STATUS))); 
         contactList.add(cont); 
         break; 
        } 
       } 
       mCursor.close(); 
       cursor.close(); 
     return contactList; 
    } 
} 
+0

用過'ListFragment'爲... –

+0

那麼什麼?有關ListFragment關於刷新片段的任何特定內容。 –

+0

以及該適配器上的'.notifyDataSetChanged()'在活動'Resume()'或其他任何地方......它會更新你的'ListFragment' ... –

回答

14

你有多種選擇來解決這個取決於你究竟是如何實現你的ListViewAdapter

  1. 通過調用notifyDataSetChanged()
  2. 通過與notifyDataSetChanged()重置Adapter

更新

這是最好的解決辦法有,但你需要修改ListAdapter正在使用此工作。例如,如果您使用的是ArrayAdapter這樣的:

String[] dataSource = new String[] { 
    "A", "B", "C", ... 
}; 

ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, R.layout.example, dataSource); 

正如你可以看到String[]是我們Adapter數據源。我們可以修改這樣的陣列,但這些變化不會立即在ListView反映:

dataSource[0] = "some new String value"; 

只有一次,我們稱之爲notifyDataSetChanged()ListView更新:

adapter.notifyDataSetChanged(); 

documentation

public void notifyDataSetChanged()

通知所附的觀察員已更改基礎數據 ,並且任何反映數據集的視圖都應刷新自身。

切勿混淆notifyDataSetChanged()notifyDataSetInvalidated(),因爲notifyDataSetInvalidated()會產生完全不同的,而且只會弄亂你的ListView

documentation

公共無效notifyDataSetInvalidated()

通知所連接的觀察者,該底層數據不再有效 或可用。一旦調用此適配器不再有效,並且 不應報告進一步的數據集更改。


更新通過重置Adapter

這是非常簡單的。每次您設置新的Adapter時,ListView都會自行更新。如果由於某種原因你不能使用notifyDataSetChanged(),那麼你必須這樣做。只要創建要更新您的ListViewAdapter每次:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, R.layout.example, newData); 

並使用setAdapter()將其設置爲ListView

listView.setAdapter(adapter); 

這將始終更新ListView但也有一些問題用這個解決方案。首先並且最重要的是,每當您更新ListView這種方式時,它會滾動回頂端,當頻繁更新或ListView中有大量內容時,這可能會非常煩人。


編輯:

有代碼中的幾件事情都不太理想。首先,您的Adapter不應該包含下載聯繫人的代碼。它不屬於那裏,Adapter的唯一責任應該是他從給定的數據源創建Views。所以首先你應該移動Adapter以外的getAllContacts()方法。我建議你創建這個靜態輔助方法,我採取了相應的修改代碼的自由:

public class ContactsHelper { 

    public static List<Contact> getAllContacts(Context context) { 

     List<Contact> contactList = new ArrayList<Contact>(); 

     String URL = "content://com.example.provider.Contacts/contacts"; 
     Uri baseUri1 = Uri.parse(URL); 
     String[] select = {ContactsContentProvider.PHONE_ID, ContactsContentProvider.STATUS}; 

     String where = "((" + ContactsContentProvider.NEEO_USER + " NOTNULL) AND (" + 
       ContactsContentProvider.NEEO_USER + " = 1)AND (" + 
       ContactsContentProvider.STATUS + " = 1))"; 

     Cursor cursor = context.getContentResolver().query(baseUri1, select, where, null, "pid"); 

     for (cursor.moveToFirst(); cursor.moveToNext(); cursor.isAfterLast()) { 
      Log.w("Filtered IDS", "" + cursor.getString(cursor.getColumnIndex(ContactsContentProvider.PHONE_ID)) + 
        "" + cursor.getString(cursor.getColumnIndex(ContactsContentProvider.STATUS))); 
     } 

     Uri baseUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; 

     String[] projection = new String[]{ 
       ContactsContract.CommonDataKinds.Phone._ID, 
       ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, 
       ContactsContract.CommonDataKinds.Phone.NUMBER}; 

     String selection = "((" + 
       ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " NOTNULL) AND (" + 
       ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " != ' '))"; 

     String[] selectionArgs = null; 
     String sortOrder = ContactsContract.CommonDataKinds.Phone._ID + " COLLATE LOCALIZED ASC"; 

     Cursor mCursor = context.getContentResolver().query(baseUri, projection, selection, selectionArgs, sortOrder); 

     // Joinging Both Cursors 
     CursorJoiner joiner = new CursorJoiner(cursor, new String[]{ContactsContentProvider.PHONE_ID}, mCursor, new String[]{ContactsContract.CommonDataKinds.Phone._ID}); 
     for (CursorJoiner.Result joinerResult : joiner) { 
      Contact cont = new Contact(); 
      Log.e("Result", joinerResult.toString()); 
      switch (joinerResult) { 
       case LEFT: 
        // handle case where a row in cursorA is unique 
        break; 
       case RIGHT: 
        // handle case where a row in cursorB is unique 
        cont.setID(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID))); 
        cont.setName(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))); 
        cont.setPhoneNumber(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); 
        cont.setStatus("0"); 
        contactList.add(cont); 
        break; 
       case BOTH: 
        // handle case where a row with the same key is in both cursors 
        cont.setID(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID))); 
        cont.setName(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))); 
        cont.setPhoneNumber(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); 
        cont.setStatus(cursor.getString(cursor.getColumnIndex(ContactsContentProvider.STATUS))); 
        contactList.add(cont); 
        break; 
      } 
     } 
     mCursor.close(); 
     cursor.close(); 
     return contactList; 
    } 
} 

有了這個代碼,你可以得到所有接觸這樣的:

List<Contact> contacts = ContactsHelper.getAllContacts(getActivity()); 

在此之後,我們需要修改Adapter使notifyDateSetChanged()將工作:

private class CustomAdapterForAllContacts extends BaseAdapter { 

    private final List<Contact> contactsList; 
    private final LayoutInflater inflater; 

    public CustomAdapterForAllContacts(Context context, List<Contact> contacts) { 
     this.inflater = LayoutInflater.from(context); 
     this.contactsList = contacts; 
    } 

    @Override 
    public int getCount() { 
     return contactsList.size(); 
    } 

    @Override 
    public Contact getItem(int position) { 
     return contactsList.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    // We expose the List so we can modify it from outside 
    public List<Contact> contacts() { 
     return this.contactsList;  
    } 

    private class SimpleViewHolder { 

     private final SparseArray<View> viewArray = new SparseArray<View>(); 
     private final View convertView; 

     public SimpleViewHolder(View convertView) { 
      this.convertView = convertView; 
     } 

     public View get(int id) { 
      View view = this.viewArray.get(id, null); 
      if(view == null) { 
       view = this.convertView.findViewById(id); 
       this.viewArray.put(id, view); 
      } 
      return view; 
     } 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup viewGroup) { 

     // By implementing the view holder pattern you only need to perform 
     // findViewById() once. This will improve the performance of `ListView` 
     // and reduce lag. 
     SimpleViewHolder viewHolder; 
     if (convertView == null) { 
      convertView = this.inflater.inflate(R.layout.list_item, viewGroup, false); 
      viewHolder = new SimpleViewHolder(convertView); 
      convertView.setTag(viewHolder); 
     } 

     viewHolder = (SimpleViewHolder) convertView.getTag(); 

     TextView contName = (TextView) viewHolder.get(R.id.nameText); 
     TextView contNumber = (TextView) viewHolder.get(R.id.numberText); 
     ImageView image = (ImageView) viewHolder.get(R.id.contact_image); 

     Contact contact = getItem(position); 

     String status = contact.getStatus(); 

     if (contact.getStatus().equals("1")) { 
      image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_online); 
     } else { 
      image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_offline); 
     } 

     contName.setText(contact.getName()); 
     contNumber.setText(contact.getPhoneNumber()); 
     return view; 
    } 
} 

我在這Adapter改變了許多東西。首先,ListContacts現在是最終的,我添加了一個方法contacts()來公開List,所以我們可以從外部修改Adapter中的數據。我也實現了查看模式,讓你的ListView更快更順暢!

我希望我沒有忘記任何東西,但這應該是你需要的所有改變。您可以使用新的Adapter這樣的:

List<Contact> contacts = ContactsHelper.getAllContacts(getActivity()); 
CustomAdapterForAllContacts adapter = new CustomAdapterForAllContacts(getActivity(), contacts); 
listView.setAdapter(adapter); 

如果你想更新ListView您以後需要修改ListAdapter像這裏面:

List<Contact> newData = ContactsHelper.getAllContacts(getActivity()); 
adapter.contacts().clear(); 
adapter.contacts().addAll(newData); 
adapter.notifyDataSetChanged(); 

我希望我可以幫你如果您還有其他問題,請隨時提問!

+0

檢查我編輯的問題。 –

+0

我也包含了代碼。現在檢查。 –

+1

好吧,我明白了。您不應該在適配器內執行數據的下載。類似的東西不屬於那裏。在'Adapter'中用作數據源的'List'通常應該是最終的,而不是像你那樣處理。我會用一些建議來編輯我的答案。 –

1

如果你是一個片段裏面,那麼你可以做

// code for fetching the data 
// ... 
// ... 
((BaseAdapter) yourlistview.getAdapter()).notifyDataSetChanged(); 
相關問題