刷新当前片段(ListView的数据)留在同一个活动 [英] Refresh Current Fragment (ListView Data) remaining in the same activity

查看:281
本文介绍了刷新当前片段(ListView的数据)留在同一个活动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

调用片段活动,我显示的ListView 有两个按钮。当我点击一个 MENU_ITEM (即显示在线),我更新的数据,并因此的ListView 。现在我需要反映更新的数据。我怎样才能刷新片段后,我请单击显示在线。到目前为止,我已经使用了以下code:

 意向意图= getIntent();
Intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
完();
startActivity(意向);

但是,这将重新启动整个活动。我只需要刷新当前片段


编辑:$ C $下加入

活动类

 公共类ContactListActivity扩展ActionBarActivity {    ListView控件的ListView;
    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        最后的动作条动作条= getActionBar();
        MenuButtonUtil.enableMenuButton(本);        FragmentManager fragmentManager = getFragmentManager();        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();        MyContactsFragment contactListFragment =新MyContactsFragment();
        fragmentTransaction.replace(android.R.id.content,contactListFragment);
        fragmentTransaction.commit();
    }    @覆盖
    公共布尔onCreateOptionsMenu(菜单菜单){
        //充气菜单;如果是present这增加了项目操作栏。
        。getMenuInflater()膨胀(R.menu.main,菜单);
        返回true;
    }    @覆盖
    公共布尔onOptionsItemSelected(菜单项项){
        INT ID = item.getItemId();
        如果(ID == R.id.show_online){
            ContentValues​​值=新ContentValues​​();
            字符串,其中=((+ ContactsContentProvider.PHONE_ID +NOTNULL)AND((+
                       ContactsContentProvider.PHONE_ID += 17486)OR(+
                       ContactsContentProvider.PHONE_ID += 17494)));            values​​.put(ContactsContentProvider.STATUS,真);
            。this.getContentResolver()更新(ContactsContentProvider.CONTENT_URI,值,其中,NULL);            ListView控件=(ListView控件)this.findViewById(android.R.id.list);
            ((BaseAdapter)listView.getAdapter())notifyDataSetChanged();            返回true;
        }
        返回super.onOptionsItemSelected(项目);
    }}

片段

 公共类MyContactsFragment扩展ListFragment {按钮allContactsBtn;
按钮neeoContactsBtn;
ListView控件的ListView;
CustomAdapterForAllContacts adapterForAllContacts;
CustomAdapterForNeeoContacts adapterForNeeoContacts;@覆盖
公共无效的onCreate(捆绑savedInstanceState){
    // TODO自动生成方法存根
    super.onCreate(savedInstanceState);
    最后的动作条动作条= getActivity()getActionBar()。
    MenuButtonUtil.enableMenuButton(getActivity());
    adapterForNeeoContacts =新CustomAdapterForNeeoContacts();
    adapterForAllContacts =新CustomAdapterForAllContacts();
}
@覆盖
公共查看onCreateView(LayoutInflater充气器,容器的ViewGroup,捆绑savedInstanceState){    查看查看= inflater.inflate(R.layout.contactsfragment,集装箱,FALSE);    allContactsBtn =(按钮)view.findViewById(R.id.allContactsButton);
    neeoContactsBtn =(按钮)view.findViewById(R.id.neeoContactsButton);
    ListView控件=(ListView控件)view.findViewById(android.R.id.list);
    // ==================== Neeo联系========================== ==
    neeoContactsBtn.setOnClickListener(新OnClickListener(){
        @覆盖
        公共无效的onClick(视图v){
            listView.setAdapter(adapterForNeeoContacts);        }
    });    // ======================所有联系人======================== =====    allContactsBtn.setOnClickListener(新OnClickListener(){
        @覆盖
        公共无效的onClick(视图v){
            listView.setAdapter(adapterForAllContacts);
        }
    });    返回视图。
}

适配器

 私有类CustomAdapterForAllContacts延伸BaseAdapter {公共CustomAdapterForAllContacts(){}
    清单<联系与GT; contactsList = getAllContacts();
    @覆盖
    公众诠释的getCount(){
        // TODO自动生成方法存根
        返回contactsList.size();
    }    @覆盖
    公众联系的getItem(INT为arg0){
        // TODO自动生成方法存根
        返回contactsList.get(为arg0);
    }    @覆盖
    众长getItemId(INT为arg0){
        // TODO自动生成方法存根
        返回将arg0;
    }    @覆盖
    公共查看getView(INT位置,查看视图的ViewGroup的ViewGroup){        如果(查看== NULL)
        {
            LayoutInflater吹气=(LayoutInflater)getActivity()getSystemService(Context.LAYOUT_INFLATER_SERVICE)。
            鉴于= 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的图像=(ImageView的)view.findViewById(R.id.contact_image);        联系方式联系方式= contactsList.get(位置);        字符串状态= contact.getStatus();        如果(contact.getStatus()。等于(1)){
            image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_online);
        }其他{
            image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_offline);
        }        contName.setText(contact.getName());
        contNumber.setText(contact.getPhoneNumber());
        返回视图。
    }    公开联系getContactPosition(INT位置)
    {
        返回contactsList.get(位置);
    }
    公开名单<联系与GT; getAllContacts(){        清单<联系与GT; contactList =新的ArrayList<联系与GT;();        字符串的URL =内容://com.example.provider.Contacts/contacts
        乌里baseUri1 = Uri.parse(URL);
        的String [] =选择{ContactsContentProvider.PHONE_ID,ContactsContentProvider.STATUS};        字符串,其中=((+ ContactsContentProvider.NEEO_USER +NOTNULL)AND(+
                                                   ContactsContentProvider.NEEO_USER += 1)AND(+
                                                   ContactsContentProvider.STATUS += 1));        光标光标= getActivity()getContentResolver()查询(baseUri1,选择,在那里,空,PID)。        为(cursor.moveToFirst(); cursor.moveToNext(); cursor.isAfterLast()){
            Log.w(过滤IDS,+ cursor.getString(cursor.getColumnIndex(ContactsContentProvider.PHONE_ID))+
                    + cursor.getString(cursor.getColumnIndex(ContactsContentProvider.STATUS)));
        }
        乌里基本URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;        的String [] =投影新的String [] {
                ContactsContract.CommonDataKinds.Phone._ID,
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                ContactsContract.CommonDataKinds.Phone.NUMBER};        字符串选择=((+
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME +NOTNULL)AND(+
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME +=''))!;        的String [] selectionArgs两个= NULL;
        字符串中将sortOrder = ContactsContract.CommonDataKinds.Phone._ID +分页中局部ASC;        。光标mCursor = getActivity()getContentResolver()查询(基本URI,投影,选择,selectionArgs两个,中将sortOrder);        // Joinging两个光标
                CursorJoiner木匠=新CursorJoiner(光标,新的String [] {} ContactsContentProvider.PHONE_ID,mCursor,新的String [] {ContactsContract.CommonDataKinds.Phone._ID});
                对于(CursorJoiner.Result joinerResult:木匠){
                    联系CONT =新的联系人();
                    Log.e(结果,joinerResult.toString());
                    开关(joinerResult){
                    案例LEFT:
                        //处理情况在CursorA软键行是独一无二的
                        打破;
                    案例RIGHT:
                        //处理情况在CursorB软键行是独一无二的
                        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.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(续)
                        打破;
                    }
                }
                mCursor.close();
                cursor.close();
        返回contactList;
    }
}


解决方案

您有多个选项来解决这个取决于你如何实施正是你的的ListView 适配器


  1. 将调用 notifyDataSetChanged()

  2. 将重置适配器


与notifyDataSetChanged()更新

这是最好的解决办法有,但你需要在列表适配器使用该修改上班。例如,如果您使用 ArrayAdapter 是这样的:

 的String []数据源=新的String [] {
    A,B,C,...
};ArrayAdapter<串GT;适配器=新ArrayAdapter<串GT;(上下文,R.layout.example,数据源);

正如你所看到的的String [] 是为我们的数据源适配器。我们可以修改这样的数组,但这些更改将不会立即在 ListView中得到体现

 数据源[0] =一些新的字符串值;

只有一次,我们称之为 notifyDataSetChanged()将在的ListView 更新:

  adapter.notifyDataSetChanged();

从<一个href=\"http://developer.android.com/reference/android/widget/BaseAdapter.html#notifyDataSetChanged%28%29\">documentation:


  

公共无效notifyDataSetChanged()


  
  

通知所附的观察家的基础数据已
  改变任何视图反映了数据集应刷新本身。


不要混淆 notifyDataSetChanged() notifyDataSetInvalidated(),因为 notifyDataSetInvalidated()做一些完全不同的,而且只会弄乱你的的ListView

从<一个href=\"http://developer.android.com/reference/android/widget/BaseAdapter.html#notifyDataSetInvalidated%28%29\">documentation:


  

公共无效notifyDataSetInvalidated()


  
  

通知所附观察员的基础数据不再
  有效或可用。一旦调用这个适配器不再有效,
  不应该再报告数据集的变化。



通过重置更新适配器

这是pretty直线前进。每次你设置一个新的适配器的ListView 将自动更新。如果你不能使用 notifyDataSetChanged()由于某种原因,那么你必须像这样做。只需创建要更新一个新的适配器您的每一次的ListView

  ArrayAdapter&LT;串GT;适配器=新ArrayAdapter&LT;串GT;(上下文,R.layout.example,newData);

和使用 setAdapter()将其设置为的ListView

  listView.setAdapter(适配器);

这会一直更新的ListView 但也有与此解决方案的几个问题。首先你每次更新的ListView 这种方式,它会回到顶端可以是当有频繁的更新还是相当恼人的滚动时有一个大量的内容在的ListView


编辑:

有在code几件事都不太理想。首先,你的适配器不应该包含code下载联系人。它只是不属于那里,唯一的责任是适配器应该是他创造查看从给定的数据资源。所以,首先你应该移动 getAllContacts()适配器之外的方法。我建议你​​创建这个静态辅助方法,我采取了相应的修改您的code的自由:

 公共类ContactsHelper {    公共静态列表&LT;联系与GT; getAllContacts(上下文的背景下){        清单&LT;联系与GT; contactList =新的ArrayList&LT;联系与GT;();        字符串的URL =内容://com.example.provider.Contacts/contacts
        乌里baseUri1 = Uri.parse(URL);
        的String [] =选择{ContactsContentProvider.PHONE_ID,ContactsContentProvider.STATUS};        字符串,其中=((+ ContactsContentProvider.NEEO_USER +NOTNULL)AND(+
                ContactsContentProvider.NEEO_USER += 1)AND(+
                ContactsContentProvider.STATUS += 1));        光标光标= context.getContentResolver()查询(baseUri1,选择,在那里,空,PID)。        为(cursor.moveToFirst(); cursor.moveToNext(); cursor.isAfterLast()){
            Log.w(过滤IDS,+ cursor.getString(cursor.getColumnIndex(ContactsContentProvider.PHONE_ID))+
                    + cursor.getString(cursor.getColumnIndex(ContactsContentProvider.STATUS)));
        }        乌里基本URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;        的String [] =投影新的String [] {
                ContactsContract.CommonDataKinds.Phone._ID,
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                ContactsContract.CommonDataKinds.Phone.NUMBER};        字符串选择=((+
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME +NOTNULL)AND(+
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME +=''))!;        的String [] selectionArgs两个= NULL;
        字符串中将sortOrder = ContactsContract.CommonDataKinds.Phone._ID +分页中局部ASC;        光标mCursor = context.getContentResolver()查询(基本URI,投影,选择,selectionArgs两个,中将sortOrder)。        // Joinging两个光标
        CursorJoiner木匠=新CursorJoiner(光标,新的String [] {} ContactsContentProvider.PHONE_ID,mCursor,新的String [] {ContactsContract.CommonDataKinds.Phone._ID});
        对于(CursorJoiner.Result joinerResult:木匠){
            联系CONT =新的联系人();
            Log.e(结果,joinerResult.toString());
            开关(joinerResult){
                案例LEFT:
                    //处理情况在CursorA软键行是独一无二的
                    打破;
                案例RIGHT:
                    //处理情况在CursorB软键行是独一无二的
                    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.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(续)
                    打破;
            }
        }
        mCursor.close();
        cursor.close();
        返回contactList;
    }
}

有了这个code,你可以得到这样的所有联系人:

 列表&LT;联系与GT;接触= ContactsHelper.getAllContacts(getActivity());

这一点,我们需要修改后的适配器 notifyDateSetChanged()将工作:

 私有类CustomAdapterForAllContacts延伸BaseAdapter {    私人最终名单&LT;联系与GT; contactsList;
    私人最终LayoutInflater吹气;    公共CustomAdapterForAllContacts(上下文的背景下,列表&LT;联系与GT;触点){
        this.inflater = LayoutInflater.from(上下文);
        this.contactsList =接触;
    }    @覆盖
    公众诠释的getCount(){
        返回contactsList.size();
    }    @覆盖
    公众联系的getItem(INT位置){
        返回contactsList.get(位置);
    }    @覆盖
    众长getItemId(INT位置){
        返回的位置;
    }    //我们揭露列表,所以我们可以从外部修改
    公开名单&LT;联系与GT;触点(){
        返回this.contactsList;
    }    私有类SimpleViewHolder {        私人最终SparseArray&LT;视图&gt; viewArray =新SparseArray&LT;视图&gt;();
        私人最终查看convertView;        公共SimpleViewHolder(查看convertView){
            this.convertView = convertView;
        }        公众观统领(INT ID){
            查看查看= this.viewArray.get(ID,NULL);
            如果(查看== NULL){
                鉴于= this.convertView.findViewById(ID);
                this.viewArray.put(ID,视图);
            }
            返回视图。
        }
    }    @覆盖
    公共查看getView(INT位置,查看convertView,ViewGroup中的ViewGroup){        //通过实施视图模式持有人只需要执行
        // findViewById()一次。这将改善ListView`的`的性能
        //并减少延误。
        SimpleViewHolder viewHolder;
        如果(convertView == NULL){
            convertView = this.inflater.inflate(R.layout.list_item,ViewGroup中,FALSE);
            viewHolder =新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的图像=(ImageView的)viewHolder.get(R.id.contact_image);        联系方式联系方式=的getItem(位置);        字符串状态= contact.getStatus();        如果(contact.getStatus()。等于(1)){
            image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_online);
        }其他{
            image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_offline);
        }        contName.setText(contact.getName());
        contNumber.setText(contact.getPhoneNumber());
        返回视图。
    }
}

我在这个适配器变多件事情。第一,联系人的最重要的列表现在是决赛,我增加了一个方法联系人() 来揭露列表,所以我们可以从外面修改适配器中的数据。我也实现了视图模式持有这样你的的ListView 滚动更快,更流畅!

我希望我没有忘记任何事情,但是这应该是你所需要的所有更改。您可以使用新的适配器是这样的:

 列表&LT;联系与GT;接触= ContactsHelper.getAllContacts(getActivity());
CustomAdapterForAllContacts适配器=新CustomAdapterForAllContacts(getActivity(),联系人);
listView.setAdapter(适配器);

如果您想更新的ListView 以后你需要修改列表的<$ C $内C>适配器是这样的:

 列表&LT;联系与GT; newData = ContactsHelper.getAllContacts(getActivity());
adapter.contacts()清()。
。adapter.contacts()的addAll(newData);
adapter.notifyDataSetChanged();

我希望我可以帮助你,如果你有任何问题,请随时问!

Calling a Fragment from an Activity, I am displaying a ListView with two Buttons. When I click on a menu_item (i.e. Show Online), i am updating the data and so the ListView. Now I need to reflect the updated data. How can i refresh the Fragment after i click Show Online. Till now, I have used the following code:

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

But this will restart the whole Activity. I just need to refresh the current Fragment.

Edited : Code Added

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

}

Fragment

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

Adapter:

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

解决方案

You have multiple options to solve this depending on how exactly you implemented your ListView and Adapter.

  1. By calling notifyDataSetChanged()
  2. By resetting the Adapter


Updating with notifyDataSetChanged()

This is the best solution there is, but you need to modify the List the Adapter is using for this to work. For example if you use an ArrayAdapter like this:

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

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

As you can see the String[] is the dataSource for our Adapter. We can modify the array like this, but those changes will not immediately be reflected in the ListView:

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

Only once we call notifyDataSetChanged() will the ListView be updated:

adapter.notifyDataSetChanged();

From the documentation:

public void notifyDataSetChanged ()

Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.

But DO NOT confuse notifyDataSetChanged() with notifyDataSetInvalidated(), because notifyDataSetInvalidated() does something completely different and would just mess up your ListView.

From the documentation:

public void notifyDataSetInvalidated ()

Notifies the attached observers that the underlying data is no longer valid or available. Once invoked this adapter is no longer valid and should not report further data set changes.


Updating by resetting the Adapter

This is pretty straight forward. Every time you set a new Adapter the ListView will update itself. If you cannot use notifyDataSetChanged() for some reason then you have to do it like this. Just create a new Adapter every time you want to update your ListView:

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

And use setAdapter() to set it to the ListView:

listView.setAdapter(adapter);

This will always update the ListView but there are a few problems with this solution. First and foremost every time you update the ListView this way it would scroll back to the top which can be quite annoying when there are frequent updates or when there is a lot of content in the ListView.


EDIT:

There are a few things in your code that are not quite optimal. First and foremost, your Adapter should not contain the code to download the contacts. It just doesn't belong there, the only responsibility of an Adapter should be that he creates Views from a given data source. So first you should move the getAllContacts() method outside of the Adapter. I suggest you create static helper method for this, I took the liberty of modifying your code accordingly:

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

With this code you can get all contacts like this:

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

After this we need to modify your Adapter so that notifyDateSetChanged() will work:

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

I have changed multiple things in this Adapter. First and foremost the List of Contacts is now final and I added a method contacts() to expose the List so we can modify the data in the Adapter from the outside. I also implemented the view holder pattern so your ListView scrolls faster and smoother!

I hope I haven't forgotten anything, but this should be all the changes you need. You can use the new Adapter like this:

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

If you want to update the ListView later on you need to modify the List inside the Adapter like this:

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

I hope I could help you and if you have any further questions please feel free to ask!

这篇关于刷新当前片段(ListView的数据)留在同一个活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆