ListView
の内部をリロードしようとして立ち往生していListFragment
ます。リフレッシュは、 で作成したリスナーを介して呼び出されFragmentDialog
ます。reloadItemsメソッドが適切に呼び出され、アイテムのリストが変数で正しく更新されていることを確認しました。
これは簡単なことのように思えますが、行き詰まっています。ListView が実際に更新されることはありませんが、Context
使用済みに関係していると思います。
onClick
ListView
プロパティを使用して設定された行のボタンを介して呼び出されandroid:onClick
ます。
ソリューション
問題は、作成中にタブ アダプタgetItem(...)
が予期せず再度呼び出されたAlertDialog
ことでした。コードが貧弱だったため、タブが再インスタンス化され、表示されているフラグメントで更新が行われませんでした。(最後に元のコードを参照してください)
これが発見されたら(受け入れられた回答を参照)、コードタブアダプターを作り直して参照を維持することで修正できました。ViewPager
誰にとっても役立つ場合に備えて、これが私の作業中のタブアダプターです。
public class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private ArrayList<Fragment> mFragments = new ArrayList<Fragment>();
static final class TabInfo {
private final Class<?> mClass;
private final Bundle mArgs;
TabInfo(Class<?> _class, Bundle _args) {
mClass = _class;
mArgs = _args;
}
public String getClassName() {
return mClass.getName();
}
public Bundle getArgs() {
return mArgs;
}
}
public TabsAdapter(Activity activity, ViewPager pager) {
super(activity.getFragmentManager());
mContext = activity;
mActionBar = activity.getActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
Fragment fragment = Fragment.instantiate(mContext, info.getClassName(), info.getArgs());
mFragments.add(fragment);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
public void onPageScrollStateChanged(int state) {
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i = 0; i < mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
ソリューションの終了
アクティビティ
public class MyActivity extends Activity {
// unrelated code removed
public void onClick(View v) {
// onClick is called via a button on a list item
MyFragment sf = (MyFragment)mTabsAdapter.getItem(0);
sf.myClick(v, getFragmentManager());
}
}
マイフラグメント
public class MyFragment extends ListFragment {
static final String TAG = "StatusFragment";
private ArrayList<MyObject> mItems = null;
AlarmDataSource datasource;
StatusAdapter mAdapter;
public void reloadItems(Context context) {
Log.d(TAG, "reloadItems");
datasource = new MyObjectDataSource(context);
datasource.open();
mItems = new ArrayList<MyObject>();
ArrayList<MyObject> active = (ArrayList<MyObject>)datasource.getAllEnabled();
for (int i = 0; i < active.size(); i++) {
MyObject next = active.get(i);
mItems.add(next);
}
mAdapter = new StatusAdapter(
context,
R.layout.status_list_item,
mItems);
// set a breakpoint and this is called when called from
// statusOptionDialogClose below. Here mAdapter DOES HAVE updated items
// inside. However getView within the adaper is NOT called
setListAdapter(mAdapter);
datasource.close();
}
public void myClick(View v, FragmentManager manager) {
StatusOptionDialog sod = StatusOptionDialog.newInstance(v.getContext());
sod.setStatusOptionDialogListener(new StatusOptionDialogListener() {
public void statusOptionDialogClose(Context context) {
// this is correctly called when dialog closed
// context is the same as sent in with newInstance above.
reloadItems(context);
}
});
sod.show(manager, "StatusOptionDialog");
}
}
何かおかしなところを見た人はいますか?さまざまな方法を試しましたが、何もうまくいきませんでした。
注更新時にも試しましmAdapter.notifyDataSetChanged()
たが、どちらも機能しません。今日の後半に Android SDK コードをステップ実行して、データがアダプターに届かない場合や何か奇妙な場合に備えて、そこにあるデータも特定できるかどうかを確認します。
更新問題の詳細を追跡しました。setListItem(mAdapter)
アイテムを更新したmAdapterを正常に呼び出した後、アダプターgetView(...)
が呼び出されないようです。
更新 #2reloadItems(...)
問題のある最も単純なコードに絞り込んだ関数を投稿しました。setListAdapter(...)
更新されたアイテムを持つ更新されたアダプターで呼び出されます。ただし、経由でgetView(...)
呼び出されたときに呼び出されることはありませんreloadItems(...)
statusOptionDialogClose(...)
アプリケーションを終了して再起動すると、更新されたデータが ListView に表示されます。reloadItems を再度呼び出すと、更新されません。
アダプタ
public class StatusAdapter extends ArrayAdapter<MyObject> {
private Context mContext;
private int mRes;
private ArrayList<MyObject> mItems;
public StatusAdapter(Context context, int textViewResourceId, ArrayList<MyObject> items) {
super(context, textViewResourceId, items);
this.mItems = items;
this.mRes = textViewResourceId;
this.mContext = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(mRes, null);
}
Alarm a = mItems.get(position);
if (a != null) {
// fills out list item
}
return v;
}
@Override
public int getCount() {
return mItems.size();
}
public void setNewList(ArrayList<Alarm> items) {
this.mItems = items;
}
}
タブ アダプタおよび タブを有効にするために使用されViewPager
ます。
public class TabsAdapter extends FragmentPagerAdapter implements
ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(Activity activity, ViewPager pager) {
super(activity.getFragmentManager());
mContext = activity;
mActionBar = activity.getActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
public void onPageScrollStateChanged(int state) {
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i = 0; i < mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}