从Fragment
呼叫Activity
,我正在显示ListView
个Buttons
。当我点击menu_item
(即在线显示)时,我正在更新数据,因此ListView
。现在我需要反映更新的数据。单击“在线显示”后,如何刷新Fragment
。直到现在,我使用了以下代码:
Intent intent = getIntent();
Intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
startActivity(intent);
但这会重新启动整个Activity
。我只需要刷新当前Fragment
。
已编辑:已添加代码
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;
}
}
答案 0 :(得分:15)
根据您ListView
和Adapter
的具体实施方式,您有多种方法可以解决此问题。
notifyDataSetChanged()
Adapter
这是最佳解决方案,但您需要修改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();
public void notifyDataSetChanged()
通知附加的观察者基础数据已经存在 已更改,任何反映数据集的视图都应自行刷新。
但是不要将notifyDataSetChanged()
与notifyDataSetInvalidated()
混淆,因为notifyDataSetInvalidated()
做了一些完全不同的事情,只会弄乱你的ListView
。
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();