刷新当前片段(ListView数据)保留在同一活动中

时间:2014-07-09 09:27:34

标签: android listview android-fragments android-listview

Fragment呼叫Activity,我正在显示ListViewButtons。当我点击menu_item(即在线显示)时,我正在更新数据,因此ListView。现在我需要反映更新的数据。单击“在线显示”后,如何刷新Fragment。直到现在,我使用了以下代码:

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

但这会重新启动整个Activity。我只需要刷新当前Fragment

enter image description here enter image description here

已编辑:已添加代码

ACTIVITY CLASS

    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;
    }
}  

2 个答案:

答案 0 :(得分:15)

根据您ListViewAdapter的具体实施方式,您有多种方法可以解决此问题。

  1. 致电notifyDataSetChanged()
  2. 重置Adapter

  3. 使用notifyDataSetChanged()

    进行更新

    这是最佳解决方案,但您需要修改List正在使用的Adapter才能生效。例如,如果您使用ArrayAdapter,请执行以下操作:

    String[] dataSource = new String[] {
        "A", "B", "C", ...
    };
    
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, R.layout.example, dataSource);
    

    正如您所看到的,String[]Adapter的dataSource。我们可以像这样修改数组,但这些更改不会立即反映在ListView

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

    只有在我们致电notifyDataSetChanged()后,ListView才会更新:

    adapter.notifyDataSetChanged();
    

    来自documentation

      

    public void notifyDataSetChanged()

         

    通知附加的观察者基础数据已经存在   已更改,任何反映数据集的视图都应自行刷新。

    但是不要notifyDataSetChanged()notifyDataSetInvalidated()混淆,因为notifyDataSetInvalidated()做了一些完全不同的事情,只会弄乱你的ListView

    来自documentation

      

    public void notifyDataSetInvalidated()

         

    通知附加的观察者不再有基础数据   有效或可用。一旦被调用,该适配器就不再有效了   不应该报告进一步的数据集更改。


    通过重置Adapter

    进行更新

    这很简单。每次设置新Adapter时,ListView都会自行更新。如果您出于某种原因无法使用notifyDataSetChanged(),那么您必须这样做。每次要更新Adapter时,只需创建一个新的ListView

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

    并使用setAdapter()将其设置为ListView

    listView.setAdapter(adapter);
    

    这将始终更新ListView,但此解决方案存在一些问题。首先,每当您以这种方式更新ListView时,它会滚动回到顶部,当频繁更新或ListView中有大量内容时,这可能非常烦人。


    修改

    您的代码中有一些不太理想的东西。首先,您的Adapter不应包含下载联系人的代码。它不属于那里,Adapter的唯一责任应该是他从给定的数据源创建Views。首先,您应该将getAllContacts()方法移到Adapter之外。我建议你为此创建静态帮助方法,我冒昧地相应地修改你的代码:

    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中更改了多项内容。首先,List的{​​{1}}现在是最终的,我添加了一个方法Contacts来公开contacts(),以便我们可以修改List中的数据外。我还实现了视图持有者模式,因此您的Adapter滚动更快更顺畅!

    我希望我没有忘记任何事情,但这应该是你需要的所有改变。您可以像这样使用新的ListView

    Adapter

    如果您想稍后更新List<Contact> contacts = ContactsHelper.getAllContacts(getActivity()); CustomAdapterForAllContacts adapter = new CustomAdapterForAllContacts(getActivity(), contacts); listView.setAdapter(adapter); ,则需要修改ListView内的List,如下所示:

    Adapter

    我希望我能帮到你,如果你有任何其他问题,请随时提出来!

答案 1 :(得分:1)

如果你在片段中,那么你可以做

// code for fetching the data
// ...
// ...
((BaseAdapter) yourlistview.getAdapter()).notifyDataSetChanged();