Fragment
からActivity
を呼び出して、2つのListView
を含むButtons
を表示しています。 menu_item
(つまり、オンラインで表示)をクリックすると、データが更新されるため、ListView
が更新されます。次に、更新されたデータを反映する必要があります。 [オンラインで表示]をクリックした後、Fragment
を更新するにはどうすればよいですか。今まで、私は次のコードを使用しました:
Intent intent = getIntent();
Intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
startActivity(intent);
ただし、これによりActivity
全体が再起動します。現在のFragment
を更新する必要があります。
編集:コード追加
アクティビティクラス
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;
}
}
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());
_
この後、notifyDateSetChanged()
が機能するようにAdapter
を変更する必要があります。
_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
のContacts
が最終版になり、メソッドcontacts()
を追加してList
を公開し、Adapter
のデータを外部から変更できるようにしました。また、ビューホルダーパターンを実装したので、ListView
はより速く、よりスムーズにスクロールします。
私は何も忘れていないことを願っていますが、これはあなたが必要とするすべての変更であるはずです。新しいAdapter
は次のように使用できます。
_List<Contact> contacts = ContactsHelper.getAllContacts(getActivity());
CustomAdapterForAllContacts adapter = new CustomAdapterForAllContacts(getActivity(), contacts);
listView.setAdapter(adapter);
_
後でListView
を更新する場合は、List
内のAdapter
を次のように変更する必要があります。
_List<Contact> newData = ContactsHelper.getAllContacts(getActivity());
adapter.contacts().clear();
adapter.contacts().addAll(newData);
adapter.notifyDataSetChanged();
_
お役に立てれば幸いです。他にご不明な点がございましたら、お気軽にお問い合わせください。
あなたがフラグメントの中にいるなら、あなたはすることができます
// code for fetching the data
// ...
// ...
((BaseAdapter) yourlistview.getAdapter()).notifyDataSetChanged();